WinHttp post request

Get help with using AutoHotkey and its commands and hotkeys
c7aesa7r
Posts: 43
Joined: 02 Jun 2016, 21:09

WinHttp post request

05 Feb 2020, 07:10

I have found this script bellow to send get Winhttp request, would like to ask for help in how i could use it to send a post request, like:

/api/item/write
So in the body:
{ "species": "value", "name": "item name", "quantity": 300 }

Code: Select all

getWebPage("https granblue.herokuapp.com /api/item/write/collection/550")  Broken Link for safety

;=========== get the content of a webpage into a variable
getWebPage(url, postdata :="")
{
    Static whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")    ; Static will make it use the same object in memory
    whr.Open((postdata?"Post":"Get"), url, true)                ; Post or Get depending if postdata is submitted
    whr.SetTimeouts("30000", "30000", "30000", "30000")         ; timeout 30 seconds

    if (StrLen(postdata)>0)
    {
        whr.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
        whr.Send(postdata)
    }
    else
    {
        whr.Send()
    }
    whr.WaitForResponse()
    Return whr.ResponseText
}
User avatar
Masonjar13
Posts: 1514
Joined: 20 Jul 2014, 10:16
GitHub: Masonjar13
Location: Не Россия

Re: WinHttp post request

05 Feb 2020, 10:31

You need to create and send the form data (param 2). You can use this to build your data: https://gist.github.com/tmplinshi/8428a280bba58d25ef0b
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
c7aesa7r
Posts: 43
Joined: 02 Jun 2016, 21:09

Re: WinHttp post request

05 Feb 2020, 17:16

hi @Masonjar13

Code: Select all

; 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

whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("POST", "https  site  /api/item/write/",  Broken Link for safety true)

objParam := { "species": "bird"
            , "name": "cana"
            , "quantity": 5 }

CreateFormData(PostData, hdr_ContentType, objParam)

whr.SetRequestHeader("Content-Type", hdr_ContentType)
whr.SetRequestHeader("Referer", "https    site      /api/item/write/")  Broken Link for safety
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0")
whr.Option(6) := False ; No auto redirect
whr.Send(PostData)
whr.WaitForResponse()
;Run, % "https black-desert-notifier.herokuapp.com /api/item/write/"  Broken Link for safety . whr.GetResponseHeader("Location")


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"
	}

}

I followed the example on the link you post, but I'm not receiving anything on my site
User avatar
Masonjar13
Posts: 1514
Joined: 20 Jul 2014, 10:16
GitHub: Masonjar13
Location: Не Россия

Re: WinHttp post request

05 Feb 2020, 17:25

Looks correct. Have you checked your server logs? Did you see a connection, possibly failed? You may need to authenticate first, or open your endpoint to the public. Potentially, you could also be timing out (though this should throw an error on AHK). You can use whr.setTimeouts() to alter those, if needed.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
tmplinshi
Posts: 1561
Joined: 01 Oct 2013, 14:57

Re: WinHttp post request

06 Feb 2020, 23:23

There are mainly 3 types of POST data.
  1. application/x-www-form-urlencoded
    example body: name=admin&shoesize=12
  2. application/json
    example body: {"name":"admin", "shoesize":12}
  3. multipart/form-data
    It's normally used for uploading binary file. CreateFormData is only used for this type.
The body is a json string, so it should be application/json.

Code: Select all

whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("POST", "https://granblue.herokuapp.com/api/item/write")
whr.SetRequestHeader("Content-Type", "application/json")
body = {"species": "value", "name": "item name", "quantity": 300}
whr.Send(body)
MsgBox % whr.ResponseText

Return to “Ask For Help”

Who is online

Users browsing this forum: AHKStudent, anhnha, Bacon19331, Bing [Bot], casperharkin, Google [Bot], littlegandhi1199, Marius I, stiuna, Xeo786 and 45 guests