<?php
@error_reporting(E_ALL ^ E_WARNING ^ E_PARSE ^ E_NOTICE);

$res = array(
    'code' => 200,
    'message' => 'success',
    'data' => array(),
);

//IP白名单
$whitelistIPs = array(
    '127.0.0.1',
    '202.91.0.0/16',
    '159.75.166.8',
    '49.235.198.63',
    '182.61.31.54',
    '154.85.42.184',
    '117.50.67.147',
    '117.50.67.0/24',
);
if (!check_white_ip($_SERVER['REMOTE_ADDR'], $whitelistIPs)){
    show_result(403, 'the ip is not in whitelist');
}

$crossDomainList = array('nicebox.cn','cdn.img.sooce.cn','cdn.yun.sooce.cn','myqcloud.com','s143.nicebox.cn');

//以下的几行代码实现api接口的功能(本地测试时可以将其暂时注释)
if (isset($_SERVER['REQUEST_METHOD']) == false || $_SERVER['REQUEST_METHOD'] !== 'GET') {
    show_result(405, 'the method is wrong');
}

if(isset($_GET['mkey'])){//此处是api的token或者说key验证(还未正式确定如何生成),暂时以下方做代替(现在没有将生成的key传递给用户端的功能)
    $t = $_GET['t'];
    if ($t < strtotime("-10 minutes")) {
        show_result(403, 'time expired');
    }
    $needKey = md5($t."iisp");
    if($_GET['mkey']!==$needKey){
        show_result(403, 'the key is wrong');
    }
}else{
    show_result(403, 'No Key Provided');
}
//以上的几行代码实现api接口的功能(本地测试时可以将其暂时注释)


$fileStat = array(
    'all'       => 0, //总数
    'success'   => 0, //成功
    'fail'      => 0, //失败
    'skip'      => 0, //跳过
);

$fileCount = 0;//更改文件数
$urlCount = 0;//更改url数
$failOpenFiles = array();//没有正确打开的文件
$failUrl = array();//没有正确修改的url
$code = 200;//状态码预设为200
$message = "success";//最终信息预设为成功
$data = array();//最终应该返回数据
$path = dirname(__FILE__);
$request = "request.php";
$suffixes = array('/\.html/', '/\.css/','/\.js/');
$filename = fn_scandir($path,$suffixes,0);
$fileStat['all'] = count($filename);

if (isset($_GET['path'])) {
    $path = $_GET['path'];
}
$res['data']['path'] = $path;
if($filename == false ){
    show_result(404, 'can not open the folder');
}

foreach ($filename as $key => $value) {
    $fileCount ++;
    $content = file_get_contents($value[0]);
    if($content === false){
        $fileStat['fail']++;
        continue;
    }
    $prefix = $request;

    for($i = 1;$i <= $value[1];$i++){
        $prefix = '../'.$prefix;
    }

    $newContent = rewriteExternalResources($content,$prefix);
    if (strpos($value[0], "comm.js")) {
        $newContent = changeComm($newContent,$request,'var scriptString');
        $newContent = changeComm($newContent,$request,'for(var i in newArr)');
    }

    if (md5($content) == md5($newContent)) {
        $fileStat['skip']++;
        continue;
    }
    file_put_contents($value[0],$newContent);
    $fileStat['success']++;
}

$requestContent = '<?php
@error_reporting(E_ALL ^ E_WARNING ^ E_PARSE ^ E_NOTICE);

$cacheDir = dirname(__FILE__) . \'/cache/\';
if (!file_exists($cacheDir)) {
    mkdir($cacheDir, 0777, true);
}
$request = "request.php";
$needCache = false;
$suffixes = array(
        ".jpg",".jpeg",".png",".gif",".bmp",".psd",".svg",".tiff",
        ".wav",".avi",".mp4",".mov","mkv",".proper",
        ".js",
        ".css",
        ".wma",".mp3",".aiff",".cd"
    );

header("Cache-Control: max-age=10800, pre-check=10800");
header("Pragma: private");
$interval=172800;
header("Expires: " . gmdate("D, d M Y H:i:s",time()+$interval)." GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
//如果浏览器对当前页面已经有缓存，那么就直接使用它。
if(isset($_SERVER[\'HTTP_IF_MODIFIED_SINCE\'])){
    header(\'Last-Modified: \'.$_SERVER[\'HTTP_IF_MODIFIED_SINCE\'],true,304);
    exit;
}

if (isset($_GET[\'url\'])) {
    $url = $_GET[\'url\'];
    if (!$url) {
        die("No url provided.");
    }
    if (isset($_GET[\'callback\'])) {
        $url .= "&callback=" . $_GET[\'callback\'];
    }
    $cookie = \'\';
    if (isset($_SERVER[\'HTTP_COOKIE\'])) {
        $cookie = $_SERVER[\'HTTP_COOKIE\'];
    }
    foreach($suffixes as $suffix){
        if(isSuffix($url,$suffix)){
            $needCache = true;
        }
    }
    list($content, $headers) = getCachedContent($url, $cacheDir,$cookie);
    foreach ($headers as $key => $value) {
        if ($key !== \'Content-Length\' && $key !== \'Transfer-Encoding\' && $key !== \'Connection\') {
            header("$key: $value");
        }
    }
    echo rewriteExternalResources($content,$request);
} else {
    echo "No \'url\' parameter provided.";
}

function getCachedContent($url, $cacheDir,$cookie) {
    global $needCache;
    $cacheFile = $cacheDir . md5($url);
    $cacheHeadersFile = $cacheDir . \'headers_\' . md5($url);

    if ($needCache && file_exists($cacheFile) && file_exists($cacheHeadersFile)) {  
        $body = file_get_contents($cacheFile);  
        $serializedHeaders = file_get_contents($cacheHeadersFile);  
        $headers = unserialize($serializedHeaders); 
        return array($body, $headers); 
    }

    if (substr($url, 0, 2) == "//") $url = "http:" . $url;

    if (substr($url, 0, 24) == "https://cdn.yun.sooce.cn") {
        $url = str_replace("https://", "http://", $url);
    }

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER[\'HTTP_USER_AGENT\']);
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_REFERER, $_SERVER[\'HTTP_REFERER\']);

    if ($_POST) {
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
    }

    $response = curl_exec($ch);

    if(curl_errno($ch)){
        echo \'Curl error: \' . curl_error($ch);
    }
    $headers = curl_getinfo($ch, CURLINFO_HEADER_OUT);
    $responseHeaders = substr($response, 0, curl_getinfo($ch, CURLINFO_HEADER_SIZE));
    $body = substr($response, curl_getinfo($ch, CURLINFO_HEADER_SIZE));
    $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    curl_close($ch);
    $responseHeaders = str_replace("Cache-Control: max-age=3600","",$responseHeaders);
    header(\'Content-Type: \' . $contentType);
    if($needCache){
        file_put_contents($cacheFile, $body);
        file_put_contents($cacheHeadersFile, serialize(getHttpHeadersFromString($responseHeaders)));
    }

    return array($body, getHttpHeadersFromString($responseHeaders));
}

function getHttpHeadersFromString($headerString) {
    $headers = array();
    $headerArray = explode("\r\n", $headerString);
    foreach ($headerArray as $header) {
        if (strpos($header, \':\') !== false) {
            list($key, $value) = explode(\': \', $header, 2);
            $headers[$key] = $value;
        }
    }
    return $headers;
}



function rewriteExternalResources($content,$request) {
    //\'/<(form)[^>]*\baction\s*=\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')([^\"\\\']*?)\2/i\',
    $patterns = array(
        \'/<(img|video|audio|source|iframe)[^>]*?\bsrc\s*=\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')([^"\\\'>]*?)\2/i\',
        \'/<script([^>]*\bsrc\s*=\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')([^"\\\'>]*?)\2)/i\',
        \'/\b(loadExtentFile)\s*\(\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')(.*?)\2/si\',
        \'/(url)\s*\(\s*(["\\\']*?)([^"\\\')]*?)\2\s*\)/U\',
        \'/(push)\s*\(\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')(.*)\2\)/U\',
        \'/(src)\s*=\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')(.*?)\2(?:.*?)/si\',
        \'/stylesheet[^>]*(href)\s*=\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')([^"\\\'>]*?)\2[^>]*>/i\',
        \'/<(link)[^>]*?\bhref\s*=\s*(\\\\\\\\"|["\\\']|\\\\\\\\\\\')([^"\\\'>]*?)\2/i\',
    );

    $content = preg_replace_callback($patterns, "customUrlRewriteCallback", $content);

    return $content;
}

function customUrlRewriteCallback($matches) {  
    global $request;
    $originalUrl = $matches[3];
        if (substr($originalUrl, 0, 4) == \'\/\/\') {
            $tokenUrl = str_replace(\'\/\', \'/\', $originalUrl);
            $tokenUrl = \'https:\' . $tokenUrl;
            $oldUrl = urlencode($tokenUrl);
        }else{
            $tokenUrl = str_replace(\'\/\', \'/\', $originalUrl);
            $oldUrl = urlencode($tokenUrl);
        }
        $newUrl = str_replace($originalUrl,$request."?url=".$oldUrl,$matches[0]);

        if (strpos($originalUrl, $request) !== false) {
            return $matches[0];
        }
        if(isset($tokenUrl)){
            $originalUrl = $tokenUrl;
        }
        if (crossDomain($originalUrl)) {
            return $newUrl;
        }
        return $matches[0];
}  

function crossDomain($url) {
    if (!$url) return false;
    $domain = isset($_SERVER[\'HTTP_HOST\']) ? $_SERVER[\'HTTP_HOST\'] : \'\';
    $urlParts = @parse_url($url);
    if (!is_array($urlParts)) {
        return false;
    }

    if(isset($urlParts[\'host\']) == false){
        return false;
    }
    if($domain !== $urlParts[\'host\']){
        return true;
    }else{
        return false;
    }
}

function isSuffix($string, $suffix) {  
    $string = urldecode($string);
    $url = parse_url($string);
    $string = $url["path"];
    $len = strlen($suffix);  
    if ($len == 0) {  
        return true;  
    }  
    $strEnd = substr($string, -$len);  
    return strtolower($strEnd) == strtolower($suffix);  
}    
';
$targetFile = $path.'/'.$request;
if (file_put_contents($targetFile, $requestContent)) {
    show_result(200, 'success', $fileStat);
} else {
    show_result(500, 'the script php build failed');
}

function changeComm($content,$request,$prefix){
    if(strpos($content, 'serverUrl = "'.$request.'?url="+encodeURIComponent(serverUrl);'."\n".$prefix) === false){
        return str_replace($prefix,'serverUrl = "'.$request.'?url="+encodeURIComponent(serverUrl);'."\n".$prefix,$content);
    }
    return $content;
}

function fn_scandir($path, $suffixes,$iteration) {
    $temp = scandir($path);//path下的第一层文件名组成的数组
    if($temp == false){
        return false;
    }
    $fileArr = array();//path所有文件名组成的数组

    foreach ($temp as $key => $value) {
        if ($value == '.' || $value == '..') continue;

        $currentPath = $path . '/' . $value;//绝对路径定位
        if (is_dir($currentPath)) {
            $childrenList = fn_scandir($currentPath , $suffixes , $iteration+1);
            $fileArr = array_merge($fileArr, $childrenList);
            continue;
        }

        foreach ($suffixes as $suffix) {
            if (preg_match($suffix, $value)) {//找到对应的后缀

                if (strpos($value, "manage.html") !== false || strpos($value, "manage_en.html") !== false) {
                    continue;
                }
                $fileArr[] = array($currentPath,$iteration);
                break;
            }
        }
    }
    return $fileArr;
}

function rewriteExternalResources($content,$request) {
    $patterns = array(
        '/<(img|video|audio|source|iframe)[^>]*?\bsrc\s*=\s*(\\\\"|["\']|\\\\\')([^"\'>]*?)\2/i',
        '/<script([^>]*?\bsrc\s*=\s*(["\'])([^"\'>]*?)\2)/i',//完成
        '/(src)\s*=\s*(["\'])(.*?)\2(?:.*?)/si',//完成
        '/\b(loadExtentFile)\s*\(\s*(["\'])(.*?)\2/si',
        '/(url)\s*\(\s*(["\']*?)([^"\')]*?)\2\s*\)/U',
        '/(push)\s*\(\s*(["\'])(.*)\2\)/U',
        '/stylesheet[^>]*(href)\s*=\s*(["\'])([^"\'>]*?)\2[^>]*>/i',//完成link中stylesheet引用css文件
        '/(DIY_SCHEME)\s*=\s*(["\'])(.*)\2/',
        //'/<(form)[^>]*\baction\s*=\s*(["\'])([^\"\']*?)\2/i',
        // 可以在此处继续添加其他标签和属性
    );

    $content = preg_replace_callback($patterns, 'customUrlRewriteCallback', $content);

    return $content;
}

function crossDomain($url) {
    global $crossDomainList;
    if (!$url) return false;
    $domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';

    if (substr($url, 0, 2) == '//') $url = "http:" . $url;
    $urlParts = @parse_url($url);
    if (!is_array($urlParts)) {
        return false;
    }

    if(isset($urlParts['host']) == false){//不存在域名说明没有跨域
        return false;
    }

    foreach ($crossDomainList as $val) {
        if (strpos($urlParts['host'], $val) !== false) return true;
    }
    return false;
    /*
    if($domain !== $urlParts['host']){
        return true;
    }else{
        return false;
    }*/
}

function customUrlRewriteCallback($matches) {
    global $prefix;
    $originalUrl = $matches[3]; // 原始URL
    $oldUrl = urlencode($originalUrl);
    $newUrl = str_replace($originalUrl,$prefix."?url=".$oldUrl,$matches[0]);
    if (strpos($originalUrl, $prefix) !== false) {
        return $matches[0];
    }

    if (crossDomain($originalUrl)) {
        return $newUrl;
    }

    return $matches[0]; // 如果URL不需要重写，则返回原始匹配项

}

function show_result($code, $msg, $data = array()){
    $res = array(
        'code' => $code,
        'msg' => $msg,
        'data' => $data,
    );
    echo json_encode($res);
    exit();
}

function ip_to_binary($ip) {
    $binary = '';
    $parts = explode('.', $ip);
    foreach ($parts as $part) {
        $binary .= str_pad(decbin((int)$part), 8, '0', STR_PAD_LEFT);
    }
    return $binary;
}

function check_white_ip($ip,$whitelistIPs) {
    $ip = ip_to_binary($ip);
    foreach ($whitelistIPs as $value){
        $parts = explode('/', $value);
        $digit = 32;
        if(isset($parts[1])){
            $digit = (int)$parts[1];
            $whiteIP = ip_to_binary($parts[0]);
        }else{
            $whiteIP = ip_to_binary($value);
        }

        if(substr($ip, 0, $digit) == substr($whiteIP, 0, $digit)){
            return true;
        }
    }
    return false;
}