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) FIN
Pour 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