2010-10-25 2 views
13

Я пишу специализированный прокси-сервер PHP и получил тупик от функции cURL.cURL и перенаправления - возврат нескольких заголовков?

Если устанавливаются следующие значения:

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 

Curl корректно обрабатывает редиректы, но возвращает все заголовки страниц, а не только конечный (не редирект) страницы, например

HTTP/1.1 302 Found 
Location: http://otherpage 
Set-Cookie: someCookie=foo 
Content-Length: 198 

HTTP/1.1 200 OK 
Content-Type: text/html; charset=utf-8 
Content-Length: 3241 

<!DOCTYPE HTML> 
...rest of content 

Обратите внимание, что CURLOPT_HEADER установлен потому, что мне нужно прочитать и скопировать часть исходного заголовка в мой заголовок прокси.

Я понимаю, почему он возвращает все эти заголовки (например, мой прокси-код должен обнаруживать любые файлы cookie, установленные в заголовке 302 и передавать их). ОДНАКО, это также делает невозможным обнаружение, когда заголовки заканчиваются и начинается контент. Как правило, с одним заголовком мы могли бы просто сделать простой сплит:

$split = preg_split('/\r\n\r\n/', $fullPage, 2) 

Но это явно не сработает. Гектометр Мы могли бы попробовать что-то, что только расщепляется, если она выглядит как следующая строка является частью заголовка:

$split = preg_split('/\r\n\r\nHTML\/(1\.0|1\.1) \\d+ \\w+/', $fullPage) 
// matches patterns such a "\r\n\r\nHTML/1.1 302 Found" 

Который будет работать почти все время, но дроссели, если кто-то имеет следующее в своей странице:

...and for all you readers out there, here is an example HTTP header: 
<PRE> 

HTTP/1.1 200 OK 

ШАРЫ!

Мы действительно хотим разделить на остановки сопоставления, как только он сталкивается с какой-либо образец \r\n\r\n, не сразу после HTML/1.x - есть способ сделать это с помощью PHP RegExs? Даже это решение может захлебываться (довольно редкой) ситуацией, когда кто-то помещает HTTP-заголовок прямо в начале своего контента. Есть ли способ в cURL получить все возвращенные страницы в виде массива?

ответ

15

Вы можете получить информацию от общего размера заголовка, и разделить строку вверх, как это:

$buffer = curl_exec($ch); 
$curl_info = curl_getinfo($ch); 
curl_close($ch); 
$header_size = $curl_info["header_size"]; 
$header = substr($buffer, 0, $header_size); 
$body = substr($buffer, $header_size) 

Информация взята из the helpful post by "grandpa".

+0

Работает отлично, спасибо – Ender

+0

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

+2

$ body = substr ($ buffer, $ header_size + 1) => Это удалит первый символ тела. substr ($ buffer, $ header_size) верен –

0
$header_size = $curl_info["header_size"]; 
$header = substr($buffer, 0, $header_size-1); 
$body = substr($buffer, $header_size); 
0

использование curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

ИСТИНА следовать любому «Location:» заголовок, который сервер отправляет как часть заголовка HTTP (обратите внимание, что это рекурсивное, PHP будет следовать, как много «Location:» заголовкам, которые его отправляется, если не установлен CURLOPT_MAXREDIRS).

+0

Извините, я просто хотел упомянуть о важности –

0

Нужно добавить, свернуться конфигурации:

curl_setopt($ch, CURLOPT_HTTPHEADER, array("Expect:")); 

Это будет решить эту проблему.

Смежные вопросы