HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Sabestian Caine
Posts: 528
Joined: 12 Apr 2015, 03:53

HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

14 Jul 2019, 02:34

Hello friends..

I want to get full html codes from https://cmyip.com/ as shown in this video-
https://www.youtube.com/watch?v=wTYhMgZNB8M&t=243s

for this i tried to use these codes-

Code: Select all

httpQuery(url, "https://cmyip.com/")
VarSetCapacity(url,-1)
MsgBox % url


; Below, there is httpQuery Function's codes




































































































; httpQuery-0-3-5.ahk
; httpQuery GET and POST requests by DerRaphael
; http://www.autohotkey.com/forum/topic33506.html
httpQuery(byref Result, lpszUrl, POSTDATA="", HEADERS="")
{   ; v0.3.5 (w) Sep, 8 2008 by Heresy & derRaphael / zLib-Style release
   ; updates Aug, 28 2008   
   ; currently the verbs showHeader, storeHeader, and updateSize are supported in httpQueryOps
   ; in case u need a different UserAgent, Proxy, ProxyByPass, Referrer, and AcceptType just
   ; specify them as global variables - mind the varname for referrer is httpQueryReferer [sic].
   ; Also if any special dwFlags are needed such as INTERNET_FLAG_NO_AUTO_REDIRECT or cache
   ; handling this might be set using the httpQueryDwFlags variable as global
	global httpQueryOps, httpAgent, httpProxy, httpProxyByPass, httpQueryReferer, httpQueryAcceptType
       , httpQueryDwFlags
   ; Get any missing default Values
	defaultOps =
   (LTrim Join|
      httpAgent=AutoHotkeyScript|httpProxy=0|httpProxyByPass=0|INTERNET_FLAG_SECURE=0x00800000
      SECURITY_FLAG_IGNORE_UNKNOWN_CA=0x00000100|SECURITY_FLAG_IGNORE_CERT_CN_INVALID=0x00001000
      SECURITY_FLAG_IGNORE_CERT_DATE_INVALID=0x00002000|SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE=0x00000200
      INTERNET_OPEN_TYPE_PROXY=3|INTERNET_OPEN_TYPE_DIRECT=1|INTERNET_SERVICE_HTTP=3
   )
	Loop,Parse,defaultOps,|
	{
		RegExMatch(A_LoopField,"(?P<Option>[^=]+)=(?P<Default>.*)",http)
		if StrLen(%httpOption%)=0
			%httpOption% := httpDefault
	}
	
   ; Load Library
	hModule := DllCall("LoadLibrary", "Str", "WinINet.Dll")
	
   ; SetUpStructures for URL_COMPONENTS / needed for InternetCrackURL
   ; http://msdn.microsoft.com/en-us/library/aa385420(VS.85).aspx
	offset_name_length:= "4-lpszScheme-255|16-lpszHostName-1024|28-lpszUserName-1024|"
                  . "36-lpszPassword-1024|44-lpszUrlPath-1024|52-lpszExtrainfo-1024"
	VarSetCapacity(URL_COMPONENTS,60,0)
   ; Struc Size               ; Scheme Size                  ; Max Port Number
	NumPut(60,URL_COMPONENTS,0), NumPut(255,URL_COMPONENTS,12), NumPut(0xffff,URL_COMPONENTS,24)
	
	Loop,Parse,offset_name_length,|
	{
		RegExMatch(A_LoopField,"(?P<Offset>\d+)-(?P<Name>[a-zA-Z]+)-(?P<Size>\d+)",iCU_)
		VarSetCapacity(%iCU_Name%,iCU_Size,0)
		NumPut(&%iCU_Name%,URL_COMPONENTS,iCU_Offset)
		NumPut(iCU_Size,URL_COMPONENTS,iCU_Offset+4)
	}
	
   ; Split the given URL; extract scheme, user, pass, authotity (host), port, path, and query (extrainfo)
   ; http://msdn.microsoft.com/en-us/library/aa384376(VS.85).aspx
	DllCall("WinINet\InternetCrackUrlA","Str",lpszUrl,"uInt",StrLen(lpszUrl),"uInt",0,"uInt",&URL_COMPONENTS)
	
   ; Update variables to retrieve results
	Loop,Parse,offset_name_length,|
	{
		RegExMatch(A_LoopField,"-(?P<Name>[a-zA-Z]+)-",iCU_)
		VarSetCapacity(%iCU_Name%,-1)
	}
	nPort:=NumGet(URL_COMPONENTS,24,"uInt")
	
   ; Import any set dwFlags
	dwFlags := httpQueryDwFlags
   ; For some reasons using a selfsigned https certificates doesnt work
   ; such as an own webmin service - even though every security is turned off
   ; https with valid certificates works when
	if (lpszScheme = "https")
		dwFlags |= (INTERNET_FLAG_SECURE|SECURITY_FLAG_IGNORE_CERT_CN_INVALID
	|SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE)
	
   ; Check for Header and drop exception if unknown or invalid URL
	if (lpszScheme="unknown") {
		Result := "ERR: No Valid URL supplied."
		Return StrLen(Result)
	}
	
   ; Initialise httpQuery's use of the WinINet functions.
   ; http://msdn.microsoft.com/en-us/library/aa385096(VS.85).aspx
	hInternet := DllCall("WinINet\InternetOpenA"
                  ,"Str",httpAgent,"UInt"
                  ,(httpProxy != 0 ?  INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_DIRECT )
                  ,"Str",httpProxy,"Str",httpProxyBypass,"Uint",0)
	
   ; Open HTTP session for the given URL
   ; http://msdn.microsoft.com/en-us/library/aa384363(VS.85).aspx
	hConnect := DllCall("WinINet\InternetConnectA"
                  ,"uInt",hInternet,"Str",lpszHostname, "Int",nPort
                  ,"Str",lpszUserName, "Str",lpszPassword,"uInt",INTERNET_SERVICE_HTTP
                  ,"uInt",0,"uInt*",0)
	
   ; Do we POST? If so, check for header handling and set default
	if (Strlen(POSTDATA)>0) {
		HTTPVerb:="POST"
		if StrLen(Headers)=0
			Headers:="Content-Type: application/x-www-form-urlencoded"
	} else ; otherwise mode must be GET - no header defaults needed
		HTTPVerb:="GET"   
	
   ; Form the request with proper HTTP protocol version and create the request handle
   ; http://msdn.microsoft.com/en-us/library/aa384233(VS.85).aspx
	hRequest := DllCall("WinINet\HttpOpenRequestA"
                  ,"uInt",hConnect,"Str",HTTPVerb,"Str",lpszUrlPath . lpszExtrainfo
                  ,"Str",ProVer := "HTTP/1.1", "Str",httpQueryReferer,"Str",httpQueryAcceptTypes
                  ,"uInt",dwFlags,"uInt",Context:=0 )
	
   ; Send the specified request to the server
   ; http://msdn.microsoft.com/en-us/library/aa384247(VS.85).aspx
	sRequest := DllCall("WinINet\HttpSendRequestA"
                  , "uInt",hRequest,"Str",Headers, "uInt",Strlen(Headers)
                  , "Str",POSTData,"uInt",Strlen(POSTData))
	
	VarSetCapacity(header, 2048, 0)  ; max 2K header data for httpResponseHeader
	VarSetCapacity(header_len, 4, 0)
	
   ; Check for returned server response-header (works only _after_ request been sent)
   ; http://msdn.microsoft.com/en-us/library/aa384238.aspx
	Loop, 5
		if ((headerRequest:=DllCall("WinINet\HttpQueryInfoA","uint",hRequest
      ,"uint",21,"uint",&header,"uint",&header_len,"uint",0))=1)
			break
	
	If (headerRequest=1) {
		VarSetCapacity(res,headerLength:=NumGet(header_len),32)
		DllCall("RtlMoveMemory","uInt",&res,"uInt",&header,"uInt",headerLength)
		Loop,% headerLength
			if (*(&res-1+a_index)=0) ; Change binary zero to linefeed
				NumPut(Asc("`n"),res,a_index-1,"uChar")
		VarSetCapacity(res,-1)
	} else
		res := "timeout"
	
   ; Get 1st Line of Full Response
	Loop,Parse,res,`n,`r
	{
		RetValue := A_LoopField
		break
	}
	
   ; No Connection established - drop exception
	If (RetValue="timeout") {
		html := "Error: timeout"
		return -1
	}
   ; Strip protocol version from return value
	RetValue := RegExReplace(RetValue,"HTTP/1\.[01]\s+")
	
    ; List taken from http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
	HttpRetCodes := "100=Continue|101=Switching Protocols|102=Processing (WebDAV) (RFC 2518)|"
              . "200=OK|201=Created|202=Accepted|203=Non-Authoritative Information|204=No"
              . " Content|205=Reset Content|206=Partial Content|207=Multi-Status (WebDAV)"
              . "|300=Multiple Choices|301=Moved Permanently|302=Found|303=See Other|304="
              . "Not Modified|305=Use Proxy|306=Switch Proxy|307=Temporary Redirect|400=B"
              . "ad Request|401=Unauthorized|402=Payment Required|403=Forbidden|404=Not F"
              . "ound|405=Method Not Allowed|406=Not Acceptable|407=Proxy Authentication "
              . "Required|408=Request Timeout|409=Conflict|410=Gone|411=Length Required|4"
              . "12=Precondition Failed|413=Request Entity Too Large|414=Request-URI Too "
              . "Long|415=Unsupported Media Type|416=Requested Range Not Satisfiable|417="
              . "Expectation Failed|418=I'm a teapot (RFC 2324)|422=Unprocessable Entity "
              . "(WebDAV) (RFC 4918)|423=Locked (WebDAV) (RFC 4918)|424=Failed Dependency"
              . " (WebDAV) (RFC 4918)|425=Unordered Collection (RFC 3648)|426=Upgrade Req"
              . "uired (RFC 2817)|449=Retry With|500=Internal Server Error|501=Not Implem"
              . "ented|502=Bad Gateway|503=Service Unavailable|504=Gateway Timeout|505=HT"
              . "TP Version Not Supported|506=Variant Also Negotiates (RFC 2295)|507=Insu"
              . "fficient Storage (WebDAV) (RFC 4918)|509=Bandwidth Limit Exceeded|510=No"
              . "t Extended (RFC 2774)"
	
   ; Gather numeric response value
	RetValue := SubStr(RetValue,1,3)
	
   ; Parse through return codes and set according informations
	Loop,Parse,HttpRetCodes,|
	{
		HttpReturnCode := SubStr(A_LoopField,1,3)    ; Numeric return value see above
		HttpReturnMsg  := SubStr(A_LoopField,5)      ; link for additional information
		if (RetValue=HttpReturnCode) {
			RetMsg := HttpReturnMsg
			break
		}
	}
	
   ; Global HttpQueryOps handling
	if strlen(HTTPQueryOps)>0 {
      ; Show full Header response (usefull for debugging)
		if (instr(HTTPQueryOps,"showHeader"))
			MsgBox % res
      ; Save the full Header response in a global Variable
		if (instr(HTTPQueryOps,"storeHeader"))
			global HttpQueryHeader := res
      ; Check for size updates to export to a global Var
		if (instr(HTTPQueryOps,"updateSize")) {
			Loop,Parse,res,`n
				If RegExMatch(A_LoopField,"Content-Length:\s+?(?P<Size>\d+)",full) {
					global HttpQueryFullSize := fullSize
					break
				}
			if (fullSize+0=0)
				HttpQueryFullSize := "size unavailable"
		}
	}
	
   ; Check for valid codes and drop exception if suspicious
	if !(InStr("100 200 201 202 302",RetValue)) {
		Result := RetValue " " RetMsg
		return StrLen(Result)
	}
	
	VarSetCapacity(BytesRead,4,0)
	fsize := 0
	Loop            ; the receiver loop - rewritten in the need to enable
	{               ; support for larger file downloads
		bc := A_Index
		VarSetCapacity(buffer%bc%,1024,0) ; setup new chunk for this receive round
		ReadFile := DllCall("wininet\InternetReadFile"
                  ,"uInt",hRequest,"uInt",&buffer%bc%,"uInt",1024,"uInt",&BytesRead)
		ReadBytes := NumGet(BytesRead)    ; how many bytes were received?
		If ((ReadFile!=0)&&(!ReadBytes))  ; we have had no error yet and received no more bytes
			break                         ; we must be done! so lets break the receiver loop
		Else {
			fsize += ReadBytes            ; sum up all chunk sizes for correct return size
			sizeArray .= ReadBytes "|"
		}
		if (instr(HTTPQueryOps,"updateSize"))
			Global HttpQueryCurrentSize := fsize
	}
	sizeArray := SubStr(sizeArray,1,-1)   ; trim last PipeChar
	
	VarSetCapacity(result,fSize+1,0)      ; reconstruct the result from above generated chunkblocks
	Dest := &result                       ; to a our ByRef result variable
	Loop,Parse,SizeArray,|
		DllCall("RtlMoveMemory","uInt",Dest,"uInt",&buffer%A_Index%,"uInt",A_LoopField)
      , Dest += A_LoopField
     
	DllCall("WinINet\InternetCloseHandle", "uInt", hRequest)   ; close all opened
	DllCall("WinINet\InternetCloseHandle", "uInt", hInternet)
	DllCall("WinINet\InternetCloseHandle", "uInt", hConnect)
	DllCall("FreeLibrary", "UInt", hModule)                    ; unload the library
	return fSize                          ; return the size - strings need update via VarSetCapacity(res,-1)
}
But, when i run these codes after opening the site- https://cmyip.com/ in Chrome browser, it shows an empty msgbox.

Please tell me what i am doing wrong..

Thanks a lot..
I don't normally code as I don't code normally.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

14 Jul 2019, 07:07

@Sabestian Caine
The library you use is very-very outdated, just don't use it.
You could using something like this instead:

Code: Select all

url := "https://cmyip.com/"
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", url, false)
whr.Send()
MsgBox, % html := whr.ResponseText
RegExMatch(html, "(\d+\.){3}\d+", ip)
MsgBox, % ip
User avatar
Sabestian Caine
Posts: 528
Joined: 12 Apr 2015, 03:53

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

14 Jul 2019, 10:04

teadrinker wrote:
14 Jul 2019, 07:07
@Sabestian Caine
The library you use is very-very outdated, just don't use it.
You could using something like this instead:

Code: Select all

url := "https://cmyip.com/"
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", url, false)
whr.Send()
MsgBox, % html := whr.ResponseText
RegExMatch(html, "(\d+\.){3}\d+", ip)
MsgBox, % ip

Thanks dear teadrinker... your really solved my problem... above codes are working great...

Sir, I want to ask one more thing..

As i want to make a POST request in https://cmyip.com/ then what should i do?
As I want to search this ip address - 169.45.78.148 in https://cmyip.com/ site then what should i do?

please look at this image-
14_07_19 @8_31_23.PNG
14_07_19 @8_31_23.PNG (149.26 KiB) Viewed 3212 times
You can see there is an search box and i want this ip address - 169.45.78.148 to set in the above search box and search it using above codes, then what should i do?

Please help and guide..

Thanks a lot...
I don't normally code as I don't code normally.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

14 Jul 2019, 10:41

Sabestian Caine wrote: As i want to make a POST request in https://cmyip.com/ then what should i do?
The type of the request is here: whr.Open("GET", url, false), so if you want to sent POST request, specify: whr.Open("POST", url, false), but in this case you don't need it.
Sabestian Caine wrote: As I want to search this ip address - 169.45.78.148 in https://cmyip.com/ site then what should i do?
Enter ip in the field, press the search button, than you will see the url you need in the address bar.

Code: Select all

url := "https://cmyip.com/search-ip.php?ip=169.45.78.148"
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", url, false)
whr.Send()
html := whr.ResponseText
; MsgBox, % html

RegExMatch(html, "Host Name:\s+(\S+).*?"
               . "City:\s+(\S.*?)\s*<.*?"
               . "Region:\s+(\S.*?)\s*<.*?"
               . "Country:\s+(\S.*?)\s*<.*?"
               . "ISP:\s+(\S.*?)\s*<", match)
               
MsgBox, % "Host Name: " . match1 . "`n"
        . "City: "      . match2 . "`n"
        . "Region: "    . match3 . "`n"
        . "Country: "   . match4 . "`n"
        . "ISP: "       . match5
User avatar
Sabestian Caine
Posts: 528
Joined: 12 Apr 2015, 03:53

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

14 Jul 2019, 11:48

teadrinker wrote:
14 Jul 2019, 10:41
Sabestian Caine wrote: As i want to make a POST request in https://cmyip.com/ then what should i do?
The type of the request is here: whr.Open("GET", url, false), so if you want to sent POST request, specify: whr.Open("POST", url, false), but in this case you don't need it.
Sabestian Caine wrote: As I want to search this ip address - 169.45.78.148 in https://cmyip.com/ site then what should i do?
Enter ip in the field, press the search button, than you will see the url you need in the address bar.

Code: Select all

url := "https://cmyip.com/search-ip.php?ip=169.45.78.148"
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", url, false)
whr.Send()
html := whr.ResponseText
; MsgBox, % html

RegExMatch(html, "Host Name:\s+(\S+).*?"
               . "City:\s+(\S.*?)\s*<.*?"
               . "Region:\s+(\S.*?)\s*<.*?"
               . "Country:\s+(\S.*?)\s*<.*?"
               . "ISP:\s+(\S.*?)\s*<", match)
               
MsgBox, % "Host Name: " . match1 . "`n"
        . "City: "      . match2 . "`n"
        . "Region: "    . match3 . "`n"
        . "Country: "   . match4 . "`n"
        . "ISP: "       . match5


Thanks a lot dear teadrinker...

Sir, could you please give me a good example of POST request, i.e. where should i use whr.Open("POST", url, false) ? I want to know is post request used to set data or strings into edit fields of websites? Please guide.. Thanks ..
I don't normally code as I don't code normally.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

14 Jul 2019, 16:31

The POST request is used in cases, when you need to send to the server some data, such as a file, JSON string or password/login. Unfortunately, there is no simple example to demonstrate this.
The following code sends an image file to imgur.com and receives a JSON string that contains the identifier of the image you uploaded.

Code: Select all

; sending an image file to imgur.com

FileSelectFile, filePath,, %A_ScriptDir%, Choose an image file, Images (*.gif; *.ti*f; *.jp*g; *.png; *.bmp)
if !filePath
   Return
url := "https://imgur.com/upload"
FileGetSize, size, % filePath

CreateFormData(postData, hdr_ContentType, {file: [filePath]})
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("POST", url, false)
whr.SetRequestHeader("Content-Type", hdr_ContentType)
whr.SetRequestHeader("Content-Length", size)
whr.SetRequestHeader("Referer", url)
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
whr.Send(postData)

if ( (status := whr.Status) != 200 )
   MsgBox, % "Error, whr.status:" . status
else {
   MsgBox, % JSON := whr.responseText
   RegExMatch(JSON, """hash"":""\K[^""]+", hash)
   MsgBox, % Clipboard := "https://imgur.com/" . hash
}

CreateFormData(ByRef retData, ByRef retHeader, objParam) {
   new CreateFormData(retData, retHeader, objParam)
}

class CreateFormData
{
   __New(ByRef retData, ByRef retHeader, objParam) {
      static CRLF := "`r`n"
      ; Create a random Boundary
      Boundary := this.RandomBoundary()
      BoundaryLine := "------------------------------" . Boundary

      this.Len := 0 ; GMEM_ZEROINIT|GMEM_FIXED = 0x40
      this.Ptr := DllCall("GlobalAlloc", UInt, 0x40, UInt, 1, Ptr)

      ; 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)
      retHeader := "multipart/form-data; boundary=----------------------------" . Boundary
   }

   StrPutUTF8( str ) {
      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 ) {
      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"
   }
}
User avatar
Sabestian Caine
Posts: 528
Joined: 12 Apr 2015, 03:53

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

16 Jul 2019, 12:17

teadrinker wrote:
14 Jul 2019, 16:31
The POST request is used in cases, when you need to send to the server some data, such as a file, JSON string or password/login. Unfortunately, there is no simple example to demonstrate this.
The following code sends an image file to imgur.com and receives a JSON string that contains the identifier of the image you uploaded.

Code: Select all

; sending an image file to imgur.com

FileSelectFile, filePath,, %A_ScriptDir%, Choose an image file, Images (*.gif; *.ti*f; *.jp*g; *.png; *.bmp)
if !filePath
   Return
url := "https://imgur.com/upload"
FileGetSize, size, % filePath

CreateFormData(postData, hdr_ContentType, {file: [filePath]})
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("POST", url, false)
whr.SetRequestHeader("Content-Type", hdr_ContentType)
whr.SetRequestHeader("Content-Length", size)
whr.SetRequestHeader("Referer", url)
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
whr.Send(postData)

if ( (status := whr.Status) != 200 )
   MsgBox, % "Error, whr.status:" . status
else {
   MsgBox, % JSON := whr.responseText
   RegExMatch(JSON, """hash"":""\K[^""]+", hash)
   MsgBox, % Clipboard := "https://imgur.com/" . hash
}

CreateFormData(ByRef retData, ByRef retHeader, objParam) {
   new CreateFormData(retData, retHeader, objParam)
}

class CreateFormData
{
   __New(ByRef retData, ByRef retHeader, objParam) {
      static CRLF := "`r`n"
      ; Create a random Boundary
      Boundary := this.RandomBoundary()
      BoundaryLine := "------------------------------" . Boundary

      this.Len := 0 ; GMEM_ZEROINIT|GMEM_FIXED = 0x40
      this.Ptr := DllCall("GlobalAlloc", UInt, 0x40, UInt, 1, Ptr)

      ; 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)
      retHeader := "multipart/form-data; boundary=----------------------------" . Boundary
   }

   StrPutUTF8( str ) {
      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 ) {
      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"
   }
}



















Thanks a lot dear teadrinker for these great codes... You are really awesome...

Sir, i am trying to learn more about web api, I come across these codes from this site - https://the-automator.com/example-webservice-api-call-connecting-to-zoom-extracting-info/

Code: Select all

IniRead, API_Token ,Auth.ini,API, Token
IniRead, API_Key   ,Auth.ini,API, Key
IniRead, API_Secret,Auth.ini,API, Secret
 
;~  EndPoint:="https://api.zoom.us/v1/user/list" ;get list of users under your account
;~  EndPoint:="https://api.zoom.us/v1/meeting/list" ;get list of meetings for a given user
EndPoint:="https://api.zoom.us/v1/meeting/get" ;get specific meeting info
;~  QueryString:=QueryString_Builder({"api_key":API_Key,"api_secret":API_Secret,"data_type":"XML","host_id":"pPzEua3eSDerCD2WO3JbUg"})
QueryString:=QueryString_Builder({"api_key":API_Key,"api_secret":API_Secret,"data_type":"XML","id":"693773857","host_id":"pPzEua3eSDerCD2WO3JbUg"})
 
;********API call**********************
HTTP := ComObjCreate("WinHttp.WinHttpRequest.5.1") ;Create COM Object
HTTP.Open("POST", EndPoint . QueryString) ;GET & POST are most frequent, Make sure you UPPERCASE
HTTP.Send() ;If POST request put data in "Payload" variable
Response_data:= HTTP.ResponseText ;Save the text that is returned
SciTE_Output(Response_data) ;Text,Clear=1,LineBreak=1,Exit=0
 
;***********query string builder******************* 
QueryString_Builder(kvp){
for key, value in kvp
  queryString.=((A_Index="1")?(url "?"):("&")) key "=" value
return queryString
}



I watched this video too - https://www.youtube.com/watch?v=tw3kLhoRhnI

But, i am getting very little..

Please tell me, as he is posting these values - QueryString_Builder({"api_key":API_Key,"api_secret":API_Secret,"data_type":"XML","id":"693773857","host_id":"pPzEua3eSDerCD2WO3JbUg"}) in QueryString
What are these values.?
Secondly- what is endpoint? Does endpoint mean the name of website?
and thirdly why he needs to use QueryString_Builder(kvp) function?

Please help and guide..

Thanks teadrinker...
I don't normally code as I don't code normally.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

16 Jul 2019, 13:01

Sorry, I have not been interested in that topic, can't say anything. How about to ask @Joe Glines? :)
User avatar
Sabestian Caine
Posts: 528
Joined: 12 Apr 2015, 03:53

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

17 Jul 2019, 10:38

teadrinker wrote:
16 Jul 2019, 13:01
Sorry, I have not been interested in that topic, can't say anything. How about to ask @Joe Glines? :)
Thanks a lot dear teadrinker... You really helped me a lot... thanks for your kind support..

Sir, please tell me one last thing- what is requestheaders which you used in your codes like-

Code: Select all

whr.SetRequestHeader("Content-Type", hdr_ContentType)
whr.SetRequestHeader("Content-Length", size)
whr.SetRequestHeader("Referer", url)
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
Why we use SetRequestHeaders? please tell.. Thanks...
I don't normally code as I don't code normally.
teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

17 Jul 2019, 10:58

This is some info that the server needs to determine what kind of data we sent, what to do with it and what the response we expect to receive.
Read more here.
User avatar
Sabestian Caine
Posts: 528
Joined: 12 Apr 2015, 03:53

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

18 Jul 2019, 12:08

Sabestian Caine wrote:
17 Jul 2019, 10:38
teadrinker wrote:
16 Jul 2019, 13:01
Sorry, I have not been interested in that topic, can't say anything. How about to ask @Joe Glines? :)
Thanks a lot dear teadrinker... You really helped me a lot... thanks for your kind support..

Sir, please tell me one last thing- what is requestheaders which you used in your codes like-

Code: Select all

whr.SetRequestHeader("Content-Type", hdr_ContentType)
whr.SetRequestHeader("Content-Length", size)
whr.SetRequestHeader("Referer", url)
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0")
Why we use SetRequestHeaders? please tell.. Thanks...
Thanks dear teadrinker for your great help....

Thanks a lot sir.. :bravo: :bravo: :bravo:
I don't normally code as I don't code normally.
dwilbank
Posts: 43
Joined: 15 Mar 2020, 12:59

Re: HttpQuery function not working and showing empty msgbox, while it should show html codes of page?

15 Mar 2020, 15:07

> what is requestheaders which you used in your codes

Try accessing whatismyip.com without these headers.
Their server will reject your query with a 1020 error, because their cloudflare firewall thinks the query is coming from a bot instead of a real browser.
These setRequestHeader commands make the request look more like a request from a real browser.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: catquas, Google [Bot], mikeyww, mmflume, thelegend and 138 guests