$value) {
$url .= $sep . $key .'='. urlencode($value);
$sep = '&';
}
// Send back the right method
$method = $_SERVER['REQUEST_METHOD'];
/*
* Common awaited Content-Type header values:
* - Content-Type: text/html
* - Content-Type: application/x-www-form-urlencoded
* - Content-Type: multipart/form-data
* - Content-Type: application/xml
* The fact is, whatever sends the remote client, if this header is present we
* must send back data, which we get back.
*/
if (isset($_SERVER['CONTENT_TYPE']) && ! empty($_SERVER['CONTENT_LENGTH'])) {
// Get back the correct data
$headers['Content-Type'] = $_SERVER['CONTENT_TYPE'];
$headers['Content-Length'] = $_SERVER['CONTENT_LENGTH'];
$data = @file_get_contents('php://input');
//$data = @$GLOBALS["HTTP_RAW_POST_DATA"];
}
else {
$data = NULL;
}
/*
* Additional request headers present in $_SERVER with prefix HTTP_.
* E.g. HTTP_ACCEPT etc.
*/
foreach ($_SERVER as $key => $value) {
if (strpos($key, 'HTTP_') === 0 && !in_array($key, $ignore_headers)) {
$key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
$headers[$key] = $value;
}
}
// Signal that the connection will be closed after completion of the response
$headers['Connection'] = 'close';
// Proxy request should pass on cookie headers to prevent Drupal from
// ending a session. Note: only if same host as this site!
if (!empty($_COOKIE) && $_SERVER['HTTP_HOST'] == parse_url($url, PHP_URL_HOST)) {
$cookies = ''; $sep = '';
foreach ($_COOKIE as $key => $value) {
$cookies .= $sep . $key .'='. $value;
$sep = '; ';
}
$headers['Cookie'] = $cookies;
}
// Now make request to target
//$response = drupal_http_request($url, $headers, $method, $data);
$result = new stdClass();
// Parse the URL and make sure we can handle the schema.
$uri = parse_url($url);
switch ($uri['scheme']) {
case 'http':
$port = isset($uri['port']) ? $uri['port'] : 80;
$host = $uri['host'] . ($port != 80 ? ':'. $port : '');
$fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15);
break;
case 'https':
// Note: Only works for PHP 4.3 compiled with OpenSSL.
$port = isset($uri['port']) ? $uri['port'] : 443;
$host = $uri['host'] . ($port != 443 ? ':'. $port : '');
$fp = @fsockopen('ssl://'. $uri['host'], $port, $errno, $errstr, 20);
break;
default:
header('HTTP/1.1 400 Bad Request');
die('Invalid schema');
}
// Make sure the socket opened properly.
if (!$fp) {
// When a network error occurs, we use a negative number so it does not
// clash with the HTTP status codes.
// @todo: return code for network error?
// header()
die('Network error: '. $errstr .' ('. $errno . ')');
}
// Construct the path to act on.
$path = isset($uri['path']) ? $uri['path'] : '/';
if (isset($uri['query'])) {
$path .= '?'. $uri['query'];
}
// Create HTTP request.
$defaults = array(
// RFC 2616: "non-standard ports MUST, default ports MAY be included".
// We don't add the port to prevent from breaking rewrite rules checking the
// host that do not take into account the port number.
'Host' => "Host: $host",
'User-Agent' => 'User-Agent: Proxy (+http://aardbodem.nl/)',
'Content-Length' => 'Content-Length: '. strlen($data)
);
// If the server url has a user then attempt to use basic authentication
if (isset($uri['user'])) {
$defaults['Authorization'] = 'Authorization: Basic '. base64_encode($uri['user'] . (!empty($uri['pass']) ? ":". $uri['pass'] : ''));
}
foreach ($headers as $header => $value) {
$defaults[$header] = $header .': '. $value;
}
$request = $method .' '. $path ." HTTP/1.0\r\n";
$request .= implode("\r\n", $defaults);
$request .= "\r\n\r\n";
if ($data) {
$request .= $data ."\r\n";
}
$result->request = $request;
fwrite($fp, $request);
// Fetch response.
$response = '';
$count = 0;
while (!feof($fp) && $chunk = fread($fp, 1024)) {
//echo 'chunk '. ++$count .'
';
if (! $result->data) {
$response .= $chunk;
list($split, $result->data) = explode("\r\n\r\n", $response, 2);
//echo var_export($result, true) . '
';
}
else {
//$result->data .= $chunk;
if (! $result->headers) {
//echo 'header was received
';
// process header in $split
$split = preg_split("/\r\n|\n|\r/", $split);
list($protocol, $code, $text) = explode(' ', trim(array_shift($split)), 3);
// Parse headers
$result->headers = array();
while ($line = trim(array_shift($split))) {
list($header, $value) = explode(':', $line, 2);
if (isset($result->headers[$header]) && $header == 'Set-Cookie') {
// RFC 2109: the Set-Cookie response header comprises the token Set-
// Cookie:, followed by a comma-separated list of one or more cookies.
$result->headers[$header] .= ','. trim($value);
}
else {
$result->headers[$header] = trim($value);
}
}
// Check headers
if (! empty($permitted_content_types)) {
$lowercase_headers = array_change_key_case($result->headers, CASE_LOWER);
if (0 == preg_match($permitted_content_types, $lowercase_headers['content-type'])) {
header('HTTP/1.1 403 Forbidden');
die('Content type not permitted');
}
}
// Return headers to caller
foreach ($result->headers as $key => $value) {
header($key .': '. $value, true);
}
// Echo first part of data
echo $result->data;
}
// Echo chunk of data
echo $chunk;
}
}
fclose($fp);
exit();