Advertisement
CYBERSERKERS

Simple PHP Proxy

Feb 14th, 2016
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.56 KB | None | 0 0
  1. <?php
  2. ob_start("ob_gzhandler");
  3.  
  4. if (!function_exists("curl_init")) die ("This proxy requires PHP's cURL extension. Please install/enable it on your server and try again.");
  5.  
  6. if (!function_exists("getallheaders")) {
  7.   function getallheaders() {
  8.     $result = array();
  9.     foreach($_SERVER as $key => $value) {
  10.       if (substr($key, 0, 5) == "HTTP_") {
  11.         $key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
  12.         $result[$key] = $value;
  13.       } else {
  14.         $result[$key] = $value;
  15.       }
  16.     }
  17.     return $result;
  18.   }
  19. }
  20.  
  21. define("PROXY_PREFIX", "http" . (isset($_SERVER['HTTPS']) ? "s" : "") . "://" . $_SERVER["SERVER_NAME"] . ($_SERVER["SERVER_PORT"] != 80 ? ":" . $_SERVER["SERVER_PORT"] : "") . $_SERVER["SCRIPT_NAME"] . "/");
  22.  
  23. function makeRequest($url) {
  24.  
  25.   $user_agent = $_SERVER["HTTP_USER_AGENT"];
  26.   if (empty($user_agent)) {
  27.     $user_agent = "Mozilla/5.0 (compatible; miniProxy)";
  28.   }
  29.   $ch = curl_init();
  30.   curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
  31.  
  32.   $browserRequestHeaders = getallheaders();
  33.  
  34.   unset($browserRequestHeaders["Host"]);
  35.   unset($browserRequestHeaders["Content-Length"]);
  36.  
  37.   unset($browserRequestHeaders["Accept-Encoding"]);
  38.   curl_setopt($ch, CURLOPT_ENCODING, "");
  39.  
  40.   $curlRequestHeaders = array();
  41.   foreach ($browserRequestHeaders as $name => $value) {
  42.     $curlRequestHeaders[] = $name . ": " . $value;
  43.   }
  44.   curl_setopt($ch, CURLOPT_HTTPHEADER, $curlRequestHeaders);
  45.  
  46.   switch ($_SERVER["REQUEST_METHOD"]) {
  47.     case "POST":
  48.       curl_setopt($ch, CURLOPT_POST, true);
  49.  
  50.       curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents("php://input"));
  51.     break;
  52.     case "PUT":
  53.       curl_setopt($ch, CURLOPT_PUT, true);
  54.       curl_setopt($ch, CURLOPT_INFILE, fopen("php://input"));
  55.     break;
  56.   }
  57.  
  58.   curl_setopt($ch, CURLOPT_HEADER, true);
  59.   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  60.   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  61.   curl_setopt ($ch, CURLOPT_FAILONERROR, true);
  62.  
  63.   curl_setopt($ch, CURLOPT_URL, $url);
  64.  
  65.   $response = curl_exec($ch);
  66.   $responseInfo = curl_getinfo($ch);
  67.   $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  68.   curl_close($ch);
  69.  
  70.   $responseHeaders = substr($response, 0, $headerSize);
  71.   $responseBody = substr($response, $headerSize);
  72.  
  73.   return array("headers" => $responseHeaders, "body" => $responseBody, "responseInfo" => $responseInfo);
  74. }
  75.  
  76. function rel2abs($rel, $base) {
  77.   if (empty($rel)) $rel = ".";
  78.   if (parse_url($rel, PHP_URL_SCHEME) != "" || strpos($rel, "//") === 0) return $rel;
  79.   if ($rel[0] == "#" || $rel[0] == "?") return $base.$rel;
  80.   extract(parse_url($base));
  81.   $path = isset($path) ? preg_replace('#/[^/]*$#', "", $path) : "/";
  82.   if ($rel[0] == '/') $path = "";
  83.   $port = isset($port) && $port != 80 ? ":" . $port : "";
  84.   $auth = "";
  85.   if (isset($user)) {
  86.     $auth = $user;
  87.     if (isset($pass)) {
  88.       $auth .= ":" . $pass;
  89.     }
  90.     $auth .= "@";
  91.   }
  92.   $abs = "$auth$host$path$port/$rel";
  93.   for ($n = 1; $n > 0; $abs = preg_replace(array("#(/\.?/)#", "#/(?!\.\.)[^/]+/\.\./#"), "/", $abs, -1, $n)) {}
  94.   return $scheme . "://" . $abs;
  95. }
  96.  
  97. function proxifyCSS($css, $baseURL) {
  98.   return preg_replace_callback(
  99.     '/url\((.*?)\)/i',
  100.     function($matches) use ($baseURL) {
  101.         $url = $matches[1];
  102.         if (strpos($url, "'") === 0) {
  103.           $url = trim($url, "'");
  104.         }
  105.         if (strpos($url, "\"") === 0) {
  106.           $url = trim($url, "\"");
  107.         }
  108.         if (stripos($url, "data:") === 0) return "url(" . $url . ")";
  109.         return "url(" . PROXY_PREFIX . rel2abs($url, $baseURL) . ")";
  110.     },
  111.     $css);
  112. }
  113.  
  114. $url = substr($_SERVER["REQUEST_URI"], strlen($_SERVER["SCRIPT_NAME"]) + 1);
  115. if (empty($url)) die("<html><head><title>PHProxy</title></head><head>
  116. <body bgcolor=black><center><a href=http://azzatssinz.tumblr.com><img src=http://azzat.wap.mu/files/1049320/piZap_1451738626699.jpg></a><br>
  117.    <style>
  118.        input { margin:0;background-color:#000000;border:1px solid #000000; }
  119. </style>
  120. <center><form onsubmit=\"window.location.href='" . PROXY_PREFIX . "' + document.getElementById('site').value; return false;\" /><input method=\"post\" id=\"site\" type=\"text\" size=\"30\" /><input type=\"submit\" value=\"GO!!!\" /></form></center></body></html>");
  121. if (strpos($url, "//") === 0) $url = "http:" . $url;
  122. if (!preg_match("@^.*://@", $url)) $url = "http://" . $url;
  123.  
  124. $response = makeRequest($url);
  125. $rawResponseHeaders = $response["headers"];
  126. $responseBody = $response["body"];
  127. $responseInfo = $response["responseInfo"];
  128.  
  129. $header_blacklist_pattern = "/^Content-Length|^Transfer-Encoding|^Content-Encoding.*gzip/i";
  130.  
  131. $responseHeaderBlocks = array_filter(explode("\r\n\r\n", $rawResponseHeaders));
  132. $lastHeaderBlock = end($responseHeaderBlocks);
  133. $headerLines = explode("\r\n", $lastHeaderBlock);
  134. foreach ($headerLines as $header) {
  135.     $header = trim($header);
  136.     if (!preg_match($header_blacklist_pattern, $header)) {
  137.       header($header);
  138.     }
  139. }
  140.  
  141. $contentType = "";
  142. if (isset($responseInfo["content_type"])) $contentType = $responseInfo["content_type"];
  143.  
  144. if (stripos($contentType, "text/html") !== false) {
  145.  
  146.   $detectedEncoding = mb_detect_encoding($responseBody, "UTF-8, ISO-8859-1");
  147.   if ($detectedEncoding) {
  148.     $responseBody = mb_convert_encoding($responseBody, "HTML-ENTITIES", $detectedEncoding);
  149.   }
  150.  
  151.   $doc = new DomDocument();
  152.   @$doc->loadHTML($responseBody);
  153.   $xpath = new DOMXPath($doc);
  154.  
  155.   foreach($xpath->query('//form') as $form) {
  156.     $method = $form->getAttribute("method");
  157.     $action = $form->getAttribute("action");
  158.  
  159.     $action = empty($action) ? $url : rel2abs($action, $url);
  160.  
  161.     $form->setAttribute("action", PROXY_PREFIX . $action);
  162.   }
  163.   foreach($xpath->query('//style') as $style) {
  164.     $style->nodeValue = proxifyCSS($style->nodeValue, $url);
  165.   }
  166.   foreach ($xpath->query('//*[@style]') as $element) {
  167.     $element->setAttribute("style", proxifyCSS($element->getAttribute("style"), $url));
  168.   }
  169.   $proxifyAttributes = array("href", "src");
  170.   foreach($proxifyAttributes as $attrName) {
  171.     foreach($xpath->query('//*[@' . $attrName . ']') as $element) {
  172.       $attrContent = $element->getAttribute($attrName);
  173.       if ($attrName == "href" && (stripos($attrContent, "javascript:") === 0 || stripos($attrContent, "mailto:") === 0)) continue;
  174.       $attrContent = rel2abs($attrContent, $url);
  175.       $attrContent = PROXY_PREFIX . $attrContent;
  176.       $element->setAttribute($attrName, $attrContent);
  177.     }
  178.   }
  179.  
  180.  
  181.   $head = $xpath->query('//head')->item(0);
  182.   $body = $xpath->query('//body')->item(0);
  183.   $prependElem = $head != NULL ? $head : $body;
  184.  
  185.  
  186.   if ($prependElem != NULL) {
  187.  
  188.     $scriptElem = $doc->createElement("script",
  189.       '(function() {
  190.  
  191.        if (window.XMLHttpRequest) {
  192.  
  193.          function parseURI(url) {
  194.            var m = String(url).replace(/^\s+|\s+$/g, "").match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
  195.            // authority = "//" + user + ":" + pass "@" + hostname + ":" port
  196.            return (m ? {
  197.              href : m[0] || "",
  198.              protocol : m[1] || "",
  199.              authority: m[2] || "",
  200.              host : m[3] || "",
  201.              hostname : m[4] || "",
  202.              port : m[5] || "",
  203.              pathname : m[6] || "",
  204.              search : m[7] || "",
  205.              hash : m[8] || ""
  206.            } : null);
  207.          }
  208.  
  209.          function rel2abs(base, href) { // RFC 3986
  210.  
  211.            function removeDotSegments(input) {
  212.              var output = [];
  213.              input.replace(/^(\.\.?(\/|$))+/, "")
  214.                .replace(/\/(\.(\/|$))+/g, "/")
  215.                .replace(/\/\.\.$/, "/../")
  216.                .replace(/\/?[^\/]*/g, function (p) {
  217.                  if (p === "/..") {
  218.                    output.pop();
  219.                  } else {
  220.                    output.push(p);
  221.                  }
  222.                });
  223.              return output.join("").replace(/^\//, input.charAt(0) === "/" ? "/" : "");
  224.            }
  225.  
  226.            href = parseURI(href || "");
  227.            base = parseURI(base || "");
  228.  
  229.            return !href || !base ? null : (href.protocol || base.protocol) +
  230.            (href.protocol || href.authority ? href.authority : base.authority) +
  231.            removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === "/" ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? "/" : "") + base.pathname.slice(0, base.pathname.lastIndexOf("/") + 1) + href.pathname) : base.pathname)) +
  232.            (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
  233.            href.hash;
  234.  
  235.          }
  236.  
  237.          var proxied = window.XMLHttpRequest.prototype.open;
  238.          window.XMLHttpRequest.prototype.open = function() {
  239.              if (arguments[1] !== null && arguments[1] !== undefined) {
  240.                var url = arguments[1];
  241.                url = rel2abs("' . $url . '", url);
  242.                url = "' . PROXY_PREFIX . '" + url;
  243.                arguments[1] = url;
  244.              }
  245.              return proxied.apply(this, [].slice.call(arguments));
  246.          };
  247.  
  248.        }
  249.  
  250.      })();'
  251.     );
  252.     $scriptElem->setAttribute("type", "text/javascript");
  253.  
  254.     $prependElem->insertBefore($scriptElem, $prependElem->firstChild);
  255.  
  256.   }
  257.  
  258.   echo "<!-- AZZATSSINS -->\n" . $doc->saveHTML();
  259. } else if (stripos($contentType, "text/css") !== false) {
  260.   echo proxifyCSS($responseBody, $url);
  261. } else {
  262.   header("Content-Length: " . strlen($responseBody));
  263.   echo $responseBody;
  264. }
  265. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement