pourquoi curl and wget aurait-il pour résultat une 403 interdite?

57

J'essaie de télécharger un fichier avec wgetet curlet il est rejeté avec une erreur 403 (interdite).

Je peux voir le fichier en utilisant le navigateur Web sur le même ordinateur.

Je réessaie avec l'agent utilisateur de mon navigateur, obtenu par http://www.whatsmyuseragent.com . Je fais ça:

wget -U 'Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' http://...

et

curl -A 'Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0' http://...

mais c'est toujours interdit. Quelles autres raisons pourrait-il y avoir pour la 403, et de quelle manière puis-je modifier les commandes wgetet curlpour les surmonter?

(Il ne s'agit pas d'obtenir le fichier. Je sais que je peux simplement l'enregistrer depuis mon navigateur. Il s'agit de comprendre pourquoi les outils de ligne de commande fonctionnent différemment.)

mise à jour

Merci à toutes les excellentes réponses apportées à cette question. Le problème spécifique que j'avais rencontré était que le serveur vérifiait le référant. En ajoutant ceci à la ligne de commande, je pourrais obtenir le fichier en utilisant curlet wget.

Le serveur qui a vérifié le référent a rebondi via un serveur 302 vers un autre emplacement qui n'a effectué aucune vérification. Un curlou wgetde ce site a donc fonctionné proprement.

Si quelqu'un est intéressé, c'est parce que je lisais cette page pour en savoir plus sur le CSS intégré et que j'essayais de regarder le fichier CSS du site pour un exemple. L'URL réelle avec laquelle j'avais des problèmes était celle-ci et curlj'ai fini par

curl -L -H 'Referer: http://css-tricks.com/forums/topic/font-face-in-base64-is-cross-browser-compatible/' http://cloud.typography.com/610186/691184/css/fonts.css

et le wget est

 wget --referer='http://css-tricks.com/forums/topic/font-face-in-base64-is-cross-browser-compatible/' http://cloud.typography.com/610186/691184/css/fonts.css

Très intéressant.

starfry
la source
7
Les pages qui vérifient le référent sont vraiment énervantes. L'en-tête est supposé être facultatif et utilisé pour la collecte de statistiques.
mardi
La chose la plus simple que j'ai trouvée est de le convertir en fichier zip et de l'utiliser de cette façon.
piniyini

Réponses:

40

Une requête HTTP peut contenir plusieurs en-têtes qui ne sont pas définis par curl ou wget. Par exemple:

  • Cookie: c'est la raison la plus probable pour laquelle une demande serait rejetée, j'ai vu cela se produire sur des sites de téléchargement. Avec un cookie key=val, vous pouvez le définir avec l' option -b key=val(ou --cookie key=val) pour curl.
  • Référent (sic): lorsque vous cliquez sur un lien sur une page Web, la plupart des navigateurs ont tendance à envoyer la page actuelle en tant que référent. On ne devrait pas s'y fier, mais même eBay n'a pas réussi à réinitialiser un mot de passe lorsque cet en-tête était absent. Alors oui, cela peut arriver. L' curloption pour cela est -e URLet --referer URL.
  • Autorisation: cela devient de moins en moins populaire en raison de l'interface utilisateur incontrôlable de la boîte de dialogue nom d'utilisateur / mot de passe, mais cela reste possible. Il peut être activé curlavec l' option -u user:password(ou --user user:password).
  • User-Agent: certaines requêtes donneront des réponses différentes selon l'agent d'utilisateur. Cela peut être utilisé de manière appropriée (fournir le téléchargement réel plutôt que de dresser une liste de miroirs) ou incorrectement (rejeter les agents utilisateurs qui ne commencent pas Mozilla, ne contiennent pas Wgetou curl).

Vous pouvez normalement utiliser les outils de développement de votre navigateur (supporté par Firefox et Chrome) pour lire les en-têtes envoyés par votre navigateur. Si la connexion n'est pas chiffrée (c'est-à-dire si vous n'utilisez pas HTTPS), vous pouvez également utiliser un renifleur de paquet tel que Wireshark à cette fin.

Outre ces en-têtes, les sites Web peuvent également déclencher des actions en coulisse qui changent d'état. Par exemple, lors de l'ouverture d'une page, il est possible qu'une requête soit effectuée sur l'arrière-plan pour préparer le lien de téléchargement. Ou une redirection se produit sur la page. Ces actions utilisent généralement Javascript, mais il peut aussi y avoir un cadre caché pour faciliter ces actions.

Si vous êtes à la recherche d'une méthode pour récupérer facilement des fichiers à partir d' un site de téléchargement, jetez un oeil à engrais vert, inclus avec socs .

Lekensteyn
la source
Une autre possibilité vraiment perverse serait que le serveur, pour une raison quelconque, soit configuré pour renvoyer 403 au lieu de 200 en cas de succès.
Kasperd
1
Cela m'a donné l'indice dont j'avais besoin. Après avoir essayé les cookies, j'ai trouvé que le problème était
dû au parrain
2
Si elle est encore échoué à wgetessayer d' ajouter --auth-no-challenge. Fonctionne comme par magie.
Jonathan
13

Je souhaite simplement ajouter aux réponses ci-dessus que vous pouvez utiliser la fonctionnalité "Copier comme cURL" présente dans les outils de développement de Chrome (depuis la version 26.0) et dans Firebug (depuis la version 1.1 ). Vous pouvez accéder à cette fonctionnalité en cliquant avec le bouton droit de la souris sur la ligne de demande dans l'onglet Réseau.

solde9
la source
Cela a énormément aidé, en particulier les outils de Chrome. Lorsque j'ai essayé Firefox, l'en-tête de la demande après le 302 était tout ce que je pouvais voir. En chrome, je pouvais voir les deux et cela me donnait l'info pour résoudre le problème.
starfry
1
@starfry Vous devez cocher Enable persistent logsl'onglet des paramètres des outils de développement de Firefox pour l'empêcher d'effacer les journaux du réseau lors d'une redirection. Chrome a une option similaire. Incidemment, "Copier en tant que cURL" est dans Firefox Nightly / Aurora / Beta depuis un moment maintenant, et doit être prochainement publié (31.0).
Bob le
9

J'ai essayé tout ce qui précède mais pas de chance; outil de navigateur dev utilisé pour obtenir la chaîne d'agent utilisateur, une fois que j'ai ajouté ce qui suit, succès:

--user-agent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
utilisateur3707737
la source
5

Selon ce que vous demandez, il pourrait s'agir d'un cookie. Avec Firefox, vous pouvez faire un clic droit lorsque vous êtes sur la page en question, "Afficher les informations de la page". Choisissez l'icône "Sécurité", puis cliquez sur le bouton "Afficher les cookies".

Pour dérouter les cookies, le plug-in Firefox "Live HTTP Headers" est essentiel. Vous pouvez voir quels cookies sont configurés et quels cookies sont renvoyés au serveur Web.

wgetpeut fonctionner avec des cookies, mais c’est totalement exaspérant, car cela ne laisse pas présumer qu’il n’a pas envoyé de cookies. Votre meilleur choix est de supprimer tous les cookies associés de votre navigateur et de suivre la séquence de connexion initiale ou de visualisation de la page requise. Consultez "En-têtes HTTP en direct" pour les cookies et pour tous les paramètres POST ou GET. Effectuez la première étape de connexion en wgetutilisant les options "--keep-session-cookies" et "--save-cookies". Cela vous donnera un fichier cookie que vous pourrez consulter avec un éditeur de texte. Utilisez wget --load-cookiesavec le fichier de cookie pour les prochaines étapes.

Bruce Ediger
la source
1
J'ai testé sans cookies dans Firefox en ouvrant une fenêtre de navigation privée et, comme prévu, j'ai eu l'erreur 403. Intéressant que vous n'obtenez pas l'erreur dans un nouvel onglet. En chrome, un nouvel onglet renvoie le 403.
starfry
1
Incidemment, vous pouvez utiliser l'onglet Réseau des outils de développement de Firefox pour inspecter les cookies envoyés et reçus sans aucun ajout. Idem pour Chrome / Chrome.
Bob le
@bob - oui j'ai trouvé ça. Cela m'a pris quelques minutes car ce n'était pas quelque chose. Firebug a maintenant Copy en tant que CURL, mais il serait bien de voir les outils natifs aussi.
starfry
1

Cela peut également se produire si le site requiert SSL. Votre navigateur transmettra automatiquement de HTTP à HTTPS, mais curl et wget ne le feront pas. Alors essayez la demande avec HTTPS au lieu de HTTP.

Richard
la source
3
Cela aboutirait à l'erreur 301 ou 302, Redirect, si j'ai raison.
Jakuje