Les instructions httpRequête et httpRécupereRésultat servent à récupérer un résultat en interrogeant une adresse URL. Pour avoir la jauge, l’utilisation de HTTPJauge est nécessaire mais est bizarrement indépendante au lieu d’être un CallBack. De même, il n’est pas possible de limiter le débit de téléchargement. Le code ci-dessous le permet et pilote la jauge directement et la vitesse.
Attention, ce code n’est pas prévu pour fonctionner sur des URL en https.
PROCEDURE TéléchargeHTTP(bContenu est un booléen,sFichierHTTP est une chaîne,sFichierDestination est une chaîne,bAvecJauge est un booléen,sPréfixeJauge est une chaîne,nTimeOut est un entier,nPort est un entier,sUser est une chaîne,sPass est une chaîne,sNomDuThread est une chaîne,LOCAL sProxy est une chaîne)
//bContenu : permet de télécharger le contenu du fichier (vrai) ou seulement l'entête (faux)
//sFichierHTTP : adresse HTTP du fichier sans http:// devant (ex : www.apple.com/fraise.png)
//sFichierDestination : chemin du fichier à créer (en local)
//bAvecJauge : affiche la progression dans la barre de message de la fenêtre appellante (à modifier si on veut faire pointer vers une autre jauge)
//sPréfixeJauge : texte à afficher avant le pourcentage (le tout s'affichera à droite de la jauge dans la barre de message de la fenêtre appelante)
//nTimeOut : durée du timeout (voir doc de la fonction SocketConnecte)
//nPort : port sur lequel faire la connexion HTTP (habituellement le 80)
//sUser : Nom d'utilisateur pour avoir accès en HTTP au fichier sFichierHTTP (voir fichier .htaccess du site)
//sPass : Mot de passe relié à l'utilisateur sUser
//sNomDuThread : nom du thread ayant appelé cette fonction (afin que cette fonction télécharge en tâche de fond)
//sProxy : adresse du proxy intermédiaire (UserProxy:PassProxy@AdresseProxy:PortProxy)
//gbAnnule : variable globale booléenne qui indique que le téléchargement doit être arrêté prématurément (vrai), sinon laisser à faux
//gsErreurHTTP : variable globale chaine qui récupère le message d'erreur
//gsAgentHTTP : variable globale chaine contenant l'agent HTTP (voir fonction HTTPRequête / agent utilisateur)
ThreadEnvoieSignal(sNomDuThread)
sMsg,sReq est une chaîne
sNomSocketHTTP est une chaine = "MonSocketHTTP"
sReqDirect est une chaîne = [
GET %1 HTTP/1.1
Host: %2
User-Agent: %3
Connection: keep-alive
]
sReqProxy est une chaîne = [
GET %1 HTTP/1.1
Host: %2
User-Agent: %3
Proxy-Connection: keep-alive
Cache-Control: max-age=0
Proxy-Authorization: Basic %4
]
nJaugeMax,f,nRecu,nSeconde,nRecuParSeconde,nCentieme,nDurée est un entier
sLigne,sEntête,sJauge,hDiff,sErr,sDomaine,sAcces est une chaîne
dhHCur,dhHInit sont des DateHeures
duDurée1 est une Durée
rDébit est un réel
QUAND EXCEPTION DANS
sDomaine=ExtraitChaîne(sFichierHTTP,1,"/")
SI sProxy>"" _ET_ Position(sProxy,"@")>0 ALORS
sAcces = Crypte(ExtraitChaîne(sProxy,1,"@"),"",crypteAnsi,encodeBASE64)
sProxy = ExtraitChaîne(sProxy,2,"@")
FIN
SI SocketConnecte(sNomSocketHTTP,(sProxy>"" ? Val(ExtraitChaîne(sProxy,2,":")) SINON nPort),(sProxy>"" ?ExtraitChaîne(sProxy,1,":") SINON sDomaine),nTimeOut)=Faux ALORS
gsErreurHTTP="Erreur de connexion : "+ErreurInfo(errMessage)
SINON
SocketChangeModeTransmission(sNomSocketHTTP,SocketSansMarqueurFin)
//gestion du proxy
SI sProxy>"" ALORS
sReq=ChaîneConstruit(sReqProxy,"http://"+sFichierHTTP,sDomaine,gsAgentHTTP,sAcces)
SINON
sReq=ChaîneConstruit(sReqDirect,Milieu(sFichierHTTP,Taille(sDomaine)+1),sDomaine,gsAgentHTTP)
FIN
//gestion de l'authentification au serveur lui-même
SI sUser>"" ALORS sReq+=RC+"Authorization: Basic "+Crypte(sUser+":"+sPass,"",crypteAnsi,encodeBASE64)
sReq+=RC+RC
SI SocketEcrit(sNomSocketHTTP,sReq) ALORS
nRecu=0;nRecuParSeconde=0
//mémorise la date et heure pour afficher une jauge chaque seconde
dhHInit=DateSys()+HeureSys();nSeconde=Val(Milieu(dhHInit,13,2));nCentieme=Val(Milieu(dhHInit,15,2))
TANTQUE SocketExiste(sNomSocketHTTP)=Vrai
sMsg = SocketLit(sNomSocketHTTP,Vrai)
SI PAS sMsg = "" ALORS
SI nRecu=0 ALORS
sEntête=ExtraitChaîne(sMsg,1,RC+RC);sMsg=ExtraitChaîne(sMsg,2,RC+RC)
SI PAS (ExtraitChaîne(sEntête,1,RC)="HTTP/1.1 200 OK" OU ExtraitChaîne(sEntête,1,RC)="HTTP/1.0 200 OK") ALORS
gsErreurHTTP="Erreur donnée par le serveur HTTP ("+Milieu(ExtraitChaîne(sEntête,1,RC),10)+")"
SORTIR
FIN
SI PAS bContenu ALORS
gsErreurHTTP=sEntête
SORTIR
FIN
//trouve la taille du fichier à télécharger pour initialiser la jauge
POUR TOUTE CHAINE sLigne DE sEntête SEPAREE PAR RC
SI Gauche(sLigne,15)="Content-Length:" ALORS nJaugeMax=Val(ExtraitChaîne(sLigne,2,":"))
FIN
fSupprime(sFichierDestination);f=fCrée(sFichierDestination)
SI f=-1 ALORS
gsErreurHTTP="Impossible créer le fichier de destination : "+ErreurInfo(errMessage)
SORTIR
FIN
SINON
SI gbAnnule ALORS SORTIR
FIN
SI PAS f=-1 ALORS
nRecu+=Taille(sMsg)
fEcrit(f,sMsg)
dhHCur=DateSys()+HeureSys();nRecuParSeconde+=Taille(sMsg)
SI bAvecJauge _ET_ PAS nSeconde=Val(Milieu(dhHCur,13,2)) ALORS
sJauge=NumériqueVersChaîne(Arrondi(nRecu/nJaugeMax*100,1),"3.1fs")+"%" // reçu à "+TailleVersChaîne(nRecuParSeconde)+"/s"
Jauge(nRecu,nJaugeMax,sPréfixeJauge+[" "]+sJauge)
nRecuParSeconde=0
dhHCur=DateSys()+HeureSys();nSeconde=Val(Milieu(dhHCur,13,2));nCentieme=Val(Milieu(dhHCur,15,2))
FIN
SI nRecu=nJaugeMax ALORS
hDiff=DateHeureDifférence(dhHInit,dhHCur)
SI bAvecJauge ALORS
duDurée1 = ChaîneVersDurée(hDiff,duréeCentième)
nDurée=duDurée..Jour*86400+duDurée..Heure*3600+duDurée..Minute*60+duDurée..Seconde
rDébit=Arrondi(nJaugeMax/nDurée,2)
Jauge(nRecu,nJaugeMax,sPréfixeJauge+[" "]+"100,0%") // reçu à "+TailleVersChaîne(rDébit)+"/s en moyenne")
FIN
fFerme(f);SORTIR
FIN
FIN
SINON
SORTIR
FIN
FIN
SI f<>-1 ALORS fFerme(f)
SI bContenu ALORS
SI (fFichierExiste(sFichierDestination) _ET_ fTaille(sFichierDestination)=nJaugeMax) ALORS
gsErreurHTTP=""
SINON SI gsErreurHTTP ALORS
gsErreurHTTP="Fichier vide ou incomplet."
FIN
FIN
SINON
gsErreurHTTP="Erreur durant le téléchargement HTTP : "+ErreurInfo(errMessage)
FIN
SocketFerme(sNomSocketHTTP)
FIN
FAIRE
SocketFerme(sNomSocketHTTP)
gsErreurHTTP="Erreur durant le téléchargement HTTP : "+ExceptionInfo(errMessage)
FINPour faire tourner le téléchargement en tâche de fond, il est conseillé (en tout cas la procédure est construite ainsi) de l’appeler dans un thread à part :
PROCEDURE sTéléchargeHTTP(sFichierHTTP est une chaîne,sFichierDestination est une chaîne="",bAvecJauge est un booléen=Faux,sPréfixeJauge est une chaîne="",nTimeOut est un entier = 5000,nPort est un entier = 80,sUser est une chaîne="", sPass est une chaîne="",sNomDuThread est une chaîne = threadPrincipal,sProxy est une chaîne = "") sNomThread est une chaîne = "MonThreadHTTP" gsErreurHTTP="" ThreadExécute(sNomThread,threadNormal,TéléchargeHTTP,(sFichierDestination>""),sFichierHTTP,sFichierDestination,bAvecJauge,sPréfixeJauge,nTimeOut,nPort,sUser,sPass,sNomDuThread,sProxy);ThreadAttendSignal() TANTQUE ThreadEtat(sNomThread)=threadEnCours SI gbAnnule ALORS ThreadArrête(sNomThread) Multitâche(-5) FIN RENVOYER gsErreurHTTP