PHP - странная проблема - поврежденные заголовки / контент из-за, казалось бы, не связанной строки кода - PullRequest
1 голос
/ 22 декабря 2010

Я потратил 3 дня и 4 SO вопроса, пытаясь исправить то, что не было проблемы в первую очередь.Однако актуальная проблема сейчас поставила меня в тупик.Пожалуйста, смотрите следующий код curl.Он правильно выбирает определенную веб-страницу и отображает.Есть закомментированная строка (№ 8), которая устанавливает дополнительную переменную POST.Если я раскомментирую его, браузер попытается загрузить файл gzip вместо его отображения.Я вообще не знаю корреляции между этой строкой и странным поведением.

(Примечание: я использовал статический URL из 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;
?>

ОБНОВЛЕНИЕ:

Если строка не закомментирована, получаются заголовки результата:

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:» в заголовок.Это заставило сервер ответить заголовком «Продолжить», который я не обрабатывал.Я использую решение, опубликованное ниже.Комментарии, особенно комментарии Мчла, были очень полезны для того, чтобы направить меня в правильном направлении, поскольку я понятия не имел, как эта строка может повлиять на поведение.

в отношении

JP

Ответы [ 3 ]

1 голос
/ 22 декабря 2010

Нашел одно решение путем догадок и поиска. С http://matthom.com/archive/2008/12/29/php-curl-disable-100-continue-expectation. Состояние 100-продолжение по умолчанию «ожидается» при использовании cURL-

Expect: 100-continue.

Я отключил его, используя

$curl_request_headers[]="Expect: ";.

И теперь это работает! (Я думаю, сервер перестает отправлять заголовок продолжения). (Однако я не уверен, что это надежно для всех типов запросов, которые клиент может сделать [в долгосрочной перспективе], но может быть нормальным для обычных целей).

0 голосов
/ 22 декабря 2010

Два предложения:

  1. Измените строку с ошибкой на if(isset($_SERVER['REMOTE_ADDR'])) _POST['unrelated_variable'] = 42;.Если это не помогает, то вы можете исключить любые проблемы, связанные с предупреждением, оставив значения параметров на $_POST как единственно возможный виновник.
  2. Измените свой дизайн, чтобы вам не нужно было выполнять прямые записи на$_POST, что многие, включая меня, считают очень плохой идеей.
0 голосов
/ 22 декабря 2010

Очевидно, что раскомментирование этой строки приводит к изменению $result, которое вы получаете от curl_exec.

. У вас есть два варианта скручивания, которые необходимо изучить:

curl_setopt($curl_handle, CURLOPT_POST, count($_POST));
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $_POST);

[править]

Быстрое исправление может заключаться в удалении заголовка HTTP 100 из $ headers.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...