Envoi de fichier par requête Http Post

Partagez votre expérience de PureBasic avec les autres utilisateurs.
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Re: Envoi de fichier par requête Http Post

Message par lepiaf31 »

Kwai chang caine a écrit :J'ai essayé de me la jouer, en le copiant dans le test.php, mais evidemment....quand on sait pas fumer..faut pas jouer avec les allumettes :oops:
xDD

Bah j'ai juste uploader le fichier a la racine du serveur avec le nom "test.php" et ensuite j'ai créer un dossier "tmp" à la racine du serveur et ensuite bah il faut juste penser à changer l'host dans le code en PB. Et puis c'est tout ^^
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Envoi de fichier par requête Http Post

Message par Kwai chang caine »

YEEEEeeeeeeaaaaahhhhhhh !!!
Tu va pas y croire...j'ai trouvé ....

En fait la limitation c'est toi qui l'a mise :lol:
Mon texte il etait super balaise et bien superieur a 300 Octets :mrgreen:

J'ai passé à 300000 au diable "les varices"...et il est arrivé comme un seul homme..
Bah j'ai juste uploader le fichier a la racine du serveur avec le nom "test.php"
Moi j'ai commis ça...et ça marche :oops:

Code : Tout sélectionner

<?php
if ($_SERVER['REQUEST_METHOD']=="POST") {
echo"POST REQUEST Ok/";
foreach($_POST as $name=>$value) {
echo "POST[$name] = $value /";
}
echo"___";
foreach($_GET as $name=>$value) {
echo "GET[$name] = $value /";
}
echo"FILE /";
var_dump($_FILES);
}

if(isset($_FILES['txt'])){ 
   if($_FILES['txt']['error'] == 0){ //pas d'erreur
      if(substr($_FILES['txt']['name'], -4) == '.txt' && $_FILES['txt']['size'] < 30000){ //on n'accepte que les fichiers ayant l'extentation txt et qui sont inferieur à 300 octets
         $name = 'tmp/'.$_FILES['txt']['name'].'_'.microtime().'.txt';
         move_uploaded_file($_FILES['txt']['tmp_name'], $name); //on déplace le fichier
         echo 'Le fichier a été déplacé dans le dossier '.$name;
      }
   }
}

?>
<form action="test.php"
enctype="multipart/form-data" method="post">
<p>
Type some text (if you like):<br>
<input type="text" name="textline" size="30">
</p>
<p>
Please specify a file, or a set of files:<br>
<input type="file" name="datafile" size="40">
</p>
<div>
<input type="submit" value="Send">
</div>
</form>
Je vais essayer chez toi en le reduisant 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Envoi de fichier par requête Http Post

Message par Kwai chang caine »

Youuupi Youpette !!!(Pas sur que ça existe au féminin :roll: )

Ca marche aussi chez toi....
T'as été un peu radin sur les octets....t'avais peut etre peur que "quinquin" t'envoie l'encyclopedie larousse en 20 volumes, et fasse chuter FREE :lol:

C'est génial, t'es un chef

Bon j'ai compris pour les fichiers, mais tu va rire...quoi que....j'suis pas sur :oops:
J'ai encore pas tout compris pour les variables....je me pencherais demain sur ça

En attendant, on peut faire des trucs de "guedin" entre PB et le WEBDaube...entre les CGI et les Serveur PB, je crois que me voila au debut d'un nouvel espace de jeux.

Ce que je cherche a faire, c'est des pages cryptées envoyées avec un simple navigateur, ton code va beaucoup m'aider 8)
Encore merci de ta patience :wink:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Re: Envoi de fichier par requête Http Post

Message par lepiaf31 »

Kwai chang caine a écrit :T'as été un peu radin sur les octets....t'avais peut etre peur que "quinquin" t'envoie l'encyclopedie larousse en 20 volumes, et fasse chuter FREE :lol:
Oulala tu sais pas à quel point il y a des farfelus sur la toile ^^
Kwai chang caine a écrit :Encore merci de ta patience :wink:
De rien =)
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Envoi de fichier par requête Http Post

Message par Kwai chang caine »

Oulala tu sais pas à quel point il y a des farfelus sur la toile ^^
T'as raison!!!
Et va bientot en avoir un de plus a qui on a donné quelques clefs pour pouvoir "démarrer la bagnole" des serveurs, et pas expliqué ou etait les freins :mrgreen: :lol: :lol:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Re: Envoi de fichier par requête Http Post

Message par lepiaf31 »

hahaha ^^
Bonne route alors ^^
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Envoi de fichier par requête Http Post

Message par Thyphoon »

Désolé j'ai été pris part le boulot ! mais bon je vois que KCC a réussit a envoyé un fichier !:P

voici une proposition de procédure a rajouter a ton code. (elle doit surement être améliorer)
Je n'ai pu la testé que dans le cadre d'un proxy. je le ferais au besoin plus tard pour le reste.
je trouve plus simple d'avoir les paramètres proxy vraiment séparer de l'url d'envoie (path/host).
car l'url d'envoie ne change pas mais tu peux en fonction de ton lieu activé ou desactivé le proxy. Qu'en penses tu ?

J'ai rencontré un problème par contre ! ton code n'est pas compatible unicode ! si tu as une idée ?

en tout cas ce code est terrible ! merci beaucoup lepiaf31 pour ce partage !

Code : Tout sélectionner

Procedure HTTP_parse(*test.HTTP_Query,method.b,url.s,proxyHost.s="", port.l=80,proxyLogin.s="", proxyPassword.s="")
  Protected host.s,path.s,login.s,pass.s,res.s,string.s
  ; si on a un proxy
  If proxyHost<>""
    HTTP_createQuery(*test, method, url, proxyHost,port,proxyLogin,proxyPassword)
  ;si on a pas de proxy  
  Else
    host = GetURLPart(url, #PB_URL_Site); the main domain
    path =GetURLPart(url,#PB_URL_Path); the path
    port= Val(GetURLPart(url, #PB_URL_Port))
    HTTP_createQuery(*test, method, "/"+path, host,port)
  EndIf
  ;si on a une protection part login/password via un htacess
  login=GetURLPart(url, #PB_URL_User)
  pass=GetURLPart(url, #PB_URL_Password)
  If login <> ""
    string = login+":"+pass
    res = Space(Len(string)*4)
    Base64Encoder(@string, Len(string), @res, Len(string)*4)
    HTTP_addQueryHeader(*test, "Authorization", "Basic "+res)
  EndIf
EndProcedure
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Envoi de fichier par requête Http Post

Message par Thyphoon »

bon j'ai réussi a rendre ton code compatible unicode
il faut dans tout les cas envoyer de l'ascii et recevoir de l'ascii
j'ai donc fait une petite macro

Code : Tout sélectionner

Macro SendNetworkAscii(__cnx,__txt)
  *tmpbuffer=AllocateMemory(StringByteLength(__txt, #PB_Ascii)+1)
  PokeS(*tmpbuffer,__txt,Len(__txt),#PB_Ascii)
  SendNetworkData(__cnx, *tmpbuffer, StringByteLength(__txt, #PB_Ascii))
  FreeMemory(*tmpbuffer)
EndMacro
voilà ! qu'en penses tu ?

Code : Tout sélectionner

;*********************************************
;***** Envoi de fichier par requete HTTP *****
;******** Par lepiaf31 le 28/06/2011 *********
;*********************************************


EnableExplicit

Structure HTTP_file
  name.s
  path.s
EndStructure

Structure HTTP_Query
  method.b
  host.s
  port.i
  path.s
  boundary.s
  List headers.s()
  List postData.s()
  List files.HTTP_file()
EndStructure

Enumeration
  #HTTP_METHOD_GET
  #HTTP_METHOD_POST
  #HTTP_METHOD_FILE
EndEnumeration


Procedure HTTP_addQueryHeader(*query.HTTP_Query, name.s, value.s)
  Protected string.s
 
  string = name+": "+value
  AddElement(*query\headers())
  *query\headers() = string
EndProcedure

Procedure HTTP_createQuery(*query.HTTP_Query, method.b, path.s, host.s, port.i=80, proxyHost.s="", login.s="", password.s="")
  Protected query.HTTP_Query, result.i, string.s, res.s
 
  *query\method = method
  *query\host = host
  *query\port = port
  *query\path = path
 
  If proxyHost <> ""
    *query\host = proxyHost
    If login <> ""
      string = login+":"+password
      res = Space(Len(string)*4)
      Base64Encoder(@string, Len(string), @res, Len(string)*4)
      HTTP_addQueryHeader(*query, "Proxy-Authorization", "Basic "+res)
    EndIf
  EndIf
 
  HTTP_addQueryHeader(*query, "Host", host)
  If method = #HTTP_METHOD_POST
    HTTP_addQueryHeader(*query, "Content-type", "application/x-www-form-urlencoded")
  ElseIf method = #HTTP_METHOD_FILE
    *query\boundary = "----------"+Str(ElapsedMilliseconds())
    HTTP_addQueryHeader(*query, "Content-type", "multipart/form-data; boundary="+*query\boundary)
  EndIf
EndProcedure

Procedure HTTP_addPostData(*query.HTTP_Query, name.s, value.s)
  Protected string.s
 
  If *query\method =#HTTP_METHOD_POST Or *query\method = #HTTP_METHOD_FILE
    string = ReplaceString(URLEncoder(name), "=", "%3D")+"="+ReplaceString(URLEncoder(value), "=", "%3D")
    AddElement(*query\postData())
    *query\postData() = string
    ProcedureReturn 1
  EndIf
 
  ProcedureReturn 0
EndProcedure

Procedure HTTP_addFile(*query.HTTP_Query, name.s, fileName.s)
  If *query\method = #HTTP_METHOD_FILE And FileSize(fileName) > -1
    AddElement(*query\files())
    *query\files()\name = name
    *query\files()\path = fileName
    ProcedureReturn 1
  EndIf
 
  ProcedureReturn 0
EndProcedure
Macro SendNetworkAscii(__cnx,__txt)
  *tmpbuffer=AllocateMemory(StringByteLength(__txt, #PB_Ascii)+1)
  PokeS(*tmpbuffer,__txt,Len(__txt),#PB_Ascii)
  SendNetworkData(__cnx, *tmpbuffer, StringByteLength(__txt, #PB_Ascii))
  FreeMemory(*tmpbuffer)
EndMacro

Procedure HTTP_sendQuery(*query.HTTP_Query)
  Protected head.s, postData.s, connection.i, size.i, fileHeaderSize.i, file.i, readed.i, *buffer,*tmpbuffer
 
  ;Methode
  Select *query\method
    Case #HTTP_METHOD_GET
      head = "GET "
    Case #HTTP_METHOD_POST
      head = "POST "
    Case #HTTP_METHOD_FILE
      head = "POST "
  EndSelect
 
  ;En-tetes
  head + *query\path + " HTTP/1.0" + #CRLF$
  ForEach *query\headers()
    head + *query\headers() + #CRLF$
  Next
 
  connection = OpenNetworkConnection(*query\host, *query\port)
  If connection
    Select *query\method
      Case #HTTP_METHOD_GET
        head + #CRLF$
        
        SendNetworkAscii(connection,head)
     
      Case #HTTP_METHOD_POST
        ForEach *query\postData()
          postData + *query\postData() + "&"
        Next
        postData = Left(postData, Len(postData)-1)
       
        head + "Content-Length: "+Str(Len(postData)) + #CRLF$
        head + #CRLF$
        head + postData
        SendNetworkAscii(connection, head)
      Case #HTTP_METHOD_FILE
        ForEach *query\postData()
          postData + "--"+*query\boundary+#CRLF$
          postData +"Content-Disposition: form-data; name="+Chr(34)+StringField(*query\postData(), 1, "=")+Chr(34)+#CRLF$
          postData + #CRLF$
          postData + StringField(*query\postData(), 2, "=")+#CRLF$
        Next
       
        fileHeaderSize = Len("Content-Disposition: form-data; name="+Chr(34)+Chr(34) +"; filename="+Chr(34)+Chr(34)+#CRLF$+"Content-Type: application/octet-stream" + #CRLF$ + #CRLF$)
        size = fileHeaderSize * ListSize(*query\files())
        ForEach *query\files()
          size + Len(GetFilePart(*query\files()\path))
          size + Len(*query\files()\name)
          size + 4
          size + FileSize(*query\files()\path)
          size + Len("--"+*query\boundary)
        Next
        size + Len(postData)
        size + (2+Len(*query\boundary)+2)
       
        head + "Content-Length: "+Str(size)+#CRLF$
        head + #CRLF$
        head + postData
        SendNetworkAscii(connection,head)
        *buffer = AllocateMemory(2048)
        ForEach *query\files()
          postData = "--"+*query\boundary+#CRLF$
          postData + "Content-Disposition: form-data; name="+Chr(34)+*query\files()\name+Chr(34) +"; filename="+Chr(34)+GetFilePart(*query\files()\path)+Chr(34)+#CRLF$
          postData + "Content-Type: application/octet-stream" + #CRLF$ + #CRLF$
          SendNetworkAscii(connection,postData)
          file = OpenFile(#PB_Any, *query\files()\path)
         
          If file
            While Eof(file) = 0
              readed = ReadData(file, *buffer, 2048)
              SendNetworkData(connection, *buffer, readed)
            Wend
            SendNetworkAscii(connection,#CRLF$)
            CloseFile(file)
          EndIf
       Next
       FreeMemory(*buffer)
       
       postData = "--"+*query\boundary+"--"
       SendNetworkData(connection, @postData, Len(postData))
    EndSelect
   
    ProcedureReturn connection
  EndIf
 
  ProcedureReturn 0
EndProcedure

Procedure HTTP_parse(*test.HTTP_Query,method.b,url.s,proxyHost.s="", port.l=80,proxyLogin.s="", proxyPassword.s="")
  Protected host.s,path.s,login.s,pass.s,res.s,string.s
  ; si on a un proxy
  If proxyHost<>""
    HTTP_createQuery(*test, method, url, proxyHost,port,proxyLogin,proxyPassword)
  ;si on a pas de proxy  
  Else
    host = GetURLPart(url, #PB_URL_Site); the main domain
    path =GetURLPart(url,#PB_URL_Path); the path
    port= Val(GetURLPart(url, #PB_URL_Port))
    HTTP_createQuery(*test, method, "/"+path, host,port)
  EndIf
  ;si on a une protection part login/password via un htacess
  login=GetURLPart(url, #PB_URL_User)
  pass=GetURLPart(url, #PB_URL_Password)
  If login <> ""
    string = login+":"+pass
    res = Space(Len(string)*4)
    Base64Encoder(@string, Len(string), @res, Len(string)*4)
    HTTP_addQueryHeader(*test, "Authorization", "Basic "+res)
  EndIf
EndProcedure

Procedure main()
  Protected test.HTTP_Query, string.s, readed.i, conn.i, time.i,*string
  InitNetwork()
  OpenConsole()
    HTTP_parse(@test, #HTTP_METHOD_FILE, "http://www.thyphoon.com/test.php","spxy.bpi.fr",3128)
    ;HTTP_createQuery(@test, #HTTP_METHOD_FILE, "/test.php", "www.thyphoon.com")
    HTTP_addQueryHeader(@test, "User-Agent", "PB")
    HTTP_addPostData(@test, "pseudo", "lepiaf31")
    HTTP_addPostData(@test, "nom", "Kevin")
    HTTP_addFile(@test, "datafile", OpenFileRequester("Please choose file to load", "", "*.*", 0))
    conn = HTTP_sendQuery(@test)
    If conn
      *string = AllocateMemory(2048)
      time = ElapsedMilliseconds()
      Repeat
        If NetworkClientEvent(conn) = #PB_NetworkEvent_Data
          
          readed = ReceiveNetworkData(conn, *string, 2048)
          Print(PeekS(*string,readed,#PB_Ascii))
          time = ElapsedMilliseconds()
        EndIf
        Delay(100)
      Until ElapsedMilliseconds() - time >= 3000
    EndIf
    Input()
  EndProcedure
  main()

lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Re: Envoi de fichier par requête Http Post

Message par lepiaf31 »

Pour ce qui est du passage Ainsi->Unicode je te fais confiance ^^

Pour la fonction de "parsage" j'aurais plutot fait un truc du genre:

Code : Tout sélectionner

Procedure HTTP_parseUrl(url.s, *host, *path, *port, *proxyLogin, *proxyPassword)
  PokeS(*host, GetURLPart(url, #PB_URL_Site))
  PokeS(*path, Left(GetURLPart(url, #PB_URL_Path), FindString(GetURLPart(url, #PB_URL_Path), ":", 1)-1))
  PokeI(*port, Val(GetURLPart(url, #PB_URL_Port)))
  PokeS(*proxyLogin, GetURLPart(url, #PB_URL_User))
  PokeS(*proxyPassword, GetURLPart(url, #PB_URL_Password))
EndProcedure

port.i = 0
host.s = Space(255)
path.s = Space(255)
login.s = Space(255)
pass.s = Space(255)

url.s = "http://toto:pass@www.thyphoon.com/test.php:80"
HTTP_parseUrl(url, @host, @path, @port, @login, @pass)
Debug "HOST: "+host
Debug "PORT: "+Str(port)
Debug "PATH: /"+path
Debug "LOGIN: "+login
Debug "PASSWORD: "+pass
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Envoi de fichier par requête Http Post

Message par Thyphoon »

effectivement... le nom de ma fonction est peut être pas la bonne car elle ne fait pas que parser ... :P

bon faut que je regarde ça !
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Envoi de fichier par requête Http Post

Message par Thyphoon »

J'ai facilité (enfin moi je trouve :P) l'utilisation du proxy grace a

Code : Tout sélectionner

 HTTP_proxy(*test.HTTP_Query,host.s="",port.i=80,login.s="",password.s="")
et aussi une procédure supplémentaire qui simplifie et automatise certaine fonction (proxy/protection htacess)

Code : Tout sélectionner

HTTP_query(*test.HTTP_Query,method.b,url.s)
voilà j’espère que lepiaf31 n'aura pas l'impression que je dénature son code :P (n’hésite pas a me le dire si ça ne vas pas)

juste un détail comment faire pour envoyé une requête a un site sur un port(exemple:81) via un proxy(exemple:2300) ?

Code : Tout sélectionner

;*********************************************
;***** Envoi de fichier par requete HTTP *****
;******** Par lepiaf31 le 28/06/2011 *********
;******** quelques modifs part thyphoon  *********
;*********************************************


EnableExplicit

Structure HTTP_file
  name.s
  path.s
EndStructure

Structure HTTP_Proxy
  host.s
  port.i
  login.s
  password.s
EndStructure

Structure HTTP_Query
  method.b
  host.s
  port.i
  path.s
  boundary.s
  proxy.HTTP_Proxy
  List headers.s()
  List postData.s()
  List files.HTTP_file()
EndStructure


Enumeration
  #HTTP_METHOD_GET
  #HTTP_METHOD_POST
  #HTTP_METHOD_FILE
EndEnumeration


Procedure HTTP_addQueryHeader(*query.HTTP_Query, name.s, value.s)
  Protected string.s

  string = name+": "+value
  AddElement(*query\headers())
  *query\headers() = string
EndProcedure

Procedure HTTP_createQuery(*query.HTTP_Query, method.b, path.s, host.s, port.i=80, proxyHost.s="", login.s="", password.s="")
  Protected query.HTTP_Query, result.i, string.s, res.s

  *query\method = method
  *query\host = host
  *query\port = port
  *query\path = path

  If proxyHost <> ""
    *query\host = proxyHost
    If login <> ""
      string = login+":"+password
      res = Space(Len(string)*4)
      Base64Encoder(@string, Len(string), @res, Len(string)*4)
      HTTP_addQueryHeader(*query, "Proxy-Authorization", "Basic "+res)
    EndIf
  EndIf

  HTTP_addQueryHeader(*query, "Host", host)
  If method = #HTTP_METHOD_POST
    HTTP_addQueryHeader(*query, "Content-type", "application/x-www-form-urlencoded")
  ElseIf method = #HTTP_METHOD_FILE
    *query\boundary = "----------"+Str(ElapsedMilliseconds())
    HTTP_addQueryHeader(*query, "Content-type", "multipart/form-data; boundary="+*query\boundary)
  EndIf
EndProcedure

Procedure HTTP_addPostData(*query.HTTP_Query, name.s, value.s)
  Protected string.s

  If *query\method =#HTTP_METHOD_POST Or *query\method = #HTTP_METHOD_FILE
    string = ReplaceString(URLEncoder(name), "=", "%3D")+"="+ReplaceString(URLEncoder(value), "=", "%3D")
    AddElement(*query\postData())
    *query\postData() = string
    ProcedureReturn 1
  EndIf

  ProcedureReturn 0
EndProcedure

Procedure HTTP_addFile(*query.HTTP_Query, name.s, fileName.s)
  If *query\method = #HTTP_METHOD_FILE And FileSize(fileName) > -1
    AddElement(*query\files())
    *query\files()\name = name
    *query\files()\path = fileName
    ProcedureReturn 1
  EndIf

  ProcedureReturn 0
EndProcedure
Macro SendNetworkAscii(__cnx,__txt)
  *tmpbuffer=AllocateMemory(StringByteLength(__txt, #PB_Ascii)+1)
  PokeS(*tmpbuffer,__txt,Len(__txt),#PB_Ascii)
  SendNetworkData(__cnx, *tmpbuffer, StringByteLength(__txt, #PB_Ascii))
  FreeMemory(*tmpbuffer)
EndMacro

Procedure HTTP_sendQuery(*query.HTTP_Query)
  Protected head.s, postData.s, connection.i, size.i, fileHeaderSize.i, file.i, readed.i, *buffer,*tmpbuffer

  ;Methode
  Select *query\method
    Case #HTTP_METHOD_GET
      head = "GET "
    Case #HTTP_METHOD_POST
      head = "POST "
    Case #HTTP_METHOD_FILE
      head = "POST "
  EndSelect

  ;En-tetes
  head + *query\path + " HTTP/1.0" + #CRLF$
  ForEach *query\headers()
    head + *query\headers() + #CRLF$
  Next

  connection = OpenNetworkConnection(*query\host, *query\port)
  If connection
    Select *query\method
      Case #HTTP_METHOD_GET
        head + #CRLF$
       
        SendNetworkAscii(connection,head)
     
      Case #HTTP_METHOD_POST
        ForEach *query\postData()
          postData + *query\postData() + "&"
        Next
        postData = Left(postData, Len(postData)-1)
       
        head + "Content-Length: "+Str(Len(postData)) + #CRLF$
        head + #CRLF$
        head + postData
        SendNetworkAscii(connection, head)
      Case #HTTP_METHOD_FILE
        ForEach *query\postData()
          postData + "--"+*query\boundary+#CRLF$
          postData +"Content-Disposition: form-data; name="+Chr(34)+StringField(*query\postData(), 1, "=")+Chr(34)+#CRLF$
          postData + #CRLF$
          postData + StringField(*query\postData(), 2, "=")+#CRLF$
        Next
       
        fileHeaderSize = Len("Content-Disposition: form-data; name="+Chr(34)+Chr(34) +"; filename="+Chr(34)+Chr(34)+#CRLF$+"Content-Type: application/octet-stream" + #CRLF$ + #CRLF$)
        size = fileHeaderSize * ListSize(*query\files())
        ForEach *query\files()
          size + Len(GetFilePart(*query\files()\path))
          size + Len(*query\files()\name)
          size + 4
          size + FileSize(*query\files()\path)
          size + Len("--"+*query\boundary)
        Next
        size + Len(postData)
        size + (2+Len(*query\boundary)+2)
       
        head + "Content-Length: "+Str(size)+#CRLF$
        head + #CRLF$
        head + postData
        SendNetworkAscii(connection,head)
        *buffer = AllocateMemory(2048)
        ForEach *query\files()
          postData = "--"+*query\boundary+#CRLF$
          postData + "Content-Disposition: form-data; name="+Chr(34)+*query\files()\name+Chr(34) +"; filename="+Chr(34)+GetFilePart(*query\files()\path)+Chr(34)+#CRLF$
          postData + "Content-Type: application/octet-stream" + #CRLF$ + #CRLF$
          SendNetworkAscii(connection,postData)
          file = OpenFile(#PB_Any, *query\files()\path)
         
          If file
            While Eof(file) = 0
              readed = ReadData(file, *buffer, 2048)
              SendNetworkData(connection, *buffer, readed)
            Wend
            SendNetworkAscii(connection,#CRLF$)
            CloseFile(file)
          EndIf
       Next
       FreeMemory(*buffer)
       
       postData = "--"+*query\boundary+"--"
       SendNetworkData(connection, @postData, Len(postData))
    EndSelect
   
    ProcedureReturn connection
  EndIf

  ProcedureReturn 0
EndProcedure

Procedure HTTP_proxy(*test.HTTP_Query,host.s="",port.i=80,login.s="",password.s="")
  *test\proxy\host=host
  *test\proxy\port=port
  *test\proxy\login=login
  *test\proxy\password=password
EndProcedure

Procedure HTTP_query(*test.HTTP_Query,method.b,url.s)
  Protected host.s,port.l,path.s,login.s,pass.s,res.s,string.s
  ; si on a un proxy
  If *test\proxy\host<>""
    HTTP_createQuery(*test, method, url, *test\proxy\host,*test\proxy\port,*test\proxy\login,*test\proxy\password)
  ;si on a pas de proxy 
  Else
    host = GetURLPart(url, #PB_URL_Site); the main domain
    path =GetURLPart(url,#PB_URL_Path); the path
    port= Val(GetURLPart(url, #PB_URL_Port))
    If port=0:port=80:EndIf
    HTTP_createQuery(*test, method, "/"+path, host,port)
  EndIf
  ;si on a une protection part login/password via un htacess
  login=GetURLPart(url, #PB_URL_User)
  pass=GetURLPart(url, #PB_URL_Password)
  If login <> ""
    string = login+":"+pass
    res = Space(Len(string)*4)
    Base64Encoder(@string, Len(string), @res, Len(string)*4)
    HTTP_addQueryHeader(*test, "Authorization", "Basic "+res)
  EndIf
EndProcedure

Procedure main()
  Protected test.HTTP_Query, string.s, readed.i, conn.i, time.i,*string
  InitNetwork()
  OpenConsole()
    ;HTTP_proxy(@test,"proxytest.fr",2400)
    HTTP_query(@test, #HTTP_METHOD_FILE, "http://www.thyphoon.com/test.php")
    ;HTTP_createQuery(@test, #HTTP_METHOD_FILE, "/test.php", "www.thyphoon.com")
    HTTP_addQueryHeader(@test, "User-Agent", "PB")
    HTTP_addPostData(@test, "pseudo", "lepiaf31")
    HTTP_addPostData(@test, "nom", "Kevin")
    HTTP_addFile(@test, "datafile", OpenFileRequester("Please choose file to load", "", "*.*", 0))
    conn = HTTP_sendQuery(@test)
    If conn
      *string = AllocateMemory(2048)
      time = ElapsedMilliseconds()
      Repeat
        If NetworkClientEvent(conn) = #PB_NetworkEvent_Data
         
          readed = ReceiveNetworkData(conn, *string, 2048)
          Print(PeekS(*string,readed,#PB_Ascii))
          time = ElapsedMilliseconds()
        EndIf
        Delay(100)
      Until ElapsedMilliseconds() - time >= 3000
    EndIf
    Input()
  EndProcedure
  main()
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Envoi de fichier par requête Http Post

Message par Thyphoon »

me revoilà !
j'ai rajouter quelques fonctions !
-HTTP_FindHeader(*mem) ; pour trouver la fin de l'header dans les données reçu en retour
-HTTP_receiveData(conn,*test.HTTP_Query) ;pour la réception des données
-HTTP_DownloadToFile(*test.HTTP_Query,url.s,file.s)
-HTTP_DownloadToMem(*test.HTTP_Query,url.s)

je pense que comme toujours ça peut être nettement améliorer.
j'aimerais rajouter un callback pour les fonctions de Download et améliorer certain truc mais on verra plus tard
Toute proposition d'amélioration est la bienvenu, mais aussi les commentaires négatif si quelques choses ne plait pas !
lepiaf31 n'hesite pas a me donner ton avis !
edit: voir code juste en dessous :P
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Envoi de fichier par requête Http Post

Message par Thyphoon »

quelques corrections et un truc de test !
pour l'instant je charge tout en mémoire et j'enregistre apprait sur le disque pour la commande HTTP_DownloadToFile(*test.HTTP_Query,url.s,file.s)
mais je vais étudier a enregistrer en streaming,
et j'aimerais aussi gérer les erreurs en retour !
comme d'hab n'hesitez pas a commenté !

Code : Tout sélectionner

;*********************************************
;***** Envoi de fichier par requete HTTP *****
;******** Par lepiaf31 le 28/06/2011 *********
;****** et quelques modif part thyphoon ******
;*********************************************


EnableExplicit

Structure HTTP_file
  name.s
  path.s
EndStructure

Structure HTTP_Proxy
  host.s
  port.i
  login.s
  password.s
EndStructure

Structure HTTP_Query
  method.b
  host.s
  port.i
  path.s
  boundary.s
  proxy.HTTP_Proxy
  List headers.s()
  List postData.s()
  List files.HTTP_file()
  conn.i          
  *buffer         ; buffer received data
  *data           ; complete received data
  *header         ; received header data
EndStructure


Enumeration
  #HTTP_METHOD_GET
  #HTTP_METHOD_POST
  #HTTP_METHOD_FILE
EndEnumeration


Procedure HTTP_addQueryHeader(*query.HTTP_Query, name.s, value.s)
  Protected string.s

  string = name+": "+value
  AddElement(*query\headers())
  *query\headers() = string
EndProcedure

Procedure HTTP_createQuery(*query.HTTP_Query, method.b, path.s, host.s, port.i=80, proxyHost.s="", login.s="", password.s="")
  Protected query.HTTP_Query, result.i, string.s, res.s

  *query\method = method
  *query\host = host
  *query\port = port
  *query\path = path

  If proxyHost <> ""
    *query\host = proxyHost
    If login <> ""
      string = login+":"+password
      res = Space(Len(string)*4)
      Base64Encoder(@string, Len(string), @res, Len(string)*4)
      HTTP_addQueryHeader(*query, "Proxy-Authorization", "Basic "+res)
    EndIf
  EndIf

  HTTP_addQueryHeader(*query, "Host", host)
  If method = #HTTP_METHOD_POST
    HTTP_addQueryHeader(*query, "Content-type", "application/x-www-form-urlencoded")
  ElseIf method = #HTTP_METHOD_FILE
    *query\boundary = "----------"+Str(ElapsedMilliseconds())
    HTTP_addQueryHeader(*query, "Content-type", "multipart/form-data; boundary="+*query\boundary)
  EndIf
EndProcedure

Procedure HTTP_addPostData(*query.HTTP_Query, name.s, value.s)
  Protected string.s

  If *query\method =#HTTP_METHOD_POST Or *query\method = #HTTP_METHOD_FILE
    string = ReplaceString(URLEncoder(name), "=", "%3D")+"="+ReplaceString(URLEncoder(value), "=", "%3D")
    AddElement(*query\postData())
    *query\postData() = string
    ProcedureReturn 1
  EndIf

  ProcedureReturn 0
EndProcedure

Procedure HTTP_addFile(*query.HTTP_Query, name.s, fileName.s)
  If *query\method = #HTTP_METHOD_FILE And FileSize(fileName) > -1
    AddElement(*query\files())
    *query\files()\name = name
    *query\files()\path = fileName
    ProcedureReturn 1
  EndIf

  ProcedureReturn 0
EndProcedure
Macro SendNetworkAscii(__cnx,__txt)
  *tmpbuffer=AllocateMemory(StringByteLength(__txt, #PB_Ascii)+1)
  PokeS(*tmpbuffer,__txt,Len(__txt),#PB_Ascii)
  SendNetworkData(__cnx, *tmpbuffer, StringByteLength(__txt, #PB_Ascii))
  FreeMemory(*tmpbuffer)
EndMacro

Procedure HTTP_sendQuery(*query.HTTP_Query)
  Protected head.s, postData.s, connection.i, size.i, fileHeaderSize.i, file.i, readed.i, *buffer,*tmpbuffer

  ;Methode
  Select *query\method
    Case #HTTP_METHOD_GET
      head = "GET "
    Case #HTTP_METHOD_POST
      head = "POST "
    Case #HTTP_METHOD_FILE
      head = "POST "
  EndSelect

  ;En-tetes
  head + *query\path + " HTTP/1.0" + #CRLF$
  ForEach *query\headers()
    head + *query\headers() + #CRLF$
  Next

  connection = OpenNetworkConnection(*query\host, *query\port)
  If connection
    Select *query\method
      Case #HTTP_METHOD_GET
        head + #CRLF$
       
        SendNetworkAscii(connection,head)
     
      Case #HTTP_METHOD_POST
        ForEach *query\postData()
          postData + *query\postData() + "&"
        Next
        postData = Left(postData, Len(postData)-1)
       
        head + "Content-Length: "+Str(Len(postData)) + #CRLF$
        head + #CRLF$
        head + postData
        SendNetworkAscii(connection, head)
      Case #HTTP_METHOD_FILE
        ForEach *query\postData()
          postData + "--"+*query\boundary+#CRLF$
          postData +"Content-Disposition: form-data; name="+Chr(34)+StringField(*query\postData(), 1, "=")+Chr(34)+#CRLF$
          postData + #CRLF$
          postData + StringField(*query\postData(), 2, "=")+#CRLF$
        Next
       
        fileHeaderSize = Len("Content-Disposition: form-data; name="+Chr(34)+Chr(34) +"; filename="+Chr(34)+Chr(34)+#CRLF$+"Content-Type: application/octet-stream" + #CRLF$ + #CRLF$)
        size = fileHeaderSize * ListSize(*query\files())
        ForEach *query\files()
          size + Len(GetFilePart(*query\files()\path))
          size + Len(*query\files()\name)
          size + 4
          size + FileSize(*query\files()\path)
          size + Len("--"+*query\boundary)
        Next
        size + Len(postData)
        size + (2+Len(*query\boundary)+2)
       
        head + "Content-Length: "+Str(size)+#CRLF$
        head + #CRLF$
        head + postData
        SendNetworkAscii(connection,head)
        *buffer = AllocateMemory(2048)
        ForEach *query\files()
          postData = "--"+*query\boundary+#CRLF$
          postData + "Content-Disposition: form-data; name="+Chr(34)+*query\files()\name+Chr(34) +"; filename="+Chr(34)+GetFilePart(*query\files()\path)+Chr(34)+#CRLF$
          postData + "Content-Type: application/octet-stream" + #CRLF$ + #CRLF$
          SendNetworkAscii(connection,postData)
          file = OpenFile(#PB_Any, *query\files()\path)
         
          If file
            While Eof(file) = 0
              readed = ReadData(file, *buffer, 2048)
              SendNetworkData(connection, *buffer, readed)
            Wend
            SendNetworkAscii(connection,#CRLF$)
            CloseFile(file)
          EndIf
       Next
       FreeMemory(*buffer)
       
       postData = "--"+*query\boundary+"--"
       SendNetworkData(connection, @postData, Len(postData))
    EndSelect
   
    ProcedureReturn connection
  EndIf

  ProcedureReturn 0
EndProcedure
;- Nouvelles fonctions
;###############################################################################################################
Procedure HTTP_proxy(*test.HTTP_Query,host.s="",port.i=80,login.s="",password.s="")
  *test\proxy\host=host
  *test\proxy\port=port
  *test\proxy\login=login
  *test\proxy\password=password
EndProcedure

Procedure HTTP_query(*test.HTTP_Query,method.b,url.s)
  Protected host.s,port.l,path.s,login.s,pass.s,res.s,string.s
  ; si on a un proxy
  If *test\proxy\host<>""
    HTTP_createQuery(*test, method, url, *test\proxy\host,*test\proxy\port,*test\proxy\login,*test\proxy\password)
  ;si on a pas de proxy 
  Else
    host = GetURLPart(url, #PB_URL_Site); the main domain
    path =GetURLPart(url,#PB_URL_Path); the path
    port= Val(GetURLPart(url, #PB_URL_Port))
    If port=0:port=80:EndIf
    HTTP_createQuery(*test, method, "/"+path, host,port)
  EndIf
  ;si on a une protection part login/password via un htacess
  login=GetURLPart(url, #PB_URL_User)
  pass=GetURLPart(url, #PB_URL_Password)
  If login <> ""
    string = login+":"+pass
    res = Space(Len(string)*4)
    Base64Encoder(@string, Len(string), @res, Len(string)*4)
    HTTP_addQueryHeader(*test, "Authorization", "Basic "+res)
  EndIf
EndProcedure

Procedure HTTP_receiveRawData(*test.HTTP_Query)
  Protected *rawdata,time.i,readed.i,size.i
  If *test\conn
    *test\buffer = AllocateMemory(2048)
    *rawdata=AllocateMemory(1)
    time = ElapsedMilliseconds()
    Repeat
      If NetworkClientEvent(*test\conn) = #PB_NetworkEvent_Data
        
        readed = ReceiveNetworkData(*test\conn, *test\buffer, 2048)
        If readed>0
          Debug readed
          
          size=MemorySize(*rawdata)
          If size=1:size=0:EndIf
          *rawdata=ReAllocateMemory(*rawdata,size+readed)
          CopyMemory(*test\buffer,*rawdata+size,readed)
        Else 
          Debug "rien"
        EndIf
        time = ElapsedMilliseconds()
        
      EndIf
      Delay(100)
      
    Until ElapsedMilliseconds() - time >= 3000
    FreeMemory(*test\buffer):*test\buffer=0;
    Debug "efface buffer:"+Str(*test\buffer)
    ProcedureReturn *rawdata
  EndIf
EndProcedure
  
  ; find the end of the header
  Procedure HTTP_FindHeader(*mem)
    Protected z.l
    For z=0 To MemorySize(*mem)-4
      If PeekB(*mem+z)=13 And PeekB(*mem+z+1)=10 And PeekB(*mem+z+2)=13 And PeekB(*mem+z+3)=10
        ProcedureReturn z+4
      EndIf
    Next
    ProcedureReturn 0
  EndProcedure
   
Procedure HTTP_DownloadToMem(*test.HTTP_Query,url.s)
    Protected  *rawdata,lenght.i
    HTTP_query(*test, #HTTP_METHOD_GET, url)
    HTTP_addQueryHeader(*test, "User-Agent", "PB")
    *test\conn = HTTP_sendQuery(*test)
    *rawdata=HTTP_receiveRawData(*test)
    lenght=HTTP_FindHeader(*rawdata) ;found the lenght of the header
    ;copy file data
    *test\data=AllocateMemory(MemorySize(*rawdata)-lenght)
    CopyMemory(*rawdata+lenght,*test\data,MemorySize(*rawdata)-lenght);
    ;copy header
    *test\header=AllocateMemory(lenght)
    CopyMemory(*rawdata,*test\header,lenght); +1 because i don't know why but the data start with 0
    Debug PeekS(*test\header,MemorySize(*test\header),#PB_Ascii)
    FreeMemory(*rawdata):*rawdata=0
    CloseNetworkConnection(*test\conn)
    ProcedureReturn #True
  EndProcedure
  
  Procedure HTTP_DownloadToFile(*test.HTTP_Query,url.s,file.s)
    HTTP_DownloadToMem(*test,url.s)
    If *test\data<>0
      CreateFile(0,file)
      WriteData(0,*test\data,MemorySize(*test\data))
      CloseFile(0)
      FreeMemory(*test\data):*test\data=0
      ProcedureReturn #True
    Else  
      ProcedureReturn #False  
    EndIf
  EndProcedure


;-Exemple !
CompilerIf Defined(INCLUDEINPROJECT,#PB_Constant)=0
InitNetwork()
Procedure test1()
  Protected test.HTTP_Query, string.s, readed.i, conn.i, time.i,*string
  InitNetwork()
  OpenConsole()
    HTTP_proxy(@test,"spxy.bpi.fr",3128)
    HTTP_query(@test, #HTTP_METHOD_FILE, "http://www.thyphoon.com/test.php")
    ;HTTP_createQuery(@test, #HTTP_METHOD_FILE, "/test.php", "www.thyphoon.com")
    HTTP_addQueryHeader(@test, "User-Agent", "PB")
    HTTP_addPostData(@test, "pseudo", "lepiaf31")
    HTTP_addPostData(@test, "nom", "Kevin")
    HTTP_addFile(@test, "datafile", OpenFileRequester("Please choose file to load", "", "*.*", 0))
    conn = HTTP_sendQuery(@test)
    If conn
      *string = AllocateMemory(2048)
      time = ElapsedMilliseconds()
      Repeat
        If NetworkClientEvent(conn) = #PB_NetworkEvent_Data
         
          readed = ReceiveNetworkData(conn, *string, 2048)
          Print(PeekS(*string,readed,#PB_Ascii))
          time = ElapsedMilliseconds()
        EndIf
        Delay(100)
      Until ElapsedMilliseconds() - time >= 3000
    EndIf
    Input()
  EndProcedure
  ;test1()
  
Define test.HTTP_Query,url.s
  url="http://www.purebasic.com/images/box.png"
  HTTP_DownloadToFile(@test,url,GetTemporaryDirectory()+GetFilePart(url))
  RunProgram(GetTemporaryDirectory()+GetFilePart(url))
  
CompilerEndIf

Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Envoi de fichier par requête Http Post

Message par Kwai chang caine »

Super marche niquel, j'ai une belle boite de PB :mrgreen:
Et du "bla bla" en cadeau :lol:

Code : Tout sélectionner

2048
2048
2048
2048
2048
1943
efface buffer:0
HTTP/1.1 200 OK
Date: Sun, 10 Jul 2011 18:50:58 GMT
Server: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.17 with Suhosin-Patch
Last-Modified: Tue, 29 Dec 2009 23:44:09 GMT
ETag: "488004-2e6d-47be69926e440"
Accept-Ranges: bytes
Content-Length: 11885
Connection: close
Content-Type: image/png
Merci TYPHOON 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Envoi de fichier par requête Http Post

Message par Thyphoon »

content que ça te plaise j'essaye d'améliorer et de facilité l'emploie des procédures faite pas le piaf31 ! histoire d'avoir quelques choses de tres facilement utilisable part tout le monde ! :mrgreen: et tout ça cross-platforme !
Répondre