Page 1 sur 2

Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 16:20
par cage
Bonjour a tous,

Je présume que ce problème a déjà été évoqué dans ce forum, mais je n'arrive pas a trouver un exemple.

Le problème:
Je cherche a récupérer de simple pages HTML sur divers serveurs internet.
Mais pour obtenir les pages, il me faut fournir un header valide pour le serveur dans ma requête HTTP.
Pour l'instant, je m'appuie sur WGET pour arriver a mes fins. (Voir Procedure getURL(page$))

La solution:
J’espère qu'elle viendra d'une âme charitable qui pourra m'aiguiller pour remplacer WGET par un bout de code PB
Je vous en remercie par avance.

Le code qui suit est un code légèrement épuré.
cage

Code : Tout sélectionner

Global host$ = "<nom_du_host>"     ; www.purebasic.com par exemple
Global site$ = "<adresse_du_site>" ; http://www.purebasic.com par exemple
Global page$ = "<nom_de_la_page>"  ; index.php par exemple

Procedure checkURL(link$, code$ = "200 OK")
  If link$ = #Null$
    Debug "no link"
    ProcedureReturn #False
  EndIf
  Protected header$
  Protected result$
  If InitNetwork()
    header$ = GetHTTPHeader(link$)
    result$ = StringField(header$, 1, #LF$)
    If FindString(result$, code$, 1, #PB_String_NoCase)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Procedure getURL(page$)
  Protected retval
  Protected URL$, header$, result$
  ;;;
  Protected Cookie$         = "<cookie>"
  Protected Accept$         = "Accept: text/html, application/xhtml+xml, image/jxr, */*"
  Protected AcceptLanguage$ = "Accept-Language: fr-FR"
  Protected UserAgent$      = "User-Agent: <user_agent>"
  Protected Referer$        = "Referer: " + site$
  Protected Host$           = "Host: " + host$
  Protected param$
  param$ = " --header=" + Chr(34) + Cookie$ + Chr(34)
  param$ + " --header=" + Chr(34) + Accept$ + Chr(34)
  param$ + " --header=" + Chr(34) + AcceptLanguage$ + Chr(34)
  param$ + " --header=" + Chr(34) + UserAgent$ + Chr(34)
  param$ + " --header=" + Chr(34) + Referer$ + Chr(34)
  param$ + " --header=" + Chr(34) + Host$ + Chr(34)
  ;;;
  SetFileAttributes(page$, #PB_FileSystem_Normal)
  DeleteFile(page$, #PB_FileSystem_Force)
  URL$ = site$ + "/" + page$
  If checkURL(URL$)
;;;;La ligne qui suit ne fonctionne pas a cause de l'absence des headers
;;;;retval = ReceiveHTTPFile(URL$, page$, #PB_HTTP_NoRedirect)
    retval = RunProgram("wget.exe", param$ + " " + URL$, AppPath$, #PB_Program_Wait|#PB_Program_Hide)
    If retval
      ProcedureReturn #True
    Else
      DeleteFile(page$, #PB_FileSystem_Force)
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

getURL(page$)

Re: Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 16:29
par djes
Le problème vient de la diversité des serveurs. Avant, j'avais pas mal bossé sur la base de l'atomic web server, mais maintenant je ne m'embête plus et j'utilise la bibliothèque cUrl qui sert d'ailleurs de base à pas mal de codes : http://www.purebasic.fr/english/viewtop ... 12&t=66527

Re: Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 16:50
par falsam
il me faut fournir un header valide pour le serveur dans ma requête HTTP.
le header retourné par GetHTTPHeader() n'est pas bon ?
HTTP/1.1 200 OK
Date: Thu, 09 Feb 2017 15:47:43 GMT
Server: Apache/2.2.22 (Debian)
X-Powered-By: PHP/5.4.45-0+deb7u6
Vary: Accept-Encoding
Content-Type: text/html
Je cherche a récupérer de simple pages HTML sur divers serveurs internet.
Avec

Code : Tout sélectionner

*Buffer = ReceiveHTTPMemory(url$)
tu as le contenu de la page.

Code récapitulatif

Code : Tout sélectionner

InitNetwork()

url$= "http://www.purebasic.com/index.php"
Header$ = GetHTTPHeader(url$)

Debug GetURLPart(url$, #PB_URL_Site)
Debug GetURLPart(url$, #PB_URL_Path)

Debug ""

Repeat
  Index+1
  Line$ = StringField(Header$, Index, #LF$)
  Debug Line$
Until Line$ = ""

Debug ""

*Buffer = ReceiveHTTPMemory(url$)
If *Buffer
  Size = MemorySize(*Buffer)
  Debug "Content: " + PeekS(*Buffer, Size, #PB_UTF8|#PB_ByteLength)
  FreeMemory(*Buffer)
Else
  Debug "Failed"
EndIf

Re: Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 17:18
par case
un header c'est juste des données envoyées au serveur.

pas besoin de commande spécifique tu peux le créer toi même

ce site explique assez bien les protocoles même si il date un peu :)

http://www.iprelax.fr/

Re: Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 17:24
par djes
Dans l'atomic web server (sources avancés), tu as la proc BuildRequestHeader() qui fait le job...

Re: Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 17:32
par cage
Merci a vous deux.
Je suis entrain de regarder libcurl

Sans header dans ma requête HTTP, le serveur me renvoi sur une page d'erreur.
Ceci est fait justement pour éviter les aspirateurs de webs

Il me faut donc fournir dans mon GET (ReceiveHTTPFile()) les éléments suivants:
Cookie:
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: fr-FR
User-Agent:
Referer:
Host:

mais ce n'est pas supporté par ReceiveHTTPFile()
C'est pour cela que j'utilise WGET pour l'instant.
J'utilise Firefox et quand je charge une page, j'ai bien le bon contenu.
En analysant la page, je trouve les informations telles que Cookie:, User-Agent:, Referer: et Host:
Il me suffit de les noter en dur dans mon code PB
En fait, pour clarifier les choses, un ReceiveHTTPFile() d'une page internet ne me donne pas la même chose que si je regarde cette page avec un navigateur quelconque.
C'est bien la le problème.

Re: Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 17:47
par falsam
un ReceiveHTTPFile() d'une page internet ne me donne pas la même chose que si je regarde cette page avec un navigateur quelconque.
et ReceiveHTTPMemory() ?

Re: Requête HTTP avec Headers ???

Publié : jeu. 09/févr./2017 18:10
par cage
C'est pareil avec un ReceiveHTTPMemory()

J'ai récupéré la Lib libcurl.pbi et le code curl_exemple.pb sur GitHub

J'ai regardé comment cela fonctionnait et je l'ai légèrement modifié (curl_exemple.pb)

Et cela fonctionne.
Beaucoup de code pour pas grand chose quand même.
Fred s'est penché sur le Proxy, je pense qu'il devrait se pencher sur la possibilité de jouer sur le Header pour les commandes ReceiveHTTPFile() et ReceiveHTTPMemory()

Voici le code modifié et fonctionnel:

Code : Tout sélectionner

; working with static libcurl
InitNetwork()
IncludeFile "libcurl.pbi"

curl      = curl_easy_init()
url.s     = str2curl("http://une-de-mes-url-qui-pose-probleme/une-page")

header.s  = str2curl("Cookie: récupéré avec Firefox")
header.s  = str2curl("Accept: text/html, application/xhtml+xml, image/jxr, */*")
header.s  = str2curl("Accept-Language: fr-FR")
header.s  = str2curl("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393")
header.s  = str2curl("Referer: récupéré avec Firefox")
header.s  = str2curl("Host: récupéré avec Firefox")

If curl
  curl_easy_setopt(curl,#CURLOPT_URL,@url)
  curl_easy_setopt(curl,#CURLOPT_IPRESOLVE,#CURL_IPRESOLVE_V4)
  curl_easy_setopt(curl,#CURLOPT_TIMEOUT,30)
  *header = curl_slist_append(0,header)
  curl_easy_setopt(curl,#CURLOPT_HTTPHEADER,*header)
  curl_easy_setopt(curl,#CURLOPT_WRITEFUNCTION,@curlWriteData())
  res = curl_easy_perform(curl)
  resData.s = curlGetData()
  curl_easy_getinfo(curl,#CURLINFO_RESPONSE_CODE,@resHTTP)
  Debug "result: " + Str(res)
  If Not res
    Debug "HTTP code: " + Str(resHTTP)
    Debug "HTTP data: " + #CRLF$ + resData
  EndIf
  curl_easy_cleanup(curl)
Else
  Debug "can't init curl!"
EndIf

End
Quelqu'un a peut-être une solution plus simple (moins de code) a proposer.
Je veux bien essayer d'autres codes.

Dans tous les cas, déjà un grand merci pour vos réponses.
cage

Re: Requête HTTP avec Headers ???

Publié : ven. 10/févr./2017 0:30
par cage
Bonsoir,

J'ai modifié mes applications qui le nécessitaient en utilisant la Lib libcurl.pbi
Tout fonctionne a merveille avec des exe qui n'ont grossis que de 2Ko
De plus, la récupération des informations dans les pages est grandement accélérée.
Merci a djes de m'avoir aiguillé vers cette Lib

Par contre, j'ai du mal a en comprendre exactement le fonctionnement.
cage

Re: Requête HTTP avec Headers ???

Publié : ven. 10/févr./2017 13:25
par djes
Je ne suis pas spécialiste, mais disons que ça fait partie de cette panoplie d'outils open source qui font bien leur job, et qui évitent de réinventer la roue. Avec les standards du web, c'est encore mieux..

Re: Requête HTTP avec Headers ???

Publié : lun. 13/févr./2017 20:52
par vurvur
cage a écrit :Bonsoir,

J'ai modifié mes applications qui le nécessitaient en utilisant la Lib libcurl.pbi
Tout fonctionne a merveille avec des exe qui n'ont grossis que de 2Ko
De plus, la récupération des informations dans les pages est grandement accélérée.
Merci a djes de m'avoir aiguillé vers cette Lib

Par contre, j'ai du mal a en comprendre exactement le fonctionnement.
cage
Grossi de 2Ko seulement? Ca me paraît bizarre. Pas besoin de DLL ?

Re: Requête HTTP avec Headers ???

Publié : lun. 13/févr./2017 21:42
par djes
Non, Curl est une .lib, donc les fonctions sont intégrées selon leur utilisation, comme les libs purebasic.

Re: Requête HTTP avec Headers ???

Publié : lun. 13/févr./2017 22:49
par vurvur
djes a écrit :Non, Curl est une .lib, donc les fonctions sont intégrées selon leur utilisation, comme les libs purebasic.
J'ai fait le test, moi ça me rajoute environ 175K d'importer libcurl. A moins que j'aie loupé quelque chose...

Re: Requête HTTP avec Headers ???

Publié : mar. 14/févr./2017 0:06
par cage
Je viens de refaire un test sur un de mes programmes.
Il passe de 577Ko (avec Curl) a 571Ko (sans Curl)

Les 571Ko sont un peu faussés car je désactive du code en plus pour ne pas avoir d'erreur a la compilation.
La taille serait plus proche de 575Ko que de 570

En gros, moins de 5Ko rajoutés.

Re: Requête HTTP avec Headers ???

Publié : mar. 14/févr./2017 9:15
par djes
vurvur a écrit :
djes a écrit :Non, Curl est une .lib, donc les fonctions sont intégrées selon leur utilisation, comme les libs purebasic.
J'ai fait le test, moi ça me rajoute environ 175K d'importer libcurl. A moins que j'aie loupé quelque chose...
Comment ça, tu importes libcurl ?