PHP - 奇怪的问题 - 由于看似无关的代码行而损坏的标头/内容

时间:2010-12-22 14:20:15

标签: php curl http-headers httpresponse httpwebresponse

我花了3天时间4个问题试图解决一开始没有问题的问题。但是,实际问题现在让我感到难过。请参阅以下卷曲代码。它正确地获取特定网页并显示。有一条注释行(编号8),它设置了一个额外的POST变量。如果我取消注释,则浏览器会尝试下载gzip文件而不是显示它。我根本不知道那条线与奇怪的行为之间的相关性。

(注意:我使用过w3schools的静态网址,以便其他人可以尝试使用此代码。我正在尝试将此代码用于我自己的内部数据服务器和代理,并且面临完全相同的问题。取消注释该特定行会导致这个奇怪的行为。我需要使用这个变量。我现在不知道解决方法,而且非常好奇找到原因。)

<?php
session_start();

$i_var_prefix="i_var_";

// Other important client 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']; };
// STRANGE PROBLEM:: IF I UNCOMMENT THE LINE ABOVE, THEN THE BROWSER DOES NOT DISPLAY THE CONTENT BUT TRIES TO DOWNLOAD IT.

$curl_url="http://www.w3schools.com/TAGS/form_action.asp";


// Set values of these header variables as got from client
$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, 1);
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $curl_request_headers);


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

//Close connection
curl_close($curl_handle);

list($headers,$content)=explode("\r\n\r\n",$result,2);
foreach (explode("\r\n",$headers) as $hdr) {
   header($hdr);
}
echo $content;
?>

UPDATE:

取消注释该行后,收到的结果标题为:

HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Wed, 22 Dec 2010 14:32:43 GMT
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
Content-Length: 478
Content-Type: text/html
Set-Cookie: ASPSESSIONIDSASCDCDT=KIIKANGALGLDJMLFHGPJBBOM; path=/
Cache-control: private

在注释掉该行后,结果标题为:

HTTP/1.1 200 OK
Date: Wed, 22 Dec 2010 14:34:21 GMT
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
Content-Length: 478
Content-Type: text/html
Set-Cookie: ASPSESSIONIDSASCDCDT=JLPKANGAHDCNADBMNGHGIMCO; path=/
Cache-control: private

1)为什么会有差异?

2)如何正确处理继续的事情?


内容:

原因是使用该行,POST变量的数量增加到1以上,curl开始自动在标题中发送“Expect:”。这使服务器响应“继续”标题,我没有处理。 我正在使用下面发布的解决方案。这些评论,特别是Mchl的评论 - 对于让我走向正确的方向非常有帮助,因为我不知道这条线会如何影响行为。

的问候,

JP

3 个答案:

答案 0 :(得分:1)

通过一些猜测和搜索找到了一个解决方案。来自http://matthom.com/archive/2008/12/29/php-curl-disable-100-continue-expectation。使用cURL-

时,默认情况下,100-continue状态为“预期”

Expect: 100-continue

我使用

禁用了它

$curl_request_headers[]="Expect: ";

现在它有效! (我猜服务器停止发送继续标头)。 (但是,我不相信这对于客户可以[从长远来看]做出的所有类型的请求都是健壮的,但是对于正常目的来说可能没问题。)

答案 1 :(得分:0)

显然取消注释此行会更改$result的{​​{1}}。

您需要检查两个卷曲选项:

curl_exec

[编辑]

快速修复可能是从$ header中删除HTTP 100标头。

答案 2 :(得分:0)

两个建议:

  1. 将违规行更改为if(isset($_SERVER['REMOTE_ADDR'])) _POST['unrelated_variable'] = 42;。如果这没有帮助,那么您可以排除任何与警告相关的问题,将$_POST上的设置值作为唯一可能的罪魁祸首。
  2. 更改您的设计,这样您就不需要对$_POST进行直接写入,其中许多人(包括我自己)认为这是一个非常糟糕的主意。