Les réponses HTTP curl et wget différents résultats

4

Pour vérifier l’en-tête de réponse HTTP pour un ensemble d’URL, j’envoie avec curl les en-têtes de requête suivants

foreach ( $urls as $url )
{
    // Setup headers - I used the same headers from Firefox version 2.0.0.6
    $header[ ] = "Accept: text/xml,application/xml,application/xhtml+xml,";
    $header[ ] = "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    $header[ ] = "Cache-Control: max-age=0";
    $header[ ] = "Connection: keep-alive";
    $header[ ] = "Keep-Alive: 300";
    $header[ ] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $header[ ] = "Accept-Language: en-us,en;q=0.5";
    $header[ ] = "Pragma: "; // browsers keep this blank.

    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_USERAGENT, 'Googlebot/2.1 (+http://www.google.com/bot.html)');
    curl_setopt( $ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt( $ch, CURLOPT_REFERER, 'http://www.google.com');
    curl_setopt( $ch, CURLOPT_HEADER, true );
    curl_setopt( $ch, CURLOPT_NOBODY, true );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
    curl_setopt( $ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
    curl_setopt( $ch, CURLOPT_TIMEOUT, 10 ); //timeout 10 seconds
}

Parfois, je reçois 200 OK, ce qui est bien. Les autres fois 301, 302, 307, ce que j’estime être bon aussi, mais d’autres fois, je reçois un statut étrange comme 406, 500, 504, ce qui devrait identifier une URL invalide, mais lorsque je l’ouvre sur le navigateur, sont bien

par exemple le script retourne

http://www.awe.co.uk/ => HTTP/1.1 406 Not Acceptable

et wget retourne

wget http://www.awe.co.uk/
--2011-06-23 15:26:26--  http://www.awe.co.uk/
Resolving www.awe.co.uk... 77.73.123.140
Connecting to www.awe.co.uk|77.73.123.140|:80... connected.
HTTP request sent, awaiting response... 200 OK

Est-ce que quelqu'un sait quel en-tête de demande me manque ou ajoute en trop?

Fab
la source

Réponses:

5

Vous incluez des en-têtes HTTP non valides dans votre demande:

$header[ ] = "Accept: text/xml,application/xml,application/xhtml+xml,";
$header[ ] = "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";

Sur la première ligne, la liste se termine par un ,type de contenu vide, ce qui est la cause d' erreurs 406 non acceptables . La deuxième ligne n'est même pas un en-tête HTTP.

Si vous regardiez les conversations HTTP de Firefox avec un renifleur de paquet, vous avez probablement déjà vu quelque chose comme:

Accept: text/xml,application/xml,application/xhtml+xml,
    text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

Comme la deuxième ligne commence par un espace, le serveur les traite comme un en-tête unique. Ils doivent également être transmis sous la forme d'un en-tête à curl:

$header[] = "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";

Vous pouvez utiliser http://echo.opera.com pour comparer les demandes envoyées.

Grawity
la source
1

Vous ne fournissez pas d'en- Host:tête dans votre header[]tableau. Dans les requêtes HTTP 1.1 aux serveurs de contenu, les en- Host:têtes sont obligatoires. Les réponses non-4xx sont celles où vous vous êtes heurté au serveur HTTP de contenu d'une personne qui pardonne en ce qui concerne cette erreur de protocole.

JdeBP
la source
Comme l'en-tête est obligatoire, curl l' inclut automatiquement (et si ce n'était pas le cas, la réponse serait 400 Bad requête ).
Grawity
1
Ce n'est pas vrai dans la pratique. Il n’en invente parfois que si on n’en a pas fourni, en fonction de ce qui est passé à d’autres options et à curl_init(), ce qui ne nous a pas été dit. Et, comme il ressort des données de la question, même si personne ne l’a jamais rencontrée dans la pratique, tout le monde n’a pas les bonnes réponses pour le protocole incorrect.
JdeBP
0

À mon humble avis, votre script a l'air correct et, puisque vous obtenez parfois les bons résultats, il devrait fonctionner.

Êtes-vous le propriétaire de http://www.awe.co.uk/?
Peut-être qu’un script en cours d’exécution décide quoi faire en fonction de certains env. Par exemple, dans votre script, vous accédez à ce site en tant qu'agent utilisateur "googlebot" alors que votre agent utilisateur wget sera "wget". Le script sur le serveur Web peut vérifier s'il s'agit de Google et fournit un contenu complètement différent de celui que votre navigateur peut voir. De la même manière, le serveur Web peut envoyer des codes de retour différents.
Pour tester ce problème, vous pouvez réduire votre script ou étendre la wgetcommande pour envoyer la même demande et comparer les résultats.

Une autre chose que je peux imaginer: combien de fois avez-vous exécuté votre script? Peut-être que le serveur web a remarqué l'énorme trafic de votre script et envoie 406 (ou autre) si vous exagérez ;-)

binfale
la source