CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Update on 1.30 (2019-01-13) - The file parameters are now placed at the end of the retData
Update on 1.30 (2019-01-13) - The file parameters are now placed at the end of the retData
There was an api that requires the file parameter to be the last part of the body, so I made that changes to the script. I found it also helps HTTP Debugger to display the multipart body as plain text instead of hex when the file parameter is in the middle of the body.
There was an api that requires the file parameter to be the last part of the body, so I made that changes to the script. I found it also helps HTTP Debugger to display the multipart body as plain text instead of hex when the file parameter is in the middle of the body.
-
- Posts: 104
- Joined: 07 Aug 2015, 15:53
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Cant get the value of upload[1] or 2??
Code: Select all
objParam := { "btSubmit": "Upload It!"
, "adult": "no"
, "mode": "local"
, "forumurl": "http://postimage.org/"
, "upload[]": ["2.png", "1.png"]
, "um": "computer"
, "MAX_FILE_SIZE": 16777216
, "optsize": 0 }
MsgBox % objParam["upload"][1]
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Hi, use MsgBox % objParam["upload[]"][1]
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
How can we make SafeArray for big files - more than 1GB with ahk32 bit running on Win 64bit?
Just for test I wrote code which uploads file on https://files.fm.
It works fine on ahk64 bit, but dont work on ahk32 bit.
As I understand that is because of 32-bit processes have a 2 GB RAM limit.
But I can upload big files with any browser 32 bit.
How browser converts file to SafeArray?
Here is example of error:
Script of upload to https://files.fm with ByteArray function:
Just for test I wrote code which uploads file on https://files.fm.
It works fine on ahk64 bit, but dont work on ahk32 bit.
As I understand that is because of 32-bit processes have a 2 GB RAM limit.
But I can upload big files with any browser 32 bit.
How browser converts file to SafeArray?
Here is example of error:
Code: Select all
oADO := ComObjCreate("ADODB.Stream")
oADO.Type := 1 ; adTypeBinary
oADO.Open
oADO.LoadFromFile("D:\1gb.mp4")
oADO.Read
oADO.Close
msgbox ok
Code: Select all
path := "D:\1GB.mp4"
HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
HTTP.Open("GET", "https://files.fm", true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send()
HTTP.WaitForResponse()
RegexMatch(HTTP.ResponseText, "s)PHPSESSID=(.+?)"".+?strCurrentUploadCallServer = '(.+?)\.", match)
phpsessid := match1
HTTP.Open("GET", "https://files.fm/server_scripts/get_upload_id.php?show_add_key=1", true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send()
HTTP.WaitForResponse()
RegexMatch(HTTP.ResponseText, "s)(.+?),.+?,(.+?)$", match)
up_id := match1, key := match2
now := A_NowUTC
EnvSub, now,1970, seconds
now .= A_MSec
objParam := {Filedata: [path]}
CreateFormData(PostData, hdr_ContentType, objParam)
HTTP.SetTimeouts(0, 0, 0, 0)
HTTP.Open("POST", "https://free.files.fm/save_file.php?PHPSESSID=" phpsessid "&up_id=" up_id "&ignore_user_abort=1&skip_update=1&key=" key "&v=" now, true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.SetRequestHeader("Content-Type", hdr_ContentType)
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send(PostData)
HTTP.WaitForResponse()
uploadedLink := "https://files.fm/u/" up_id
; test of uploading file
HTTP.SetTimeouts(0, 60000, 30000, 30000)
HTTP.Open("GET", uploadedLink, true)
HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
HTTP.SetRequestHeader("Pragma", "no-cache")
HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store")
HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
HTTP.Send()
HTTP.WaitForResponse()
if InStr(HTTP.ResponseText, "tools_button_download")
msgbox % clipboard := uploadedLink
else
msgbox Error
return
; CreateFormData() by tmplinshi, AHK Topic: https://autohotkey.com/boards/viewtopic.php?t=7647
; Thanks to Coco: https://autohotkey.com/boards/viewtopic.php?p=41731#p41731
; Modified version by SKAN, 09/May/2016
CreateFormData(ByRef retData, ByRef retHeader, objParam) {
New CreateFormData(retData, retHeader, objParam)
}
Class CreateFormData {
__New(ByRef retData, ByRef retHeader, objParam) {
Local CRLF := "`r`n", i, k, v, str, pvData
; Create a random Boundary
Local Boundary := this.RandomBoundary()
Local BoundaryLine := "------------------------------" . Boundary
this.Len := 0 ; GMEM_ZEROINIT|GMEM_FIXED = 0x40
this.Ptr := DllCall( "GlobalAlloc", "UInt",0x40, "UInt",1, "Ptr" ) ; allocate global memory
; Loop input paramters
For k, v in objParam
{
If IsObject(v) {
For i, FileName in v
{
str := BoundaryLine . CRLF
. "Content-Disposition: form-data; name=""" . k . """; filename=""" . FileName . """" . CRLF
. "Content-Type: " . this.MimeType(FileName) . CRLF . CRLF
this.StrPutUTF8( str )
this.LoadFromFile( Filename )
this.StrPutUTF8( CRLF )
}
} Else {
str := BoundaryLine . CRLF
. "Content-Disposition: form-data; name=""" . k """" . CRLF . CRLF
. v . CRLF
this.StrPutUTF8( str )
}
}
this.StrPutUTF8( BoundaryLine . "--" . CRLF )
; Create a bytearray and copy data in to it.
retData := ComObjArray( 0x11, this.Len ) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
pvData := NumGet( ComObjValue( retData ) + 8 + A_PtrSize )
DllCall( "RtlMoveMemory", "Ptr",pvData, "Ptr",this.Ptr, "Ptr",this.Len )
this.Ptr := DllCall( "GlobalFree", "Ptr",this.Ptr, "Ptr" ) ; free global memory
retHeader := "multipart/form-data; boundary=----------------------------" . Boundary
}
StrPutUTF8( str ) {
Local ReqSz := StrPut( str, "utf-8" ) - 1
this.Len += ReqSz ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42
this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len + 1, "UInt", 0x42 )
StrPut( str, this.Ptr + this.len - ReqSz, ReqSz, "utf-8" )
}
LoadFromFile( Filename ) {
Local objFile := FileOpen( FileName, "r" )
this.Len += objFile.Length ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42
this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len, "UInt", 0x42 )
objFile.RawRead( this.Ptr + this.Len - objFile.length, objFile.length )
objFile.Close()
}
RandomBoundary() {
str := "0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"
Sort, str, D| Random
str := StrReplace(str, "|")
Return SubStr(str, 1, 12)
}
MimeType(FileName) {
n := FileOpen(FileName, "r").ReadUInt()
Return (n = 0x474E5089) ? "image/png"
: (n = 0x38464947) ? "image/gif"
: (n&0xFFFF = 0x4D42 ) ? "image/bmp"
: (n&0xFFFF = 0xD8FF ) ? "image/jpeg"
: (n&0xFFFF = 0x4949 ) ? "image/tiff"
: (n&0xFFFF = 0x4D4D ) ? "image/tiff"
: "application/octet-stream"
}
}
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
I wonder if the undocumented ConvertAndEscapePostData function from mshtml.dll would help.
https://www.geoffchappell.com/studies/windows/ie/mshtml/api/index.htm
https://www.geoffchappell.com/studies/windows/ie/mshtml/api/index.htm
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
hi,i want to know how to check the website form parameters? I just can not find it.
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
You can check them, in chrome network log, for example.
-
- Posts: 95
- Joined: 13 Sep 2021, 06:08
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Anyone know how i can make this requisition with ahk?
It's a form-data to send xml with two content-type inside a body
![Image](https://i.imgur.com/4d07w7o.png)
It's a form-data to send xml with two content-type inside a body
![Image](https://i.imgur.com/4d07w7o.png)
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Read 1 post example and do the same.
-
- Posts: 95
- Joined: 13 Sep 2021, 06:08
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Then You did it incorrect.
You need to send 2 parameters in body.
file[] and query.
You need to send 2 parameters in body.
file[] and query.
-
- Posts: 95
- Joined: 13 Sep 2021, 06:08
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
I'm trying, like this.
But dont work.
Code: Select all
; ###############################################################################################
TokenValidador := "mytoken"
BearerValidador := "mybearer"
File := "C:\Users\Thales\Desktop\TESTES\1.XML"
FileRead, BOXE, C:\Users\Thales\Desktop\TESTES\boxe.txt
FileRead, ARQ, C:\Users\Thales\Desktop\TESTES\arq.txt
URL := "https://api.onvio.com.br/dominio/invoice/v3/batches"
SendXMLAPI := ComObjCreate("WinHttp.WinHttpRequest.5.1")
SendXMLAPI.Open("POST", URL , False)
SendXMLAPI.SetRequestHeader("x-integration-key", TokenValidador)
SendXMLAPI.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)")
SendXMLAPI.SetRequestHeader("Authorization","Bearer " BearerValidador)
objParam := { "file[]": ARQ
, "query": BOXE }
CreateFormData(PostData, Header, objParam)
SendXMLAPI.Send(PostData)
Result := SendXMLAPI.ResponseText
Status := SendXMLAPI.Status
Gui, Add, Edit, w500 r10, 3 - Result: %Result%
Gui, Show
return
Guiclose:
ExitApp
{"error":{"code":500,"errors":[],"message":"HTTP 415 Unsupported Media Type"}}
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
You do it wrong, and I am too lazy to do it instead of You.
You need to understand how 1 example in this topic works and do the same.
You need to understand how 1 example in this topic works and do the same.
-
- Posts: 95
- Joined: 13 Sep 2021, 06:08
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
I do not see Your code.
-
- Posts: 95
- Joined: 13 Sep 2021, 06:08
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
There is
Code: Select all
; ###############################################################################################
TokenValidador := "mytoken"
BearerValidador := "mybearer"
File := "C:\Users\Thales\Desktop\TESTES\1.XML"
FileRead, BOXE, C:\Users\Thales\Desktop\TESTES\boxe.txt
FileRead, ARQ, C:\Users\Thales\Desktop\TESTES\arq.txt
URL := "https://api.onvio.com.br/dominio/invoice/v3/batches"
SendXMLAPI := ComObjCreate("WinHttp.WinHttpRequest.5.1")
SendXMLAPI.Open("POST", URL , False)
SendXMLAPI.SetRequestHeader("x-integration-key", TokenValidador)
SendXMLAPI.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)")
SendXMLAPI.SetRequestHeader("Authorization","Bearer " BearerValidador)
objParam := { "file[]": ARQ
, "query": BOXE }
CreateFormData(PostData, Header, objParam)
SendXMLAPI.Send(PostData)
Result := SendXMLAPI.ResponseText
Status := SendXMLAPI.Status
Gui, Add, Edit, w500 r10, 3 - Result: %Result%
Gui, Show
return
Guiclose:
ExitApp
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Are You kidding?
How I can know what You put at
How I can know what You put at
Code: Select all
FileRead, BOXE, C:\Users\Thales\Desktop\TESTES\boxe.txt
FileRead, ARQ, C:\Users\Thales\Desktop\TESTES\arq.txt
-
- Posts: 95
- Joined: 13 Sep 2021, 06:08
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
I'm sorry.malcev wrote: ↑11 Dec 2021, 15:26Are You kidding?
How I can know what You put atCode: Select all
FileRead, BOXE, C:\Users\Thales\Desktop\TESTES\boxe.txt FileRead, ARQ, C:\Users\Thales\Desktop\TESTES\arq.txt
That's the contents in the files.
BOXE.TXT
Code: Select all
{"boxe/File": false}
Code: Select all
C:\Users\Thales\Desktop\TESTES\1.XML
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Files You need send as objects.
Because function CreateFormData checks if value of key is object or not and depending of it adds it to body with different ways.
https://gist.github.com/tmplinshi/8428a280bba58d25ef0b#file-createformdata-ahk-L52
Code: Select all
"upload[]": ["2.png", "1.png"]
https://gist.github.com/tmplinshi/8428a280bba58d25ef0b#file-createformdata-ahk-L52
-
- Posts: 95
- Joined: 13 Sep 2021, 06:08
Re: CreateFormData - Create "multipart/form-data" for http post (Updated:2019-01-13)
Dont work
, but thanks for the help, i will try in other moment
![Sad :(](./images/smilies/icon_e_sad.gif)