WinHttp.WinHttpRequest.5.1 and HTTPS

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
JnLlnd
Posts: 487
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

WinHttp.WinHttpRequest.5.1 and HTTPS

31 Jul 2019, 15:46

First, I must admit that I do no expert about network protocols... This is why I'm looking for help here :-)

In a compiled software build with AHK, I include a command that is checking the latest version available of the app by checking a value on my web server. This command is using the function Url2Var below (I can't find the initial source of it, but it can be found in some posts on the old forum). It is calling the "WinHttp.WinHttpRequest.5.1" Windows object.

Code: Select all

Url2Var(strUrl)
{
objWebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
objWebRequest.Open("GET", strUrl)
objWebRequest.Send()
return (objWebRequest.StatusText() = "OK" ? objWebRequest.ResponseText() : "")
}
This function worked well as long as the command was sending the query to an HTTP url. But I guess that since the infos on an HTTPS server, some users do not receive the answer and/or see errors in their event viewer (source: Schannel) when running the command. Not all user get this error. Personally, I could not reproduce it on my own system.

Is there any option (or other command to use) in order to get a variable more reliably on an HTTPS server?

Or could I use some options offered by the WinHttpRequest.ahk function (https://www.autohotkey.com/boards/viewtopic.php?t=3256) posted by tmplinshi?

PS: One user reported that enabling TLS 1.2 by default by setting the value x800 in the registry key DefaultSecureProtocols under
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp
solved the issue on his system. Of course, I could not ask every user to change their setting but maybe this info could help find a solution from the script point of view.

Thanks,

Jean
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey
teadrinker
Posts: 4311
Joined: 29 Mar 2015, 09:41
Contact:

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

01 Aug 2019, 05:16

Try using ComObjCreate("MSXML2.XMLHTTP.6.0") instead of ComObjCreate("WinHttp.WinHttpRequest.5.1").
User avatar
JnLlnd
Posts: 487
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

01 Aug 2019, 09:32

Thanks teadrinker. I'll ask a user having the issue to test this protocol. On my system, it works as the other.
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey
User avatar
JnLlnd
Posts: 487
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

01 Aug 2019, 16:22

teadrinker wrote:
01 Aug 2019, 05:16
Try using ComObjCreate("MSXML2.XMLHTTP.6.0") instead of ComObjCreate("WinHttp.WinHttpRequest.5.1").
As I said, MSXML2.XMLHTTP.6.0 works on my system (as did WinHttp.WinHttpRequest.5.1). But unfortunately, not on my user's system.

On his system (Windows 7 64-bit), when using MSXML2.XMLHTTP.6.0, there is no error logged in the event viewer, the query returns a status 200 (no error) but the content of the request is not returned (remains empty).

This user solved his case by adding the following key to his registry to force the use of TLS 1.2:
Key: "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" value: "DefaultSecureProtocols" data: "x800"

He also found in this doc an option of the C++ WinHttpQueryOption command allowing to force or prevent the use of some secure protocols. Is this something that could be used with MSXML2.XMLHTTP.6.0 or WinHttp.WinHttpRequest.5.1 to avoid the use of TLS 1.0 ?

If yes, how? I would definitely need help doing it in AHK (I know very little about C++).
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey
teadrinker
Posts: 4311
Joined: 29 Mar 2015, 09:41
Contact:

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

01 Aug 2019, 17:27

JnLlnd wrote: Is this something that could be used with MSXML2.XMLHTTP.6.0 or WinHttp.WinHttpRequest.5.1 to avoid the use of TLS 1.0 ?
No, those are for WinHttpSetOption function and can't be used with COM-objects.
JnLlnd wrote: to avoid the use of TLS 1.0
Sorry, I don't know how to achieve this without editing the registry.
teadrinker
Posts: 4311
Joined: 29 Mar 2015, 09:41
Contact:

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

01 Aug 2019, 18:27

You could try using this code:

Code: Select all

url := "https://www.autohotkey.com/boards/viewtopic.php?f=76&t=66685&p=286791"
DataFromUrl(url, data)
MsgBox, % StrGet(&data, "utf-8")

DataFromUrl(url, ByRef data) {
   static userAgent := "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"
        , INTERNET_OPEN_TYPE_DIRECT := 1
        , OpenUrlFlags   := ( INTERNET_FLAG_IGNORE_CERT_CN_INVALID   := 0x00001000 )
                          | ( INTERNET_FLAG_IGNORE_CERT_DATE_INVALID := 0x00002000 )
                          | ( INTERNET_FLAG_RELOAD                   := 0x80000000 )
        , QueryInfoFlags := ( HTTP_QUERY_FLAG_NUMBER                 := 0x20000000 )
                          | ( HTTP_QUERY_CONTENT_LENGTH              := 0x00000005 )
        , FILE_BEGIN := 0, INVALID_SET_FILE_POINTER := -1, NO_ERROR := 0
        , HEAP_ZERO_MEMORY := 0x8
        
   #MaxMem 4095
   if !hLib := DllCall("LoadLibrary", Str, "Wininet.dll", Ptr)
      throw Exception("Can't load Wininet.dll")

   Loop 1 {
      if !hInternet := DllCall("Wininet\InternetOpen", Str, userAgent, UInt, INTERNET_OPEN_TYPE_DIRECT, Ptr, 0, Ptr, 0, UInt, 0, Ptr) {
         error := "InternetOpen fails. Last Error: " . A_LastError
         break
      }
      Loop {
         attemptCount := A_Index
         start := A_TickCount
         while !hUrl := DllCall("Wininet\InternetOpenUrl", Ptr, hInternet, Str, url, Ptr, 0, UInt, 0, UInt, OpenUrlFlags, Ptr, 0, Ptr) {
            if (A_TickCount - start > 30000 && error := "InternetOpenUrl fails. LastError: " . A_LastError . "`nCheck the internet connection!")
               break 2
            Sleep, 1000
         }
         if (attemptCount = 1) {
            DllCall("Wininet\HttpQueryInfo", Ptr, hUrl, UInt, QueryInfoFlags, UIntP, fullSize, UIntP, l := 4, UIntP, idx := 0)
            hHeap := DllCall("GetProcessHeap", Ptr)
            pHeap := DllCall("HeapAlloc", Ptr, hHeap, UInt, HEAP_ZERO_MEMORY, Ptr, buffSize := fullSize ? fullSize : 0x100000, Ptr)
            prevSize := bytesRead := 0
         }
         else {
            res := DllCall("Wininet\InternetSetFilePointer", Ptr, hUrl, UInt, bytesRead & 0xFFFFFFFF
                                                                      , IntP, h := (bytesRead >> 32), UInt, FILE_BEGIN, UInt, 0)
            if (res = INVALID_SET_FILE_POINTER && A_LastError != NO_ERROR) {
               error := "InternetSetFilePointer fails. Last Error: " . A_LastError
               break 2
            }
         }
         Loop {
            if !DllCall("Wininet\InternetQueryDataAvailable", Ptr, hUrl, UIntP, size, UInt, 0, Ptr, 0)
               break
            if (size = 0 && EOF := true)
               break
            if (bytesRead + size > buffSize) {
               pHeapNew := DllCall("HeapAlloc", Ptr, hHeap, UInt, HEAP_ZERO_MEMORY, Ptr, buffSize *= 2, Ptr)
               DllCall("RtlMoveMemory", Ptr, pHeapNew, Ptr, pHeap, Ptr, bytesRead)
               DllCall("HeapFree", Ptr, hHeap, UInt, 0, Ptr, pHeap)
               pHeap := pHeapNew
            }
            if !DllCall("Wininet\InternetReadFile", Ptr, hUrl, Ptr, pHeap + bytesRead, UInt, size, UIntP, read)
               break
            bytesRead += read
         }
         DllCall("Wininet\InternetCloseHandle", Ptr, hUrl)
      } until EOF || (attemptCount = 3 && error := "Can't download the file. Unknown error")
   }
   ( hInternet && DllCall("Wininet\InternetCloseHandle", Ptr, hInternet) )
   DllCall("FreeLibrary", Ptr, hLib)
   if error {
      DllCall("HeapFree", Ptr, hHeap, UInt, 0, Ptr, pHeap)
      throw Exception(error)
   }
   else {
      VarSetCapacity(data, bytesRead, 0)
      DllCall("RtlMoveMemory", Ptr, &data, Ptr, pHeap, Ptr, bytesRead)
   }
   DllCall("HeapFree", Ptr, hHeap, UInt, 0, Ptr, pHeap)
   Return bytesRead
}
Last edited by teadrinker on 01 Aug 2019, 18:56, edited 1 time in total.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

02 Aug 2019, 06:35

May be try this:

Code: Select all

link := "https://www.google.com"
 
req := ComObjCreate("Msxml2.XMLHTTP")
req.open("GET", link, False)
req.Send()
MsgBox, % req.responseText
User avatar
JnLlnd
Posts: 487
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

02 Aug 2019, 07:07

Thanks malcev and teadrinker. These solutions work well on my system (Windows 10) but can produce errors in the event log on system where the old protocol TLS 1.0 is still enabled. But Windows catch-up after the error and produce the expected result. So I can work with this. Users wanting to avoid the error can enter the registry key DefaultSecureProtocols mentioned earlier to bypass TLS 1.0 and use TLS 1.2 (but this is not necessary).

Jean
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

02 Aug 2019, 07:18

If You use Msxml2.XMLHTTP You have to set cache related headers to avoid getting response text from cache.

Code: Select all

req.SetRequestHeader("Pragma", "no-cache")
req.SetRequestHeader("Cache-Control", "no-cache, no-store")
req.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT")
You also have to send them If You use WinHttp.WinHttpRequest.5.1 through proxy.
And it is strange that with MSXML2.XMLHTTP.6.0 You received empty response text.
User avatar
JnLlnd
Posts: 487
Joined: 29 Sep 2013, 21:29
Location: Montreal, Quebec, Canada
Contact:

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

02 Aug 2019, 11:20

malcev wrote:
02 Aug 2019, 07:18
And it is strange that with MSXML2.XMLHTTP.6.0 You received empty response text.
Thanks for the tip about caching. In the lats test, MSXML2.XMLHTTP.6.0 returned the page content even if it was producing an error. I could not explain why, I'm not the one who ran these test on the Win 7 system.
:thumbup: Author of freeware Quick Access Popup, the powerful Windows folders, apps and documents launcher!
:P Now working on Quick Clipboard Editor
:ugeek: The Automator's Courses on AutoHotkey
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: WinHttp.WinHttpRequest.5.1 and HTTPS

06 Dec 2019, 14:45

JnLlnd wrote:
31 Jul 2019, 15:46
PS: One user reported that enabling TLS 1.2 by default by setting the value x800 in the registry key DefaultSecureProtocols under
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp
solved the issue on his system. Of course, I could not ask every user to change their setting but maybe this info could help find a solution from the script point of view.
i've had the same problem with specific users on win7. they can enable TLS1.2 within internet explorer options on the advanced tab, and that worked to fix it

looks like the ahk installer just switched to the XMLHTTP too:
https://github.com/Lexikos/AutoHotkey-Release/commit/4622287857dbbb2f23dfc91615c5b3b6650241ac


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: hiahkforum and 143 guests