Page 1 sur 1
[R] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : lun. 23 mars 2009 05:23
par orax
Edité : le problème est en partie résolu, j'envoie la requête avec TCPSend(), en "brute", et ça marche, mais j'aurais bien aimé pouvoir faire ça simplement avec un objet tel que WinHttpRequest par exemple.
- - - -
Bonjour, j'aimerais héberger une image sur site qui propose ce service, tel que imageshack ou autres...
Pour l'exemple j'utilise WinHttpRequest pour envoyer ma requête POST dans laquelle est contenu mon image.
Le problème est que mon image n'est pas envoyée correctement, il n'y a que les premiers octets (moins de 10 octets je pense) qui sont envoyés (j'ai vérifié avec Wireshark). Je ne vois vraiment pas ce que j'ai mal fait.
Merci de m'éclairer un peu si vous avez une idée.
► Afficher le textecode
Code : Tout sélectionner
#include <IE.au3>
Local Const $boundary = '-----------------------------570623639010'
Local $contenuFichier = FileRead("IMG.png")
Local $obj = ObjCreate("WinHttp.WinHttpRequest.5.1")
;~ Local $obj=ObjCreate("Microsoft.XMLHTTP")
;~ Local $obj=ObjCreate("Msxml2.XMLHTTP")
$obj.open("POST", "http://www.ptp-images.com/image-uploade.html")
$obj.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 (.NET CLR 3.5.30729)")
$obj.SetRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
$obj.SetRequestHeader("Accept-Language", "fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3")
$obj.SetRequestHeader("Accept-Encoding", "gzip,deflate")
$obj.SetRequestHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
$obj.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" & $boundary)
$obj.Send('--' & $boundary & @CRLF & _
'Content-Disposition: form-data; name="fichier"; filename="IMG.png"' & @CRLF & _
'Content-Type: image/png' & @CRLF & @CRLF & _
$contenuFichier & _
@CRLF & '--' & $boundary & @CRLF & _
'Content-Disposition: form-data; name="email"' & @CRLF & @CRLF & _
@CRLF & '--' & $boundary & '--' & @CRLF)
; pour voir le résultat de la réponse
$oIE = _IECreate("google.fr")
_IEDocWriteHTML($oIE, $obj.StatusText & @CRLF & $obj.ResponseText)
Et voici ce que m'affiche Wireshark :
► Afficher le textecapture de trames
Code : Tout sélectionner
0000 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d ----------------
0010 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 31 ---------------1
0020 32 31 36 34 32 35 35 34 32 37 36 31 39 0d 0a 43 2164255427619..C
0030 6f 6e 74 65 6e 74 2d 44 69 73 70 6f 73 69 74 69 ontent-Dispositi
0040 6f 6e 3a 20 66 6f 72 6d 2d 64 61 74 61 3b 20 6e on: form-data; n
0050 61 6d 65 3d 22 66 69 63 68 69 65 72 22 3b 20 66 ame="fichier"; f
0060 69 6c 65 6e 61 6d 65 3d 22 49 4d 47 2e 70 6e 67 ilename="IMG.png
0070 22 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a "..Content-Type:
0080 20 69 6d 61 67 65 2f 70 6e 67 0d 0a 0d 0a [color=#FF0000]e2 80[/color] image/png...... [color=#00FF00]; début du contenu de mon image[/color]
0090 [color=#FF0000]b0 50 4e 47 0d 0a 1a 0a[/color] .PNG.... [color=#00FF00]; et il n'y a pas la suite de mon image[/color]
Re: [..] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : lun. 23 mars 2009 16:36
par Max5
En essayant le code avec l'objet "WinHttp.WinHttpRequest.5.1" j'obtient :
Bad Request
Bad Request
Your browser sent a request that this server could not understand.
Mais avec L'objet "Microsoft.XMLHTTP" c'est bon.

En tout cas chez moi. ^^
J'ai remarquer par expérience que xmlhttp est préférable a winhttprequest.

Re: [..] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : lun. 23 mars 2009 17:17
par orax
Le Bad request c'est de ma faute, j'avais oublié d'enlever cette ligne mal formée
Code : Tout sélectionner
$obj.SetRequestHeader("Host", "Host: http://www.ptp-images.com")
Je vais tester "Microsoft.XMLHTTP". Merci !
- - - - - -
Au fait, rien avoir avec le sujet, et le problème est peut-être déjà connu : j'ai remarqué que quand je mets, par exemple, about:blank entre les balises "[ code ]" ça me donne ça :
Re: [..] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : lun. 23 mars 2009 21:49
par orax
Avec Microsoft.XMLHTTP, j'ai le même problème, il ne m'envoie que les 10 premiers octets de l'image. Il semblerait que pour envoyer un fichier binaire avec Microsoft.XMLHTTP je doive faire autrement.
J'ai essayé d'envoyer une requête via TCPSend() pour être certain que le problème ne provienne pas d'une simple erreur de syntaxe, et là ça marche, même si ça ne résout pas pour autant mon problème avec Microsoft.XMLHTTP. Le code est ci-dessous, il permet de faire les 2 types d'envoie.
► Afficher le textecode
Code : Tout sélectionner
#include <IE.au3>
Local $a
$a = 0 ; envoie via TCPSend()
;~ $a=1 ; envoie via l'objet
$a = 2 ; envoie via via TCPSend() et l'objet
Local Const $hote = "www.ptp-images.com"
Local $contenuFichier = FileRead("IMG.png")
Local Const $boundary = '---------------------------570623639010'
Local $contenu = '--' & $boundary & @CRLF & _
'Content-Disposition: form-data; name="fichier"; filename="IMG.png"' & @CRLF & _
'Content-Type: image/png' & @CRLF & @CRLF & _
$contenuFichier & _
@CRLF & '--' & $boundary & @CRLF & _
'Content-Disposition: form-data; name="email"' & @CRLF & @CRLF & _
@CRLF & '--' & $boundary & '--' & @CRLF
If $a = 0 Or $a = "" Or $a = 2 Then
TCPStartup()
$s = TCPConnect(TCPNameToIP($hote), 80)
TCPSend($s, 'POST /image-uploade.html HTTP/1.1' & @CRLF & _
'Host: ' & $hote & @CRLF & _
'User-Agent: Mozilla/5.0' & @CRLF & _
'Accept-Encoding:' & @CRLF & _
'Connection: Close' & @CRLF & _
'Referer: http://www.ptp-images.com/image-uploade.html' & @CRLF & _
'Content-Type: multipart/form-data; boundary=' & $boundary & @CRLF & _
'Content-Length: ' & StringLen($contenu) & @CRLF & @CRLF & _
$contenu)
Local $recv = ""
While 1
$recv &= TCPRecv($s, 2048)
If @error Then ExitLoop
Sleep(5)
WEnd
$oIE = _IECreate("about:blank")
_IEDocWriteHTML($oIE, $recv) ; le fichier envoyé est bien envoyé en totalité puisqu'il est visible sur la page
EndIf
;~ * * * * * * * * * * * * * * * * * * * * * * * * * * *
If $a = 1 Or $a = 2 Then
Local $obj = ObjCreate("Microsoft.XMLHTTP")
;~ Local $obj=ObjCreate("Msxml2.XMLHTTP")
;~ Local $obj = ObjCreate("WinHttp.WinHttpRequest.5.1")
$obj.open("POST", "http://www.ptp-images.com/image-uploade.html")
$obj.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" & $boundary)
$obj.Send($contenu)
$oIE = _IECreate("about:blank")
_IEDocWriteHTML($oIE, $obj.ResponseText) ; l'envoie du fichier semble réussi mais en réalité, seul 10 octets du fichiers ont été envoyés
EndIf
Re: [..] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : lun. 23 mars 2009 23:33
par orax
Finalement j'ai trouvé un script VBS qui fait ce que je demande à
http://www.nowsms.com/download/sendmms.vbs.txt ; il est conçu pour envoyer des mms alors je l'ai un peu modifié. Par contre je trouve qu'il est bien compliqué pour le simple envoie d'un fichier binaire... je m'attendais à plus simple donc si quelqu'un a une autre solution je suis prenant.
► Afficher le textevbs
Code : Tout sélectionner
' http://www.nowsms.com/download/sendmms.vbs.txt
Const DEST_URL = "http://www.ptp-images.com/image-uploade.html"
Const REPERTOIRE_FICHIER = "D:\"
Const NOM_FICHIER = "IMG.png"
envoieFichier()
Sub envoieFichier()
Dim FileContents
Dim FileName, FieldName
Dim FormData
Dim aCounter, Arg
Dim fso
FormData = ""
FieldName = "fichier" 'Variable name for file upload
'Define MIME Boundary
Const Boundary = "---------------------------NowSMS---VBScript---Boundary----"
Arg=REPERTOIRE_FICHIER + NOM_FICHIER
'Get source file As a binary data.
FileContents = GetFile(Arg)
'Build multipart/form-data document
FormData = AppendBinary (FormData, AddFileToFormData(FileContents, Boundary, NOM_FICHIER, FieldName))
'close the multipart MIME
FormData = AppendBinary (FormData, CloseFormData (Boundary))
'Post the data To the destination URL
Set objHTML = CreateObject("InternetExplorer.Application")
objHTML.Navigate ("about:blank")
objHTML.document.Write(WinHttpPostRequest (DEST_URL, FormData, Boundary))
objHTML.document.close()
objHTML.Visible=true
End Sub
'Combine 2 binary strings into 1
Function AppendBinary(binary1, binary2)
Dim BinaryData
'Build form data using recordset binary field
Const adLongVarBinary = 205
Dim RS: Set RS = CreateObject("ADODB.Recordset")
RS.Fields.Append "b", adLongVarBinary, LenB(binary1) + LenB(binary2)
RS.Open
RS.AddNew
Dim LenData
RS("b").AppendChunk (binary1)
RS("b").AppendChunk (binary2)
RS.Update
BinaryData = RS("b")
RS.Close
AppendBinary = BinaryData
End Function
'Add a file to a multipart/form-data document
Function AddFileToFormData(FileContents, Boundary, FileName, FieldName)
Dim FormData, Pre, Po
Const ContentType = "image/png"
'The two parts around file contents In the multipart-form data.
Pre = "--" + Boundary + vbCrLf + mpFields(FieldName, FileName, ContentType)
Po = vbCrLf
'Build form data using recordset binary field
Const adLongVarBinary = 205
Dim RS: Set RS = CreateObject("ADODB.Recordset")
RS.Fields.Append "b", adLongVarBinary, Len(Pre) + LenB(FileContents) + Len(Po)
RS.Open
RS.AddNew
Dim LenData
'Convert Pre string value To a binary data
LenData = Len(Pre)
RS("b").AppendChunk (StringToMB(Pre) & ChrB(0))
Pre = RS("b").GetChunk(LenData)
RS("b") = ""
'Convert Po string value To a binary data
LenData = Len(Po)
RS("b").AppendChunk (StringToMB(Po) & ChrB(0))
Po = RS("b").GetChunk(LenData)
RS("b") = ""
'Join Pre + FileContents + Po binary data
RS("b").AppendChunk (Pre)
RS("b").AppendChunk (FileContents)
RS("b").AppendChunk (Po)
RS.Update
FormData = RS("b")
RS.Close
AddFileToFormData = FormData
End Function
'Add a variable to multipart/form-data document
Function AddVarToFormData(Boundary, varName, varValue)
Dim FormData, Pre, Po, binValue
'The two parts around file contents In the multipart-form data.
Pre = "--" + Boundary + vbCrLf + mpFields2(varName)
Po = vbCrLf
'Build form data using recordset binary field
Const adLongVarBinary = 205
Dim RS: Set RS = CreateObject("ADODB.Recordset")
RS.Fields.Append "b", adLongVarBinary, Len(Pre) + Len(varValue) + Len(Po)
RS.Open
RS.AddNew
Dim LenData
'Convert Pre string value To a binary data
LenData = Len(Pre)
RS("b").AppendChunk (StringToMB(Pre) & ChrB(0))
Pre = RS("b").GetChunk(LenData)
RS("b") = ""
'Convert varValue string value To a binary data
LenData = Len(varValue)
RS("b").AppendChunk (StringToMB(varValue) & ChrB(0))
binValue = RS("b").GetChunk(LenData)
RS("b") = ""
'Convert Po string value To a binary data
LenData = Len(Po)
RS("b").AppendChunk (StringToMB(Po) & ChrB(0))
Po = RS("b").GetChunk(LenData)
RS("b") = ""
'Join Pre + FileContents + Po binary data
RS("b").AppendChunk (Pre)
RS("b").AppendChunk (binValue)
RS("b").AppendChunk (Po)
RS.Update
FormData = RS("b")
RS.Close
AddVarToFormData = FormData
End Function
'Close multipart/form-data document with final boundary
Function CloseFormData(Boundary)
Dim FormData, Po
Po = "--" + Boundary + "--" + vbCrLf
'Build form data using recordset binary field
Const adLongVarBinary = 205
Dim RS: Set RS = CreateObject("ADODB.Recordset")
RS.Fields.Append "b", adLongVarBinary, Len(Po)
RS.Open
RS.AddNew
Dim LenData
'Convert Po string value To a binary data
LenData = Len(Po)
RS("b").AppendChunk (StringToMB(Po) & ChrB(0))
Po = RS("b").GetChunk(LenData)
RS("b") = ""
'Join Pre + FileContents + Po binary data
RS("b").AppendChunk (Po)
RS.Update
FormData = RS("b")
RS.Close
CloseFormData = FormData
End Function
'Infrormations In form field header.
Function mpFields(FieldName, FileName, ContentType)
Dim MPTemplate 'template For multipart header
MPTemplate = "Content-Disposition: form-data; name=""{field}"";" + _
" filename=""{file}""" + vbCrLf + _
"Content-Type: {ct}" + vbCrLf + vbCrLf
Dim Out
Out = Replace(MPTemplate, "{field}", FieldName)
Out = Replace(Out, "{file}", FileName)
mpFields = Replace(Out, "{ct}", ContentType)
End Function
'Infrormations In form field header.
Function mpFields2(FieldName)
Dim MPTemplate 'template For multipart header
MPTemplate = "Content-Disposition: form-data; name=""{field}""" + vbCrLf + vbCrLf
mpFields2 = Replace(MPTemplate, "{field}", FieldName)
End Function
'Returns file contents As a binary data
Function GetFile(FileName)
Dim Stream: Set Stream = CreateObject("ADODB.Stream")
Stream.Type = 1 'Binary
Stream.Open
Stream.LoadFromFile FileName
GetFile = Stream.Read
Stream.Close
End Function
'Converts OLE string To multibyte string
Function StringToMB(S)
Dim I, B
For I = 1 To Len(S)
B = B & ChrB(Asc(Mid(S, I, 1)))
Next
StringToMB = B
End Function
'sends multipart/form-data To the URL using WinHttprequest/XMLHTTP
'FormData - binary (VT_UI1 | VT_ARRAY) multipart form data
Function WinHTTPPostRequest(URL, FormData, Boundary)
Dim http
'Create XMLHTTP/ServerXMLHTTP/WinHttprequest object
'You can use any of these three objects.
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
'Set http = CreateObject("Msxml2.XMLHTTP")
'Set http = CreateObject("MSXML2.ServerXMLHTTP")
'Open URL As POST request
http.Open "POST", URL, False
'Set Content-Type header
http.setRequestHeader "Content-Type", "multipart/form-data; boundary=" + Boundary
'Send the form data To URL As POST binary request
http.send FormData
'Get a result of the script which has received upload
WinHTTPPostRequest = http.responseText
End Function
Re: [R] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : mar. 14 avr. 2009 19:24
par GaRydelaMer
Bonjour
j'ai apporté une solution à ton problème, tu la trouvera dans les exemples de script.
http://www.autoitscript.fr/forum/viewto ... f=6&t=2747
Chris.
Re: [R] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : mar. 14 avr. 2009 19:32
par orax
Oui en effet, je venais à l'instant de voir le message. Je n'ai pas encore testé mais ça me semble parfait. Merci
Juste une petite chose : (si j'ai bien compris la RFC) si la valeur de boundary (Const $BOUNDARY = '--ThIs_Is_tHe_bouNdaRY_$--') est présente dans le fichier, le transfert va échouer

(...bon d'accord, il y a une chance sur 1 000 000 000... pour que ça arrive).
Re: [R] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : mer. 15 avr. 2009 09:15
par Artemis
Merci pour toutes vos réponses, j'ai du boulot :p
Artemis

Re: [R] Problème pour envoyer un fichier - (Méthode HTTP POST)
Posté : mer. 15 avr. 2009 17:43
par GaRydelaMer
orax a écrit :Oui en effet, je venais à l'instant de voir le message. Je n'ai pas encore testé mais ça me semble parfait. Merci
Juste une petite chose : (si j'ai bien compris la RFC) si la valeur de boundary (Const $BOUNDARY = '--ThIs_Is_tHe_bouNdaRY_$--') est présente dans le fichier, le transfert va échouer

(...bon d'accord, il y a une chance sur 1 000 000 000... pour que ça arrive).
Non pas vraiment puisque le fichier est codé en binaire tu auras jamais cette chaine la
