9
votes

Comment obtenir des en-têtes HTTP avant de télécharger avec Openuri de Ruby

J'utilise actuellement Openuri pour télécharger un fichier à Ruby. Malheureusement, il semble impossible d'obtenir les en-têtes HTTP sans télécharger le fichier complet: xxx

exécutant le code ci-dessus montre qu'il télécharge d'abord le fichier complet et imprime uniquement l'en-tête dont j'ai besoin.

Y a-t-il un moyen d'obtenir les en-têtes avant que le fichier complet ne soit téléchargé, afin que je puisse annuler le téléchargement si les en-têtes ne sont pas ce que je m'attends à ce que ce soit?


3 commentaires

dupliquer? Stackoverflow.com/Questtions/13916046/...


@Kira Non, en utilisant la réponse liée, téléchargera d'abord le fichier complet, exactement ce que je fais pas voulu.


Ouvert ne charge pas toute la réponse en mémoire. En fait, cela le fait, mais uniquement pour les réponses plus petites ou égales à 10240 octets. Les réponses plus importantes vont être diffusées en continu à un Tempfile . Vous pouvez utiliser cette connaissance, pour accéder au Tempfile et faire des choses maigres avec elle. Rien ne se passe en mémoire, à moins que vous ne le souhaitiez. Voir ma réponse ici: Stackoverflow.com/questions/2263540/... Mais si vous voulez seulement accéder aux en-têtes, vous ne devez pas utiliser Ouvrir , car il va toujours lire la réponse. Les réponses ci-dessous sont bonnes.


3 Réponses :


11
votes

Vous pouvez utiliser net :: http pour cette affaire, par exemple:

require 'net/http'

http = Net::HTTP.start('www.planetpdf.com')

resp = http.head('/codecuts/pdfs/ooc.pdf')
resp.each { |k, v| puts "#{k}: #{v}" }
http.finish


7 commentaires

Il est plus propre d'utiliser la forme de bloc de Démarrer . Voir l'exemple dans la documentation .


Il existe de nombreuses bonnes raisons d'utiliser la forme de bloc, y compris la fermeture automatique de la logique, sinon la connexion, lorsque le bloc se termine. La prérogative de son programmeur de faire ce qu'ils veulent, mais il devrait y avoir des raisons saines. L'indentation passe au profit de la forme profonde ou la forme de blocage de ne pas être monté comme un besoin de refracteur.


Merci, mais ce n'était pas vraiment ce que je voulais archier (voir ma réponse). Il a beaucoup aidé de toute façon à trouver ce que je cherchais, merci.


@Epirat Bien en fait, si vous ne voulez pas télécharger le fichier et que vous souhaitez simplement recueillir des informations sur le fichier, une demande de tête est en effet ce que vous voulez. de rfc2616 sec. 9.4 Cette méthode (tête) peut être utilisée pour obtenir de la métainformation sur l'entité impliquée par la demande sans transférer l'entité-corps lui-même. Cette méthode est souvent utilisée pour tester les liens hypertextes pour la validité, l'accessibilité et la modification récente. Visitez w3.org/protocols/rfc2616/rfc2616-sec9.html


@kira belle explication. J'ai toujours des difficultés à comprendre le http lib .. Voulez-vous m'aider à cela?


@Kira Pouvez-vous me déposer un email, à mon identifiant de messagerie, de sorte que si j'ai un problème, je peux déclencher un email à vous..Veuillez :-) Mon email est sur mon profil "À propos de moi". J'ai juste besoin d'une aide sur donc http / https lib.


Dans le dernier exemple Open-UriR télécharge toujours le fichier entier. On peut le voir en utilisant progres_proc param.



5
votes

Il semble que je voulais que je voulais, il ne soit pas possible d'archier l'utilisation de Openuri, au moins pas, comme je l'ai dit, sans charger l'ensemble du fichier en premier.

J'ai pu faire ce que je voulais utiliser l'utilisation de Net :: HTTP demande_get

ici un exemple: xxx

Notez que cela ne fonctionne que lors de l'utilisation d'un bloc, le fais comme: < Pré> xxx

Le corps sera déjà lu.


1 commentaires

Correct, Openuri pré-lit le contenu puis renvoie une poignée de fichier, que vous utilisiez le formulaire de bloc ou non.



3
votes

Plutôt que d'utiliser net :: http, qui peut être comme creuser une piscine sur la plage à l'aide d'une pelle de sable, vous pouvez utiliser un certain nombre de clients HTTP pour RUBY et nettoyer le code.

Voici un échantillon en utilisant httparty : xxx < P> À ce stade, il est facile de vérifier la taille du document: xxx

Malheureusement, le HTTPD que vous parlez peut ne pas savoir à quel point le contenu sera grand; Afin de réagir rapidement aux serveurs, ne calculez pas nécessairement la taille de la production générée dynamiquement, ce qui prendrait presque aussi longtemps et être presque aussi important que de la CPU qui l'envoie, de sorte que la valeur de la "longueur de contenu" pourrait être buggy. < / p>

Le problème avec net :: http est-ce qu'il ne traitera pas automatiquement les redirections, alors vous devez donc ajouter du code supplémentaire. Constituée, ce code est fourni dans la documentation, mais le code continue de croître à mesure que vous devez faire plus de choses, jusqu'à ce que vous ayez fini par écrire un autre client HTTP (YAHC). Donc, évitez cela et utilisez une roue existante.


3 commentaires

Si je comprends le code correctement, cela fait en réalité une demande de tête, ce qui n'est pas ce que je voulais, dans ce cas particulier. Même si ce serait probablement un bon moyen de résoudre ce problème, je devais utiliser une demande d'obtention dans ce cas.


Un get essaiera toujours de récupérer tout le fichier. Il est possible d'entrer dans le traitement et d'abandonner la connexion, mais cela n'est pas un bon citoyen de réseau. Considérez ce qui se passe: vous émettez un get et le serveur charge le fichier pour commencer à l'envoyer. Vous abandonnez et vous venez de perdre une charge supplémentaire sur le serveur et le réseau intermédiaire et votre hôte. C'est pourquoi la tête a été inventée pour éviter de le faire.


Comme je l'ai dit, je suis conscient de cela, mais dans la tête de cas spécifique ne fonctionnait pas, alors obtenez-vous était la seule option. Et je voulais éviter de télécharger le fichier complet juste pour le jeter, alors je pensais être capable d'abandonner le plus tôt possible, pas après le téléchargement de l'ensemble du dossier, serait une bonne chose.