Что делать с лишними заголовок HTTP с прокси?

наша среда требует использования исходящего прокси-сервера для внешних служб. Обычно это не проблема. В этом случае с Twilio дополнительный возвращаемый заголовок разрывает клиента.

исходящие заголовки:

POST /2010-04-01/Accounts/FOO/SMS/Messages.json HTTP/1.1
Authorization: Basic FOO==
User-Agent: twilio-php/3.10.0
Host: api.twilio.com
Accept: */*
Accept-Charset: utf-8
Content-Type: application/x-www-form-urlencoded
Content-Length: 108

Заголовки Ответа:

HTTP/1.0 200 Connection established

HTTP/1.1 201 Created
Server: nginx
Date: Thu, 06 Jun 2013 14:39:24 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 551
Connection: close
X-Powered-By: PHP/5.3.11

Я могу только предположить, что прокси добавляет дополнительный HTTP-заголовок.

клиент Twilio проверяет наличие:

list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue') 

как я понимаю, есть времена или версии curl, которые автоматически добавит заголовок Expect в запрос, и HTTP 100 будет возвращен в ответе, но в этом случае это не так, и ответ-это соединение 200. Для чего стоит добавить пустой Expect: или Expect: bacon не изменил результаты.

Я бы предпочел не взламывать клиент Twilio слишком много здесь, и я особенно хотел бы избежать просто добавления / / $parts[0] = = 'HTTP / 1.0 200 Connection established' , как кажется, это грязный.

можно ли отправить заголовок запроса в том, что будет подавлять / скрывать дополнительный заголовок? Или, вариант завитка, который я не вижу, чтобы игнорировать его?

исходящим прокси является Linux / Squid

2 ответов


проблема прокси-сервера-это то, с чем сталкиваются многие скрипты. Предпочтительное решение, которое я могу найти в интернете, - это просто добавить следующие строки кода.

<?php
// cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string
if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {
  $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);
}
?>

теперь добавить это к клиенту twilio было бы немного грязно. К счастью, вы можете использовать пространства имен для воссоздания собственных функций. Рассмотрим следующий пример.

<?php
namespace FakeCurl;

//create curl_exec function with same name, but its created in the FakeCurl namespace now.
function curl_exec($ch) {
  //execute the actual curl_exec function in the main namespace
  $response =  \curl_exec($ch);

  // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string
  if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {
    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);
  } 

  return "ADDED TO RESPONSE\r\n\r\n".$response;
}

//make a regular curl request, no alterations.

$curl = curl_init();
curl_setopt_array( $curl, array(
    CURLOPT_HEADER => true,
    CURLOPT_NOBODY => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_URL => 'http://stackoverflow.com' ) );
$response = curl_exec( $curl );
curl_close( $curl );

echo '<pre>'.$response.'</pre>';

?>

выход

ADDED TO RESPONSE

HTTP/1.1 200 OK
Cache-Control: public, max-age=11
Content-Length: 191951
Content-Type: text/html; charset=utf-8
Expires: Wed, 12 Jun 2013 07:09:02 GMT
Last-Modified: Wed, 12 Jun 2013 07:08:02 GMT
Vary: *
X-Frame-Options: SAMEORIGIN
Date: Wed, 12 Jun 2013 07:08:49 GMT

поэтому для использования с клиентом twilio вам нужно поместить в самую верхнюю часть вашего скрипта следующий:

<?php
namespace FakeCurl;
function curl_exec($ch) {
  $response =  \curl_exec($ch);

  // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string
  if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {
    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);
  } 

  return $response;
}

include("twilio.php");
?>

если по какой-то причине параметр пространства имен не работает, я бы добавил простую функцию вне клиента twilio.

<?php
function fixProxyResponse($response) {
  // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string
  if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {
    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);
  } 

  return $response;
}

а затем измените сценарий twilio TinyHttp.php и измените только следующую строку (~linenr 63)

if ($response = curl_exec($curl)) {
  $parts = explode("\r\n\r\n", $response, 3);
  list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue')

to

if ($response = curl_exec($curl)) {
  $parts = explode("\r\n\r\n", fixProxyResponse($response), 3);
  list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue')

некоторые очень поздние разъяснения. При подключении к серверу SSL/TLS через прокси-сервер Прокси-сервер устанавливает туннель, используя HTTP CONNECT. Это покрыто RFC2817 и истек туннелирование spec, а не адресу rfc2616.

исходная спецификация туннелирования требовала, чтобы прокси-сервер вернул клиенту "установленное соединение 200" после успешного подключения к серверу, что вы видите. За этим потенциально следует больше заголовков, и затем пустая строка, прежде чем соединение станет прозрачным, и вы получите фактический ответ от сервера. Итак, вы получаете два набора заголовков. RFC 2817 ослабляет это и позволяет любому ответу 2xx на запрос подключения.

Что означает, короче, что вы не можете полагаться на обнаружение и удаление одной строки заголовка с помощью кода php выше. Может быть более одной строки, и первая строка может не иметь кода 200, и может не включать в себя " соединение установленная ' строка. Вы должны быть готовы обнаружить два полных набора заголовков.

cURL удалил первоначальный ответ connect до 7.11.1 в 2004 году, но теперь отправляет все обратно клиенту. См.здесь для сведения.