2015-04-07 23:06:19 +02:00
|
|
|
<?php
|
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
class Proxy {
|
|
|
|
public function __construct($serv, $port = 80, $root = '/', $localRoot = '') {
|
|
|
|
// Functions
|
|
|
|
function str_replace_once($search, $replace, $subject) { // TODO Credit
|
|
|
|
$pos = strpos($subject, $search);
|
|
|
|
if ($pos === false) {
|
|
|
|
return $subject;
|
|
|
|
}
|
2015-04-07 23:04:07 +02:00
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
return substr($subject, 0, $pos) . $replace . substr($subject, $pos + strlen($search));
|
2015-04-07 23:06:19 +02:00
|
|
|
}
|
2015-04-09 19:46:07 +02:00
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
if (!function_exists('getallheaders')) { // TODO Credit
|
|
|
|
function getallheaders() {
|
|
|
|
if (!is_array($_SERVER)) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
|
|
|
|
$headers = array();
|
|
|
|
foreach ($_SERVER as $name => $value) {
|
|
|
|
if (substr($name, 0, 5) == 'HTTP_') {
|
|
|
|
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $headers;
|
2015-04-07 23:06:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
// Target determination
|
|
|
|
$metd = $_SERVER['REQUEST_METHOD'];
|
|
|
|
$reqp = $_SERVER['REQUEST_URI'];
|
2015-04-09 21:59:17 +02:00
|
|
|
if ($localRoot != '') {
|
|
|
|
$reqp = str_replace_once($localRoot, '', $reqp); // TODO Reliable method
|
|
|
|
}
|
2015-04-07 23:06:19 +02:00
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
// Preparing request headers
|
|
|
|
$reqHeds = "$metd $root$reqp HTTP/1.1\r\n";
|
|
|
|
$reqHeds .= "Host: $serv:$port\r\n";
|
2015-04-07 23:06:19 +02:00
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
// Converting client request headers to server request headers
|
|
|
|
$reqsHedsC = getallheaders();
|
|
|
|
foreach ($reqsHedsC as $name => $content) {
|
|
|
|
if ($name != 'Host' && $name != 'Connection') { // TODO More analysis
|
|
|
|
$reqHeds .= "$name: $content\r\n";
|
|
|
|
}
|
|
|
|
}
|
2015-04-07 23:06:19 +02:00
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
if ($metd == 'POST') { // TODO Other with data methods
|
|
|
|
if (isset($_POST['payload'])) {
|
|
|
|
$postData = stripslashes($_POST['payload']);
|
|
|
|
$reqHeds .= "Content-Length: ".strlen($postData)."\r\n";
|
|
|
|
$reqHeds .= "Connection: Close\r\n";
|
|
|
|
$reqHeds .= "\r\n" . $postData;
|
|
|
|
} else {
|
|
|
|
$postinfo = '';
|
|
|
|
foreach ($_POST as $key => $value) {
|
|
|
|
$postinfo .= $key . '=' . urlencode($value) . '&';
|
|
|
|
}
|
|
|
|
$postinfo = rtrim($postinfo, '&');
|
|
|
|
$reqHeds .= "\r\n" . $postinfo;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$reqHeds .= "Connection: Close\r\n\r\n";
|
2015-04-09 19:49:59 +02:00
|
|
|
}
|
2015-04-07 23:06:19 +02:00
|
|
|
|
|
|
|
|
2015-04-09 21:49:50 +02:00
|
|
|
$fp = fsockopen($serv, $port, $errno, $errstr, 30);
|
|
|
|
if (!$fp) { // TODO ErrorCode, ErrorDocument
|
|
|
|
echo "Couldn't connect to server\n<br/>$errstr ($errno)<br />\n";
|
2015-04-07 23:06:19 +02:00
|
|
|
} else {
|
2015-04-09 21:49:50 +02:00
|
|
|
// Sending request
|
|
|
|
fwrite($fp, $reqHeds);
|
|
|
|
$resBuf = '';
|
|
|
|
while ($get = fgets($fp, 128)) {
|
|
|
|
// Getting response
|
|
|
|
if ($resBuf === True) { // If headers sent
|
|
|
|
echo $get;
|
|
|
|
} else {
|
|
|
|
$resBuf .= $get;
|
|
|
|
if ($sepPos = strrpos($resBuf, "\r\n\r\n")) { // Headers have been retrieved
|
|
|
|
$resHeds = explode("\r\n", substr($resBuf, 0, $sepPos));
|
|
|
|
foreach ($resHeds as $resHed) { // Setting headers
|
|
|
|
header($resHed);
|
|
|
|
if (substr($resHed, 0, 4) == 'HTTP') { // FastCGI fix when using ErrorDocument
|
|
|
|
header('Status: ' . substr($resHed, 9));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
echo substr($resBuf, $sepPos + 4); // Sending the rest (usually empty)
|
|
|
|
$resBuf = True; // Setting mode to automatically redirect
|
2015-04-07 23:06:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-09 21:49:50 +02:00
|
|
|
fclose($fp);
|
2015-04-07 23:06:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-09 21:49:50 +02:00
|
|
|
|
2015-04-09 19:46:07 +02:00
|
|
|
?>
|