2010-10-25 4 views
13

Je suis en train d'écrire un proxy PHP spécialisé et je suis tombé sur une fonctionnalité de cURL.cURL et redirections - renvoyer plusieurs en-têtes?

Si les valeurs suivantes sont définies:

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

CURL gère correctement réoriente, mais renvoie toutes les têtes de page, et pas seulement la dernière page (sans redirection), par exemple

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 

Notez que CURLOPT_HEADER est réglé parce que je dois lire et copier des parties de l'en-tête d'origine dans mon tête proxy.

Je comprends pourquoi il retourne tous ces en-têtes (par exemple, mon code proxy doit détecter tous les cookies placés dans l'en-tête 302 et les transmettre). TOUTEFOIS, cela rend également impossible de détecter quand les en-têtes se terminent et que le contenu commence. Normalement, avec un en-tête, nous pourrions faire un simple division:

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

Mais que de toute évidence ne fonctionnera pas ici. Hm. Nous pourrions essayer quelque chose qui sépare seulement si elle ressemble à la ligne suivante fait partie d'un en-tête:

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

qui fonctionnera presque tout le temps, mais selfs si quelqu'un a ce qui suit dans leur page:

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

HTTP/1.1 200 OK 

BALLES!

Nous voulons vraiment la scission arrêt correspondant dès qu'il rencontre une forme de \r\n\r\n qui ne sont pas immédiatement suivie HTML/1.x - est-il un moyen de le faire avec PHP regexs? Même cette solution peut s'étouffer sur la situation (assez rare) où quelqu'un met un en-tête HTTP directement au début de leur contenu. Y a-t-il un moyen dans cURL d'obtenir toutes les pages retournées sous forme de tableau?

Répondre

15

Vous pouvez obtenir les informations de la taille d'en-tête totale, et diviser la chaîne comme ceci:

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

Information tirée de the helpful post by "grandpa".

+0

Fonctionne très bien, merci – Ender

+0

bonne suggestion, je me demandais à ce sujet et je viens de vérifier les prochains en-têtes chaque fois que je reçois un statut http connu qui n'est probablement pas la dernière. – Evert

+2

$ body = substr ($ buffer, $ header_size + 1) => Ceci supprimera le premier caractère du corps. substr ($ buffer, $ header_size) est correct –

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

utilisation curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

TRUE pour suivre toute « Location: » que le serveur envoie de l'en-tête HTTP (notez cette fonction est récursive, PHP suivra « Location: » têtes que est envoyé, sauf si CURLOPT_MAXREDIRS est défini).

+0

Désolé, je voulais juste mentionner l'importance –

0

besoin d'ajouter, à friser configurations:

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

Il est sera de résoudre le problème.