Update index.php
Browse files
index.php
CHANGED
|
@@ -1,14 +1,14 @@
|
|
| 1 |
<?php
|
| 2 |
-
// By: Colime – PHP
|
| 3 |
|
| 4 |
-
//
|
| 5 |
if ($_SERVER['REQUEST_URI'] === '/' || $_SERVER['REQUEST_URI'] === '') {
|
| 6 |
header('Content-Type: text/html; charset=utf-8');
|
| 7 |
echo '<p>about:blank</p>';
|
| 8 |
exit;
|
| 9 |
}
|
| 10 |
|
| 11 |
-
//
|
| 12 |
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
| 13 |
http_response_code(204);
|
| 14 |
header('Access-Control-Allow-Origin: *');
|
|
@@ -39,16 +39,45 @@ if (!$parts || !isset($parts['host'])) {
|
|
| 39 |
$requestHeaders = getallheaders();
|
| 40 |
$forwardHeaders = [];
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
foreach ($requestHeaders as $name => $value) {
|
| 43 |
$lower = strtolower($name);
|
| 44 |
-
// Drop Cloudflare headers
|
| 45 |
if (strpos($lower, 'cf-') === 0 || $lower === 'x-real-ip' || $lower === 'host') {
|
| 46 |
continue;
|
| 47 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
$forwardHeaders[] = "$name: $value";
|
| 49 |
}
|
|
|
|
|
|
|
| 50 |
$forwardHeaders[] = 'Host: ' . $parts['host'];
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
// cURL request
|
| 53 |
$ch = curl_init($target);
|
| 54 |
curl_setopt_array($ch, [
|
|
@@ -56,11 +85,13 @@ curl_setopt_array($ch, [
|
|
| 56 |
CURLOPT_HTTPHEADER => $forwardHeaders,
|
| 57 |
CURLOPT_RETURNTRANSFER => true,
|
| 58 |
CURLOPT_FOLLOWLOCATION => true,
|
| 59 |
-
CURLOPT_HEADER => true,
|
| 60 |
CURLOPT_TIMEOUT => 30,
|
|
|
|
|
|
|
| 61 |
]);
|
| 62 |
|
| 63 |
-
// Forward request body
|
| 64 |
$body = file_get_contents('php://input');
|
| 65 |
if ($body !== '' && $body !== false) {
|
| 66 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
|
@@ -78,22 +109,25 @@ if ($error) {
|
|
| 78 |
}
|
| 79 |
|
| 80 |
// Split headers and body
|
| 81 |
-
$headerSize
|
| 82 |
$responseHeaders = substr($response, 0, $headerSize);
|
| 83 |
$responseBody = substr($response, $headerSize);
|
| 84 |
|
| 85 |
-
// Parse response headers
|
| 86 |
$headersArr = explode("\r\n", $responseHeaders);
|
| 87 |
$statusCode = 200;
|
| 88 |
-
$outHeaders = []; //
|
| 89 |
|
| 90 |
foreach ($headersArr as $line) {
|
|
|
|
| 91 |
if (stripos($line, 'HTTP/') === 0) {
|
| 92 |
preg_match('/\d{3}/', $line, $m);
|
| 93 |
$statusCode = (int)($m[0] ?? 200);
|
| 94 |
continue;
|
| 95 |
}
|
| 96 |
-
if (trim($line) === '')
|
|
|
|
|
|
|
| 97 |
|
| 98 |
$colon = strpos($line, ':');
|
| 99 |
if ($colon !== false) {
|
|
@@ -101,18 +135,27 @@ foreach ($headersArr as $line) {
|
|
| 101 |
$value = trim(substr($line, $colon + 1));
|
| 102 |
$lower = strtolower($name);
|
| 103 |
|
| 104 |
-
// Remove security headers that
|
| 105 |
if ($lower === 'content-security-policy' || $lower === 'x-frame-options') {
|
| 106 |
continue;
|
| 107 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
$outHeaders[] = [$name, $value];
|
| 109 |
}
|
| 110 |
}
|
| 111 |
|
| 112 |
-
// ---
|
| 113 |
http_response_code($statusCode);
|
| 114 |
|
| 115 |
-
// CORS
|
| 116 |
header('Access-Control-Allow-Origin: *');
|
| 117 |
header('Access-Control-Allow-Methods: *');
|
| 118 |
header('Access-Control-Allow-Headers: *');
|
|
@@ -120,7 +163,7 @@ header('Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate');
|
|
| 120 |
header('Pragma: no-cache');
|
| 121 |
header('Expires: 0');
|
| 122 |
|
| 123 |
-
// Forward upstream headers
|
| 124 |
foreach ($outHeaders as $h) {
|
| 125 |
header($h[0] . ': ' . $h[1]);
|
| 126 |
}
|
|
|
|
| 1 |
<?php
|
| 2 |
+
// By: Colime – PHP reverse proxy, tuned for Google
|
| 3 |
|
| 4 |
+
// Root page
|
| 5 |
if ($_SERVER['REQUEST_URI'] === '/' || $_SERVER['REQUEST_URI'] === '') {
|
| 6 |
header('Content-Type: text/html; charset=utf-8');
|
| 7 |
echo '<p>about:blank</p>';
|
| 8 |
exit;
|
| 9 |
}
|
| 10 |
|
| 11 |
+
// CORS preflight
|
| 12 |
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
| 13 |
http_response_code(204);
|
| 14 |
header('Access-Control-Allow-Origin: *');
|
|
|
|
| 39 |
$requestHeaders = getallheaders();
|
| 40 |
$forwardHeaders = [];
|
| 41 |
|
| 42 |
+
// Hop-by-hop headers that should NOT be forwarded (both request and response)
|
| 43 |
+
$hopByHop = [
|
| 44 |
+
'connection', 'keep-alive', 'proxy-authenticate',
|
| 45 |
+
'proxy-authorization', 'te', 'trailer', 'transfer-encoding',
|
| 46 |
+
'upgrade'
|
| 47 |
+
];
|
| 48 |
+
|
| 49 |
foreach ($requestHeaders as $name => $value) {
|
| 50 |
$lower = strtolower($name);
|
| 51 |
+
// Drop Cloudflare headers, real IP, and original Host
|
| 52 |
if (strpos($lower, 'cf-') === 0 || $lower === 'x-real-ip' || $lower === 'host') {
|
| 53 |
continue;
|
| 54 |
}
|
| 55 |
+
// Don't forward hop-by-hop request headers
|
| 56 |
+
if (in_array($lower, $hopByHop)) {
|
| 57 |
+
continue;
|
| 58 |
+
}
|
| 59 |
+
// Accept-Encoding is handled by cURL automatically; do not forward it
|
| 60 |
+
if ($lower === 'accept-encoding') {
|
| 61 |
+
continue;
|
| 62 |
+
}
|
| 63 |
$forwardHeaders[] = "$name: $value";
|
| 64 |
}
|
| 65 |
+
|
| 66 |
+
// Set the target host
|
| 67 |
$forwardHeaders[] = 'Host: ' . $parts['host'];
|
| 68 |
|
| 69 |
+
// Fallback User-Agent (only if client didn't send one)
|
| 70 |
+
$hasUserAgent = false;
|
| 71 |
+
foreach ($forwardHeaders as $h) {
|
| 72 |
+
if (stripos($h, 'User-Agent:') === 0) {
|
| 73 |
+
$hasUserAgent = true;
|
| 74 |
+
break;
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
if (!$hasUserAgent) {
|
| 78 |
+
$forwardHeaders[] = 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36';
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
// cURL request
|
| 82 |
$ch = curl_init($target);
|
| 83 |
curl_setopt_array($ch, [
|
|
|
|
| 85 |
CURLOPT_HTTPHEADER => $forwardHeaders,
|
| 86 |
CURLOPT_RETURNTRANSFER => true,
|
| 87 |
CURLOPT_FOLLOWLOCATION => true,
|
| 88 |
+
CURLOPT_HEADER => true, // include headers in output
|
| 89 |
CURLOPT_TIMEOUT => 30,
|
| 90 |
+
CURLOPT_ENCODING => '', // accept any compression, decompress automatically
|
| 91 |
+
CURLOPT_SSL_VERIFYPEER => true, // keep enabled (HF has CA certs)
|
| 92 |
]);
|
| 93 |
|
| 94 |
+
// Forward request body (if any)
|
| 95 |
$body = file_get_contents('php://input');
|
| 96 |
if ($body !== '' && $body !== false) {
|
| 97 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
|
|
|
| 109 |
}
|
| 110 |
|
| 111 |
// Split headers and body
|
| 112 |
+
$headerSize = $info['header_size'];
|
| 113 |
$responseHeaders = substr($response, 0, $headerSize);
|
| 114 |
$responseBody = substr($response, $headerSize);
|
| 115 |
|
| 116 |
+
// Parse incoming response headers
|
| 117 |
$headersArr = explode("\r\n", $responseHeaders);
|
| 118 |
$statusCode = 200;
|
| 119 |
+
$outHeaders = []; // name -> value pairs (duplicates allowed, but we'll filter some)
|
| 120 |
|
| 121 |
foreach ($headersArr as $line) {
|
| 122 |
+
// Status line
|
| 123 |
if (stripos($line, 'HTTP/') === 0) {
|
| 124 |
preg_match('/\d{3}/', $line, $m);
|
| 125 |
$statusCode = (int)($m[0] ?? 200);
|
| 126 |
continue;
|
| 127 |
}
|
| 128 |
+
if (trim($line) === '') {
|
| 129 |
+
continue;
|
| 130 |
+
}
|
| 131 |
|
| 132 |
$colon = strpos($line, ':');
|
| 133 |
if ($colon !== false) {
|
|
|
|
| 135 |
$value = trim(substr($line, $colon + 1));
|
| 136 |
$lower = strtolower($name);
|
| 137 |
|
| 138 |
+
// Remove security headers that block iframes
|
| 139 |
if ($lower === 'content-security-policy' || $lower === 'x-frame-options') {
|
| 140 |
continue;
|
| 141 |
}
|
| 142 |
+
// Remove hop-by-hop response headers
|
| 143 |
+
if (in_array($lower, $hopByHop)) {
|
| 144 |
+
continue;
|
| 145 |
+
}
|
| 146 |
+
// cURL already decompressed the body – remove Content-Encoding
|
| 147 |
+
if ($lower === 'content-encoding') {
|
| 148 |
+
continue;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
$outHeaders[] = [$name, $value];
|
| 152 |
}
|
| 153 |
}
|
| 154 |
|
| 155 |
+
// --- Send final response ---
|
| 156 |
http_response_code($statusCode);
|
| 157 |
|
| 158 |
+
// Always add CORS and no-cache headers
|
| 159 |
header('Access-Control-Allow-Origin: *');
|
| 160 |
header('Access-Control-Allow-Methods: *');
|
| 161 |
header('Access-Control-Allow-Headers: *');
|
|
|
|
| 163 |
header('Pragma: no-cache');
|
| 164 |
header('Expires: 0');
|
| 165 |
|
| 166 |
+
// Forward upstream headers (except those we filtered out)
|
| 167 |
foreach ($outHeaders as $h) {
|
| 168 |
header($h[0] . ': ' . $h[1]);
|
| 169 |
}
|