Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinHttpRequest timeouts

I'm using AHK script to send some POST requests. I'm trying to get a timeout response so I can popup some message to the user. I cant figure out how to use the "SetTimeouts" method and the "WaitForResponse" See code below

WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WebRequest.SetTimeouts(3000,3000,3000,3000)

openConnection(WebRequest,ip){
   WebRequest.Open("POST", "http://" ip "/cgi/drsLogin",true)
   WebRequest.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
   WebRequest.Send("action=login&username=admin&password=admin")
   time := WebRequest.WaitForResponse(2)

   if (time = -1) {
    addTextToGui("Connection Timeout")
   }
   else{
     return
   }
 return
}
like image 470
bardalas Avatar asked Mar 15 '23 18:03

bardalas


2 Answers

AutoHotkey likes Values in functions to be surrounded by Quotes.

Try changing:

WebRequest.SetTimeouts(3000,3000,3000,3000)

to

WinHttpReq.SetTimeouts("30000", "30000", "30000", "30000")

Edit: Okay it seems I was wrong and both methods work.

I tested the above using this website: http://tmplinshi.sinaapp.com/test/timeout-test-20s.php

In the code below SetTimouts is set for 10 Seconds Our test is set to respond in 20 Seconds so this will guarantee a Timeout.

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
MsgBox % webpage

I'm getting a Timeout Error but this breaks the script and still doesn't answer how to pull the Timeout message?

Well since we are getting a Timeout Error this means we need to add Error Handling to our code. We'll do this using Try / Catch.

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")

Try { 
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
}
Catch e{
    MsgBox % e
    ExitApp
}

MsgBox % webpage

Okay, the script no longer breaks but the MsgBox is blank? This isn't working!

Well it is blank because our Error message is being returned from an Object as an Object! Examining the e Object I found that it contains several Keys storing data as Strings and even an Integer value. The keys are labeled as such: Extra, File, Line, Message, and What... So lets take a look at Message!

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")

Try { 
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
}
Catch e{
    MsgBox % e.Message
    ExitApp
}

MsgBox % webpage

Okay so now I see:

0x80072EE2 -
Source: WinHttp.WinHttpRequest

Description: The operation timed out

HelpFile: (null)

HelpContext: 0

Right, it appears we got our Timed Out message and a bunch of other info we probably don't want. So what we can do now is parse the data we want out of of the message! Like so:

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")

Try { 
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
}
Catch e{
    For Each, Line in StrSplit(e.Message, "`n", "`r") {
        Results := InStr(Line, "Description:") 
            ? StrReplace(Line, "Description:")
            : ""
        If (Results <> "")
            Break
    }
    MsgBox % Trim(Results)
    ExitApp
}

MsgBox % webpage

Edit:

Forgot to mention that this method will not just Catch Timeouts but various other errors such as Unreachable address or an invalid URL and it will display those errors correctly.

You can see test these yourself by going to http://www.isitdownrightnow.com/ and trying to use the code above on a Site that is Down. You'll see it returns:

The server name or address could not be resolved

Also adding characters that don't belong or spaces to a URL the code produces:

The URL is invalid

like image 165
errorseven Avatar answered Apr 21 '23 12:04

errorseven


Here is another way of doing it. It's a bit more readable and allows you to set a total timeout time instead of for different lower level timeout times that you usually don't care about.

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")

timedOut := False
WinHttpReq.Open("GET", "http://google.com", True)
WinHttpReq.Send()
Sleep, 1     ;timeout: 1 millisecond (will time out)
;Sleep, 4000 ;timeout: 4 seconds (should not time out)

ComObjError(False)
WinHttpReq.Status
If (A_LastError) ;if WinHttpReq.Status was not set (no response received yet)
    timedOut := True
ComObjError(True)

If (timedOut)
    MsgBox, timed out
Else
    MsgBox, didn't time out
like image 41
Forivin Avatar answered Apr 21 '23 12:04

Forivin