2010-10-25 8 views
13

Escribo un proxy PHP especializado y me queda perplejo una característica de cURL.cURL y redirige - devolviendo múltiples encabezados?

Si se establecen los siguientes valores:

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

Curl usa bien redirecciones, pero devuelve todos los encabezados de página, no sólo el (no redirección) página final, por ejemplo

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 

Tenga en cuenta que CURLOPT_HEADER se establece porque necesito leer y copiar partes de la cabecera original en el encabezado de mi proxy.

Aprecio por qué devuelve todos estos encabezados (por ejemplo, mi código proxy debe detectar las cookies establecidas en el encabezado 302 y pasarlas). SIN EMBARGO, también hace que sea imposible detectar cuándo terminan los encabezados y comienza el contenido. Normalmente, con un encabezado podríamos simplemente hacer una división simple:

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

Pero eso obviamente no funcionará aquí. Hm. Podríamos intentar algo que sólo se divide si se ve como la siguiente línea es parte de una cabecera:

$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" 

que funcionará casi todo el tiempo, pero se ahoga si alguien tiene lo siguiente en su página:

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

HTTP/1.1 200 OK 

BALLS!

Realmente quieren la división de parada a juego tan pronto como se encuentra con cualquier patrón de \r\n\r\n que no vaya seguida inmediatamente por HTML/1.x - ¿hay una manera de hacer esto con PHP regexs? Incluso esta solución puede ahogarse en la situación (bastante rara) en la que alguien coloca un encabezado HTTP justo al comienzo de su contenido. ¿Hay alguna manera en cURL para obtener todas las páginas devueltas como una matriz?

Respuesta

15

, usted puede obtener la información del tamaño total de la cabecera, y dividir la cadena de esta manera:

$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) 

Información tomada de the helpful post by "grandpa".

+0

Funciona muy bien, gracias – Ender

+0

gran sugerencia, me he estado preguntando sobre esto y acabo de comprobar los siguientes encabezados cada vez que obtengo un estado http conocido que probablemente no sea el último. – Evert

+2

$ body = substr ($ buffer, $ header_size + 1) => Esto eliminará el primer carácter del cuerpo. substr ($ buffer, $ header_size) es correcto –

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

uso curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

TRUE para seguir cualquier "Ubicación:" encabezado que el servidor envía como parte de la cabecera HTTP (tenga en cuenta que esto es recursivo, PHP seguirá tantos "Ubicación:" cabeceras que se se envía, a menos que se establezca CURLOPT_MAXREDIRS).

+0

Lo siento, solo quería mencionar la importancia –

0

necesidad de añadir, para rizar configuraciones:

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

Es será resolver el problema.

Cuestiones relacionadas