Что делать с лишними заголовок 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 году, но теперь отправляет все обратно клиенту. См.здесь для сведения.