// https://github.com/gnh1201/caterpillar // Created at: 2022-10-06 // Updated at: 2024-02-26 define("PHP_HTTPPROXY_VERSION", "0.2.0-dev"); if (strpos($_SERVER['HTTP_USER_AGENT'], "php-httpproxy/") !== 0) { exit('It works!

It works!

Download the client


php-httpproxy/' . PHP_HTTPPROXY_VERSION . ' (Server; PHP ' . phpversion() . '; abuse@catswords.net)

'); } ini_set("default_socket_timeout", 1); // must be. because of `feof()` works ini_set("max_execution_time", 0); function parse_headers($str) { // Parses HTTP headers into an array // https://stackoverflow.com/questions/16934409/curl-as-proxy-deal-with-https-connect-method // https://stackoverflow.com/questions/12433958/how-to-parse-response-headers-in-php $headers = array(); $lines = preg_split("'\r?\n'", $str); $first_line = array_shift($lines); $headers['@method'] = explode(' ', $first_line); foreach ($lines as $line) { if (!preg_match('/^([^:]+):(.*)$/', $line, $out)) continue; $headers[$out[1]] = trim($out[2]); } return $headers; } // stateless mode function relay_request($params) { $buffer_size = $params['chunksize']; $relay_data = base64_decode($params['data']); $relay_headers = parse_headers($relay_data); $relay_port = intval($params['port']); $relay_scheme = $params['scheme']; $relay_hostname = $params['server']; if (in_array($relay_scheme, array("https", "ssl", "tls"))) { $relay_hostname = "tls://" . $relay_hostname; } switch ($relay_headers['@method'][0]) { case "CONNECT": echo sprintf("%s 200 Connection Established\r\n\r\n", $relay_headers['@method'][2]); break; default: $fp = fsockopen($relay_hostname, $relay_port, $errno, $errstr, 1); if (!$fp) { echo "$errstr ($errno)
\n"; } else { fwrite($fp, $relay_data); $buf = null; while (!feof($fp) && $buf !== false) { $buf = fgets($fp, $buffer_size); echo $buf; } fclose($fp); } } } // stateful mode function relay_connect($params) { // todo } // parse context $context = json_decode(file_get_contents('php://input'), true); // check is it jsonrpc if ($context['jsonrpc'] == "2.0") { $method = $context['method']; switch ($method) { case "relay_request": relay_request($context['params']); // stateless mode break; case "relay_connect": relay_connect($context['params']); // stateful mode break; } }