PHP卷曲和标题问题

时间:2010-12-22 09:17:52

标签: php http curl content-type httpresponse

我之前曾就此提出过一个问题,但又遇到了问题而无法解决问题。我有一个内部代理服务器和一个内容服务器。代理服务器上的代码是这样的。 (有些评论可能有误,但留下来传达我的理解):

<?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;
}    
?>

问题1:使用当前代码,即使data_server返回的Content-Type是text / plain,客户端看到的内容类型也是text / html。 例如,请参阅http://sarcastic-quotes.com/robots.txt此请求转到上面的文件。我已经检查过数据服务器实际上是将Content-Type作为text / plain返回。但是通过代理,客户端将响应头中的内容类型视为text / html。

问题2:请注意使用变量process_headers_separately。如果我将其设置为1,则浏览器会尝试下载gzip文件而不是显示内容(无论数据服务器返回什么内容类型)。因此,代码流中存在一些逻辑错误。

我只想让上面的代码作为内部代理工作,无缝地充当我的数据服务器和客户端之间的桥梁。任何想法都会受到赞赏,我真的很困惑如何正确处理上面的标题。

的问候, JP


当process_headers_separately = 1(浏览器下载文件而非显示)时,我找到了问题的原因。但它很奇怪,我无法解决它。问题:如果我取消注释行if(isset($_SERVER['REMOTE_ADDR'])) { $_POST["${i_var_prefix}_REMOTE_ADDR"]=$_SERVER['REMOTE_ADDR']; }; 然后事情开始正常工作!奇怪!

像Neil建议的那样,它必须是一些疯狂的空白问题。

无论如何,试图解决这个问题 - 由于这个疯狂的错误,我已经花了3天时间(之前的2个和现在的1个):(。感谢Neil和RF帮我解决这个问题。

2 个答案:

答案 0 :(得分:2)

这一切看起来都很犹太。我能看到的唯一差异是,某些服务器只将标头与\n分开,而不是\r\n。但这可能不是问题。

您可以尝试将var_export(explode("\r\n",$headers),true)写入文件并查看结果吗?

重新解决您的gzip问题,确保在结束?>后没有尾随空格,或者更安全,将echo $result更改为die($result)。显然,如果你没有传递CURL响应的头文件,那么Apache将自己编写,所以你需要CURLOPT_HEADER标志。

CURL会为您解压缩响应吗?如果是这样,您可能需要干预Content-EncodingContent-Length响应标头。

<磷>氮

答案 1 :(得分:2)

您可以使用以下代码行:

//Execute post
$result = curl_exec($curl_handle);
$result_info = curl_getinfo($curl_handle);

然后:

} else {
    if (isset($result_info['content_type'])) {
        header("Content-Type: {$result_info['content_type']}");
    }
    echo $result;
}

基本上,您的代理服务器是返回数据的服务器。所以,这就是你必须设置Content-Type的地方。默认情况下,这将是html。但是,如果您检查CURL响应是否具有特定的Content-Type并设法设置,那么它就可以了! :)

请告诉我们这是否适合您。


我有点理解你现在要做的事情。所以这里是如何在代理的响应中获取标题:

如果您将CURLOPT_HEADER选项设置为1,您将在输出中收到标题,以便您执行此操作:

// Grab the headers from the result
if ($process_headers_separately) {
    list($header_string, $content) = explode("\r\n\r\n", $result, 2);
    // OR :
    // $header_string = substr($result, 0, $result_info['header_size']);
    $headers = http_parse_headers($header_string);
    foreach ($headers as $key => $value) {
        header("$key: $value");
    }
}

我建议使用http_parse_headers函数,因为第一个答案的海报提到的原因。我不确定这是否能解决您的gzipping问题。请告诉我们。