\r\n"; if ( $backendPath == '/' ) $backendPath = substr($uriPath, 0 ,strlen($uriPath)-1); else $backendPath = $uriPath; $target = $backendScheme . '://' . $backendHost . ':' . $backendPort . $backendPath; if ($query !== '') { $target .= '?' . $query; } //die( $target); $ch = curl_init($target); $headers = [ 'Host: ' . $publicHost, 'X-Forwarded-Host: ' . $publicHost, 'X-Forwarded-Proto: ' . $forwardProto, 'X-Forwarded-For: ' . ($_SERVER['REMOTE_ADDR'] ?? ''), 'X-Forwarded-Prefix: ' . $mountPrefix, 'Https: 1', ]; $contentType = $_SERVER['CONTENT_TYPE'] ?? ''; if ($contentType !== '') { $headers[] = 'Content-Type: ' . $contentType; } if ($method === 'POST') { $body = file_get_contents('php://input'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $body); } curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 10, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => $headers, CURLOPT_HEADER => true, ]); $response = curl_exec($ch); if ($response === false) { http_response_code(502); header('Content-Type: text/plain; charset=UTF-8'); echo 'Backend error: ' . curl_error($ch) . "\n"; curl_close($ch); exit; } $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); curl_close($ch); $rawHeaders = substr($response, 0, $headerSize); $responseBody = substr($response, $headerSize); http_response_code($statusCode ?: 502); $hopByHop = [ 'connection', 'transfer-encoding', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'upgrade', ]; foreach (explode("\r\n", $rawHeaders) as $line) { if (strpos($line, ':') === false) { continue; } [$name, $value] = explode(':', $line, 2); $name = trim($name); $value = trim($value); if ($name === '') { continue; } if (in_array(strtolower($name), $hopByHop, true)) { continue; } header($name . ': ' . $value, false); } echo $responseBody;