I have asked a question on this before, but again ran into problems and just cannot solve it. I have a internal proxy server and a content server. The code on the proxy server is this. (Some comments may be wrong but leaving here to convey what is my understanding):
<?php
session_start();
$data_server_url = "http://my_data_server_url/";
$i_var_prefix="i_var_";
$process_headers_separately=0;
//$process_headers_separately=1;
// WARNING! Has problems with GZIPPED DATA!
// AVOID/REMOVE OPTION ALLTOGETHER
// (Set to 1 if you want to catch received headers
// and send explicit headers to clients)
//-----------------------------------------
// Other important request dependent 'SERVER' variables.
if(isset($_SERVER['HTTPS']))
{ $_POST["${i_var_prefix}_HTTPS"]=$_SERVER['HTTPS']; };
if(isset($_SERVER['REMOTE_ADDR']))
{ $_POST["${i_var_prefix}_REMOTE_ADDR"]=$_SERVER['REMOTE_ADDR']; };
$request_uri="";
if(isset($_SERVER['REQUEST_URI'])) { $request_uri = $_SERVER['REQUEST_URI']; };
$curl_url="${data_server_url}${request_uri}";
$field_array= array(
'Accept' => 'HTTP_ACCEPT',
'Accept-Charset' => 'HTTP_ACCEPT_CHARSET',
'Accept-Encoding' => 'HTTP_ACCEPT_ENCODING',
'Accept-Language' => 'HTTP_ACCEPT_LANGUAGE',
'Connection' => 'HTTP_CONNECTION',
'Host' => 'HTTP_HOST',
'Referer' => 'HTTP_REFERER',
'User-Agent' => 'HTTP_USER_AGENT'
);
$curl_request_headers=array();
foreach ($field_array as $key => $value) {
if(isset($_SERVER["$value"])) {
$server_value=$_SERVER["$value"];
$curl_request_headers[]="$key: $server_value";
}
};
//------
session_write_close();
//Open connection
$curl_handle = curl_init();
curl_setopt($curl_handle,CURLOPT_COOKIE,session_name()."=".session_id().";");
//Set the url, number of POST vars, POST data
curl_setopt($curl_handle, CURLOPT_URL, $curl_url);
curl_setopt($curl_handle, CURLOPT_POST, count($_POST));
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $_POST);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($curl_handle, CURLOPT_HEADER, $process_headers_separately);
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $curl_request_headers);
curl_setopt($curl_handle, CURLOPT_ENCODING, "identity");
//Execute post
$result = curl_exec($curl_handle);
//Close connection
curl_close($curl_handle);
if ($process_headers_separately) {
list($headers,$content)=explode("\r\n\r\n",$result,2);
foreach (explode("\r\n",$headers) as $hdr) {
header($hdr);
}
echo $content;
} else {
echo $result;
}
?>
Problem 1: With the current code, even if the Content-Type returned by the data_server is text/plain, the content-type seen by the client is text/html. For example, see http://sarcastic-quotes.com/robots.txt This request goes to the file above. I have checked that the data server is actually returning Content-Type as text/plain. But through the proxy, client sees content-type in response headers as text/html.
Problem 2: Note the use of variable process_headers_separately. If I set it to 1, then the browser tries to download a gzip file instead of displaying the contents (no matter what content-type the data server returns). Thus, there is some logical bug in that code flow.
I just want the above code to work as an internal proxy that seamlessly acts as a bridge between my data server and the client. Any thoughts would be appreciated, I am really confused with how to correctly handle the headers above.
regards, JP
I have found the cause of the problem when process_headers_separately=1 (browser downloading file instead of displaying). But it is SO strange and am unable to solve it. Problem: If I uncomment the lines if(isset($_SERVER['REMOTE_ADDR'])) { $_POST["${i_var_prefix}_REMOTE_ADDR"]=$_SERVER['REMOTE_ADDR']; };
then things start working fine! Strange!
Its gotta be some crazy whitespace problem like Neil suggested.
Anyways, trying to fix this - I have spent 3 days (2 earlier and 1 now) due to this crazy bug :(. Thanks to Neil and RF for helping me on this.
Content-Typeheader is set to something the browser can't display, likeapplication/octet-stream, or theContent-Dispositionheader is set incorrectly. Compressed data not being decompressed, with the right headers, should at least just show gobbledegook.Content-Encodingresponse header from CURL and the output it actually serves. CURL will try to decompress content if it thinks it can, so you'll need to recompress it usinggzcompress()orgzdeflate(). Apart from compressing, is your content type issue still around? Also, try replacing$curl_request_headerswith a treatment ofapache_request_headers(). Sometimes, when you usemod_rewrite, you end up with stuff like$_SERVER['HTTP_REDIRECT_ACCEPT_ENCODING']instead of what you're looking for.