Page 4 sur 7

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 12:20
par lepiaf31
Heu ouais ben ecoutes jvais essayer de faire ca ^^

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 12:29
par Thyphoon
lepiaf31 a écrit :Heu ouais ben ecoutes jvais essayer de faire ca ^^
merci ! si ça peut t'aidé j'avais réussi a le faire voici la partie de mon code

Code : Tout sélectionner

Structure proxy_structure
  server.s      ;
  port.l        ;
  login.s       ;
  password.s    ;
EndStructure


;-TEST SI PROXY
  ;http://www.purebasic.fr/english/viewtopic.php?f=12&t=10327
  If *posts\proxy\server<>""
    connection = OpenNetworkConnection(*posts\proxy\server, *posts\proxy\port)
    POST + "POST "+*posts\url+" HTTP/1.0"+ #CRLF$
    If *posts\proxy\login<>""
      conc$=*posts\proxy\login+":"+*posts\proxy\password
      *OutputBuffer = AllocateMemory(Len(conc$)*4)
      Base64Encoder(@conc$,Len(conc$),*OutputBuffer,Len(conc$)*4)
      enc$=PeekS(*OutputBuffer)
      FreeMemory(*OutputBuffer)
     
      POST +"Proxy-Authorization: Basic "+enc$+#CRLF$
    EndIf
  Else
    connection = OpenNetworkConnection(url, port)
    POST + "POST "+"/"+path+" HTTP/1.0"+ #CRLF$
  EndIf
 

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 12:31
par lepiaf31
Bon voilà, pour utiliser un proxy c'est très simple : tout se fait lors de l'appel de HTTP_createQuery(), il faut simplement indiquer l'host du serveur proxy, son port et préciser le login. (Je n'ai pas testé mais je suppose que ca doit marcher puisque j'ai repris le code de Thyphoon).

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, 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 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
  
  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

Procedure HTTP_sendQuery(*query.HTTP_Query)
  Protected head.s, postData.s, connection.i, size.i, fileHeaderSize.i, file.i, readed.i, *buffer
  
  ;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$
  head + "Host: " + *query\host + #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$
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
      
      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
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
      
      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$)*SizeOf(Character)
        size = fileHeaderSize * ListSize(*query\files())
        ForEach *query\files()
          size + Len(GetFilePart(*query\files()\path))*SizeOf(Character)
          size + Len(*query\files()\name)*SizeOf(Character)
          size + 4*SizeOf(Character)
          size + FileSize(*query\files()\path)
          size + Len("--"+*query\boundary)*SizeOf(Character)
        Next
        size + Len(postData)*SizeOf(Character)
        size + (2+Len(*query\boundary)+2)*SizeOf(Character)
        
        head + "Content-Length: "+Str(size)+#CRLF$
        head + #CRLF$
        head + postData
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
        
        *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$
          SendNetworkData(connection, @postData, Len(postData)*SizeOf(Character))
          file = OpenFile(#PB_Any, *query\files()\path)
          
          If file
            While Eof(file) = 0
              readed = ReadData(file, *buffer, 2048)
              SendNetworkData(connection, *buffer, readed)
            Wend
            CloseFile(file)
          EndIf
       Next
       FreeMemory(*buffer)
       
       postData = #CRLF$+"--"+*query\boundary+"--"
       SendNetworkData(connection, @postData, Len(postData)*SizeOf(Character))
    EndSelect
    
    ProcedureReturn connection
  EndIf
  
  ProcedureReturn 0
EndProcedure

Procedure main()
  Protected test.HTTP_Query, string.s, readed.i, conn.i, time.i
  OpenConsole()
  InitNetwork()
  
  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", "envoi.txt")
  conn = HTTP_sendQuery(@test)
  
  string.s = Space(2048)
  time = ElapsedMilliseconds()
  Repeat
    If NetworkClientEvent(conn) = #PB_NetworkEvent_Data
      readed = ReceiveNetworkData(conn, @string, 2048)
      Print(Left(string, readed))
      time = ElapsedMilliseconds()
    EndIf
    Delay(100)
  Until ElapsedMilliseconds() - time >= 3000
  Input()
EndProcedure

main()

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 12:41
par Thyphoon
Merci beaucoup ! par contre j'ai pas très bien compris comment utiliser le proxy dans ton code.
entre autre chez moi j'ai un proxy mais sans login et password donc juste une adresse de serveur et un port !

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 12:44
par lepiaf31
Eh bien théoriquement (parce que je ne suis pas spécialement calé en ce qui concerne les proxy) tu as juste à faire :

Code : Tout sélectionner

test.HTTP_Query
HTTP_createQuery(@test, #HTTP_METHOD_GET, "/test.php", "adresseProxy.com", 8080) ;8080: port du proxy (pas besoin de spécifier le login
et ensuite tu mets ce que tu veux dans la requete et tu envoi.
Dis moi si ca marche

EDIT: erreur ca ne devrait pas marcher, il faut que je corrige quelque chose

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 12:52
par lepiaf31
Voilà, en fait j'ai rajouté le paramètre proxyHost à la fonction HTTP_createQuery().

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

Procedure HTTP_sendQuery(*query.HTTP_Query)
  Protected head.s, postData.s, connection.i, size.i, fileHeaderSize.i, file.i, readed.i, *buffer
  
  ;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$
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
      
      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
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
      
      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$)*SizeOf(Character)
        size = fileHeaderSize * ListSize(*query\files())
        ForEach *query\files()
          size + Len(GetFilePart(*query\files()\path))*SizeOf(Character)
          size + Len(*query\files()\name)*SizeOf(Character)
          size + 4*SizeOf(Character)
          size + FileSize(*query\files()\path)
          size + Len("--"+*query\boundary)*SizeOf(Character)
        Next
        size + Len(postData)*SizeOf(Character)
        size + (2+Len(*query\boundary)+2)*SizeOf(Character)
        
        head + "Content-Length: "+Str(size)+#CRLF$
        head + #CRLF$
        head + postData
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
        
        *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$
          SendNetworkData(connection, @postData, Len(postData)*SizeOf(Character))
          file = OpenFile(#PB_Any, *query\files()\path)
          
          If file
            While Eof(file) = 0
              readed = ReadData(file, *buffer, 2048)
              SendNetworkData(connection, *buffer, readed)
            Wend
            CloseFile(file)
          EndIf
       Next
       FreeMemory(*buffer)
       
       postData = #CRLF$+"--"+*query\boundary+"--"
       SendNetworkData(connection, @postData, Len(postData)*SizeOf(Character))
    EndSelect
    
    ProcedureReturn connection
  EndIf
  
  ProcedureReturn 0
EndProcedure

Procedure main()
  Protected test.HTTP_Query, string.s, readed.i, conn.i, time.i
  OpenConsole()
  InitNetwork()
  
  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", "envoi.txt")
  conn = HTTP_sendQuery(@test)
  
  string.s = Space(2048)
  time = ElapsedMilliseconds()
  Repeat
    If NetworkClientEvent(conn) = #PB_NetworkEvent_Data
      readed = ReceiveNetworkData(conn, @string, 2048)
      Print(Left(string, readed))
      time = ElapsedMilliseconds()
    EndIf
    Delay(100)
  Until ElapsedMilliseconds() - time >= 3000
  Input()
EndProcedure

main()

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 12:57
par Thyphoon
lepiaf31 a écrit :Eh bien théoriquement (parce que je ne suis pas spécialement calé en ce qui concerne les proxy) tu as juste à faire :

Code : Tout sélectionner

test.HTTP_Query
HTTP_createQuery(@test, #HTTP_METHOD_GET, "/test.php", "adresseProxy.com", 8080) ;8080: port du proxy (pas besoin de spécifier le login
et ensuite tu mets ce que tu veux dans la requete et tu envoi.
Dis moi si ca marche

EDIT: erreur ca ne devrait pas marcher, il faut que je corrige quelque chose
super ça marche d'enfer !
parcontre pour une question de simplicité mettre une url au lieu de séparer host et le path ? ça serait pas mieux, ça permet de jouer avec les différents façon d'écrire l'url
ex:http://toto:pass@www.thyphoon.com:80
ce qui me fait pensé qu'il ne manque plus qu'une seul chose pour que ton code soit parfait (et crois moi ton code est déjà pas loin de la perfection)
c'est justement la gestion des login et mot pass avec les htacess
je crois que c'est un truc du genre
POST + "Authorization: Basic "+ OutputBuffer + #CRLF$
ou le Outpufbuffer est login:pass en base64 comme pour le login et mot de passe du proxy

qu'en penses tu ?

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:01
par Kwai chang caine
De mon coté j'ai essayé et ça me remonte ça, est ce que c'est bon ??? :oops:

Code : Tout sélectionner

HTTP/1.1 307 Temporary Redirect
Location: https://authcla.entreprise.fr/?cfru=aHR0cDovL3d3dy50aHlwaG9vbi5jb20vdGVzdC5waHA=
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Proxy-Connection: close
Connection: close
Content-Length: 761

<HTML><HEAD>
<TITLE>Redirect</TITLE>
</HEAD>
<BODY>
<FONT face="Helvetica">
<center><big><strong>Acc&egrave;s Internet d&rsquo;</strong></big><BR></center>
</FONT>
<blockquote>
<TABLE border=0 cellPadding=1 width="80%">
<TR><TD>
<FONT face="Helvetica">
<big>Redirect (authentication_redirect_to_virtual_host)</big>
<BR>
<BR>
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
You are being redirected to the authentication virtual host.
</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">

</FONT>
</TD></TR>
<TR><TD>
<FONT face="Helvetica">
<BR>
En cas de difficult&eacute;, vous pouvez contacter votre assistance habituelle.
<br>L'&eacute;quipe d'exploitation des acc&egrave;s Internet d&rsquo;
</FONT>
</TD></TR>
</TABLE>
</blockquote>
</BODY></HTML>


Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:02
par lepiaf31
Thyphoon a écrit : parcontre pour une question de simplicité mettre une url au lieu de séparer host et le path ? ça serait pas mieux, ça permet de jouer avec les différents façon d'écrire l'url
ex:http://toto:pass@www.thyphoon.com:80
Rien n'empeche de creer une fonction parse() qui va à partir d'une URL renvoyer le login, l'host, le mot de passe et le port dans des variables différentes. Et ensuite il ne reste plus qu'a utiliser les memes fonctions qu'avant =)
Thyphoon a écrit : c'est justement la gestion des login et mot pass avec les htacess
je crois que c'est un truc du genre
POST + "Authorization: Basic "+ OutputBuffer + #CRLF$
ou le Outpufbuffer est login:pass en base64 comme pour le login et mot de passe du proxy

qu'en penses tu ?
On peut utiliser la fonction HTTP_addQueryHeader() qui permet d'ajouter un en-tete à la requete ;) (Il suffit simplement de mette 'Authorization' en name et ' Basic "+ OutputBuffer' en tant que valeur =) )

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:05
par Thyphoon
lepiaf31 a écrit : On peut utiliser la fonction HTTP_addQueryHeader() qui permet d'ajouter un en-tete à la requete ;) (Il suffit simplement de mette 'Authorization' en name et ' Basic "+ OutputBuffer' en tant que valeur =) )
le paradis !!! c'est très bien pensé tout ça !en plus elle devrait être cross-plaform !
tu devrait la proposer sur le forum anglais ! car je pense que beaucoup comme moi attendant d'avoir un tel code ! Merci beaucoup ! :mrgreen:

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:07
par lepiaf31
De rien ;) (qui aurait cru que mes cours de réseaux me serviraient si vite ^^)

@KKC: ca me parait très bizarre ^^ quel code as-tu testé ?

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:13
par Kwai chang caine
J'ai testé le dernier code de "LePiaf" avec comme port 8080 comme avait dit LePiaf :

Code : Tout sélectionner

HTTP_createQuery(@test, #HTTP_METHOD_FILE, "/test.php", "www.thyphoon.com", 8080, "proxypacsc.entreprise.fr")
Et rien ne reviens
Alors j'ai essayé avec le port 80

Code : Tout sélectionner

HTTP_createQuery(@test, #HTTP_METHOD_FILE, "/test.php", "www.thyphoon.com", 80, "proxypacsc.entreprise.fr")
et ça me retourne ça

Code : Tout sélectionner

HTTP/1.1 200 OK
Date: Tue, 28 Jun 2011 12:11:15 GMT
Server: Apache
Content-Type: text/html
Connection: close
Age: 0

POST REQUEST Ok/POST[pseudo] = lepiaf31 /POST[nom] = Kevin
 /___FILE /array(0) {
}
<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>


Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:15
par lepiaf31
J'avais mis le port 8080 mais ce n'est pas forcement celui-ci qu'il faut utiliser ^^

Par contre au vu de la réponse que tu as recu je pense que ca as marché ;)

PS: je crois qu'il y a encore un bug dans mon code (lorsqu'on envoi plusieurs fichiers ...); Je regarde ca.

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:22
par lepiaf31
Ok: bug corrigé (petit souci de retour à la ligne):

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

Procedure HTTP_sendQuery(*query.HTTP_Query)
  Protected head.s, postData.s, connection.i, size.i, fileHeaderSize.i, file.i, readed.i, *buffer
  
  ;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$
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
      
      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
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
      
      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$)*SizeOf(Character)
        size = fileHeaderSize * ListSize(*query\files())
        ForEach *query\files()
          size + Len(GetFilePart(*query\files()\path))*SizeOf(Character)
          size + Len(*query\files()\name)*SizeOf(Character)
          size + 4*SizeOf(Character)
          size + FileSize(*query\files()\path)
          size + Len("--"+*query\boundary)*SizeOf(Character)
        Next
        size + Len(postData)*SizeOf(Character)
        size + (2+Len(*query\boundary)+2)*SizeOf(Character)
        
        head + "Content-Length: "+Str(size)+#CRLF$
        head + #CRLF$
        head + postData
        SendNetworkData(connection, @head, Len(head)*SizeOf(Character))
        *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$
          SendNetworkData(connection, @postData, Len(postData)*SizeOf(Character))
          file = OpenFile(#PB_Any, *query\files()\path)
          
          If file
            While Eof(file) = 0
              readed = ReadData(file, *buffer, 2048)
              SendNetworkData(connection, *buffer, readed)
            Wend
            PokeS(*buffer, #CRLF$)
            SendNetworkData(connection, *buffer, 2*SizeOf(Character))
            CloseFile(file)
          EndIf
       Next
       FreeMemory(*buffer)
       
       postData = "--"+*query\boundary+"--"
       SendNetworkData(connection, @postData, Len(postData)*SizeOf(Character))
    EndSelect
    
    ProcedureReturn connection
  EndIf
  
  ProcedureReturn 0
EndProcedure

Procedure main()
  Protected test.HTTP_Query, string.s, readed.i, conn.i, time.i
  OpenConsole()
  InitNetwork()
  
  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", "envoi.txt")
  HTTP_addFile(@test, "datafile2", "moon.png")
  conn = HTTP_sendQuery(@test)
  
  string.s = Space(2048)
  time = ElapsedMilliseconds()
  Repeat
    If NetworkClientEvent(conn) = #PB_NetworkEvent_Data
      readed = ReceiveNetworkData(conn, @string, 2048)
      Print(Left(string, readed))
      time = ElapsedMilliseconds()
    EndIf
    Delay(100)
  Until ElapsedMilliseconds() - time >= 3000
  Input()
EndProcedure

main()

Re: Envoi de fichier par requête Http Post

Publié : mar. 28/juin/2011 13:26
par Kwai chang caine
J'avais mis le port 8080 mais ce n'est pas forcement celui-ci qu'il faut utiliser ^^
Par contre au vu de la réponse que tu as recu je pense que ca as marché
D'accord merci LePiaf 8)

Par contre j'suis désolé d'etre un gros lourd, mais j'ai toujours pas trouvé ou etait le fichier dans ce fameux TMP du serveur

J'ai créé a la racine de ton code un fichier "envoi.txt" ou j'ai mis du texte dedans, je ne sais pas si c'etait ce qu'il fallait faire.
Et apres, je comprend plus rien :oops: