Jump to content
trancexx

WinHTTP functions

Recommended Posts

When you use InetGet and specify background flag then AutoIt creates new thread in which the download is done. Other than that Inet download is slower than with WinHttp.

So it's very clear how you can solve your problem. Use built-in Inet function, make another thread and use WinHTTP or try it in async mode.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
Guest

When you use InetGet and specify background flag then AutoIt creates new thread in which the download is done. Other than that Inet download is slower than with WinHttp.

So it's very clear how you can solve your problem. Use built-in Inet function, make another thread and use WinHTTP or try it in async mode.

Thank you for the word "async". It gave me a new direction.

I managed to do it this way:

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#AutoIt3Wrapper_Run_AU3Check=n

#include "WinHttp.au3"

;~ Opt("MustDeclareVars", 1)
Global $Surl , $iSizeBufferAsync , $tBufferAsync , $pBufferAsync , $hWINHTTP_STATUS_CALLBACK , $hOpen , $hConnect , $hRequest


$Surl = "https://googledrive.com/host/0B-dsGBArc-IuVHdIRFFyUV8xSXc/host-in-drive.html"
$iSizeBufferAsync = 1048576 ; 1MB for example, should be enough ; The size
$tBufferAsync = DllStructCreate("byte[" & $iSizeBufferAsync & "]") ; The buffer
$pBufferAsync = DllStructGetPtr($tBufferAsync) ; Get pointer to this memory space
$hWINHTTP_STATUS_CALLBACK = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword") ; Register Callback function
$hOpen = _WinHttpOpen(Default, Default, Default, Default, $WINHTTP_FLAG_ASYNC) ; Initialize and get session handle. Asynchronous flag.
_WinHttpSetStatusCallback($hOpen, $hWINHTTP_STATUS_CALLBACK) ; Assign callback function
$CrackUrl = _WinHttpCrackUrl($Surl) ; Get connection handle
$hConnect = _WinHttpConnect($hOpen, $CrackUrl[2],$INTERNET_DEFAULT_HTTPS_PORT)
$hRequest = _WinHttpOpenRequest($hConnect, Default, $CrackUrl[6], Default, Default, Default, $WINHTTP_FLAG_SECURE) ; Make request
_WinHttpSendRequest($hRequest)

$timer = TimerInit()
While 1
    ToolTip("test")
    If TimerDiff($timer) > 5000 Then ExitLoop
    Sleep(10)
WEnd


; Close handles
_WinHttpCloseHandle($hRequest)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)
; Free callback. Redundant here
DllCallbackFree($hWINHTTP_STATUS_CALLBACK)



;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
; Define callback function
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Func __WINHTTP_STATUS_CALLBACK($hInternet, $iContext, $iInternetStatus, $pStatusInformation, $iStatusInformationLength)
    #forceref $hInternet, $iContext, $pStatusInformation, $iStatusInformationLength
;~     ConsoleWrite(">> ")
    ; Interpret the status

;~  If _WinHttpQueryDataAvailable($hRequest) Then
;~      $sChunk = _WinHttpReadData($hRequest)
;~      ConsoleWrite($sChunk&@CRLF)
;~  EndIf

;~  Return
    Local $sStatus
    Switch $iInternetStatus
;~         Case $WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
;~             $sStatus = "Closing the connection to the server"
;~         Case $WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
;~             $sStatus = "Successfully connected to the server."
;~         Case $WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
;~             $sStatus = "Connecting to the server."
;~         Case $WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
;~             $sStatus = "Successfully closed the connection to the server."
        Case $WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
            $sStatus = "Data is available to be retrieved with WinHttpReadData."
;~             ConsoleWrite($sStatus & @CRLF)

            ;*************************************
            ; Read asynchronously
            ;*************************************
            _WinHttpSimpleReadDataAsync($hInternet, $pBufferAsync, $iSizeBufferAsync)
;~             Return

;~         Case $WINHTTP_CALLBACK_STATUS_HANDLE_CREATED
;~             $sStatus = "An HINTERNET handle has been created: " & $hInternet
;~         Case $WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING
;~             $sStatus = "This handle value has been terminated: " & $hInternet
        Case $WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
            $sStatus = "The response header has been received and is available with WinHttpQueryHeaders."
;~             ConsoleWrite($sStatus & @CRLF)

            ;*************************************
            ; Print header
            ;*************************************
;~             ConsoleWrite(_WinHttpQueryHeaders($hInternet) & @CRLF)

            ;*************************************
            ; Check if there is any data available
            ;*************************************
            _WinHttpQueryDataAvailable($hInternet)

;~             Return

;~         Case $WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE
;~             $sStatus = "Received an intermediate (100 level) status code message from the server."
;~         Case $WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
;~             $sStatus = "Successfully found the IP address of the server."
        Case $WINHTTP_CALLBACK_STATUS_READ_COMPLETE
            $sStatus = "Data was successfully read from the server."
;~             ConsoleWrite($sStatus & @CRLF)

            ;*************************************
            ; Print read data
            ;*************************************
            Local $sRead = DllStructGetData(DllStructCreate("char[" & $iStatusInformationLength & "]", $pStatusInformation), 1)
            ConsoleWrite($sRead & @CRLF)

            Return

;~         Case $WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
;~             $sStatus = "Waiting for the server to respond to a request."
;~         Case $WINHTTP_CALLBACK_STATUS_REDIRECT
;~             $sStatus = "An HTTP request is about to automatically redirect the request."
;~         Case $WINHTTP_CALLBACK_STATUS_REQUEST_ERROR
;~             $sStatus = "An error occurred while sending an HTTP request."
;~         Case $WINHTTP_CALLBACK_STATUS_REQUEST_SENT
;~             $sStatus = "Successfully sent the information request to the server."
;~         Case $WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
;~             $sStatus = "Looking up the IP address of a server name."
;~         Case $WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
;~             $sStatus = "Successfully received a response from the server."
;~         Case $WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
;~             $sStatus = "One or more errors were encountered while retrieving a Secure Sockets Layer (SSL) certificate from the server."
;~         Case $WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
;~             $sStatus = "Sending the information request to the server."
        Case $WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
            $sStatus = "The request completed successfully."
            _WinHttpReceiveResponse($hInternet)
            Return
;~         Case $WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
;~             $sStatus = "Data was successfully written to the server."
    EndSwitch
    ; Print it
;~     ConsoleWrite($sStatus & @CRLF)
EndFunc    ;==>__WINHTTP_STATUS_CALLBACK

but most of the time it does not work and I get a fatal crash or random errors.

I guess it's not a good direction unless you have a solution for this way to make it 100% stable.

 

Use built-in Inet function

I'm currently using this solution. But there is a disadvantage in this solution - this solution requires to download to temp file.

I want to download in background to directly to a variable without having to download to temp file during the process.

 

make another thread and use WinHTTP

I tried to create another thread and in the another thread i used InetRead() as you can see at the link below:

'?do=embed' frameborder='0' data-embedContent>>

But it does not work stable (but more stable then the example about async mode) .. this method also causing autoit crash sometimes

I guess that the new thread is causing autoit crash.

Can you please give me an example of how to create new thread that will not cause autoit to crash?

I guess you have no idea. Because I read the forum and I realized that no one managed to new thread and run the script 100% stable.

Anyway, if you have an idea then please give an example.

If the example will related to to this thread, then open New Thread ..

Thank you for your time

Edited by Guest

Share this post


Link to post
Share on other sites

Here is a websocket example (Win8 is required) :

;http://code.msdn.microsoft.com/windowsdesktop/WinHTTP-WebSocket-sample-50a140b5/sourcecode?fileId=51199&pathId=1032775223

#include "WinHttp.au3"
#include <WinAPI.au3> ;_WinAPI_GetLastError

Global Const $ERROR_NOT_ENOUGH_MEMORY = 8
Global Const $ERROR_INVALID_PARAMETER = 87

Global Const $WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114

Global Const $WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE = 0
Global Const $WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE = 1

Global Const $WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS = 1000

Global $hOpen = 0, $hConnect = 0, $hRequest = 0, $hWebSocket = 0
Global $iError = 0

Example()
Exit quit()

Func Example()
    Local $sServerName = "echo.websocket.org"
    Local $sPath = ""

    Local $sMessage = "Hello world"

    ; Create session, connection and request handles.

    $hOpen = _WinHttpOpen("WebSocket sample", $WINHTTP_ACCESS_TYPE_DEFAULT_PROXY)
    If $hOpen = 0 Then
        $iError = _WinAPI_GetLastError()
        ConsoleWrite("Open error" & @CRLF)
        Return False
    EndIf

    $hConnect = _WinHttpConnect($hOpen, $sServerName, $INTERNET_DEFAULT_HTTP_PORT)
    If $hConnect = 0 Then
        $iError = _WinAPI_GetLastError()
        ConsoleWrite("Connect error" & @CRLF)
        Return False
    EndIf

    $hRequest = _WinHttpOpenRequest($hConnect, "GET", $sPath, "")
    If $hRequest = 0 Then
        $iError = _WinAPI_GetLastError()
        ConsoleWrite("OpenRequest error" & @CRLF)
        Return False
    EndIf

    ; Request protocol upgrade from http to websocket.

    Local $fStatus = _WinHttpSetOptionNoParams($hRequest, $WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET)
    If Not $fStatus Then
        $iError = _WinAPI_GetLastError()
        ConsoleWrite("SetOption error" & @CRLF)
        Return False
    EndIf

    ; Perform websocket handshake by sending a request and receiving server's response.
    ; Application may specify additional headers if needed.

    $fStatus = _WinHttpSendRequest($hRequest)
    If Not $fStatus Then
        $iError = _WinAPI_GetLastError()
        ConsoleWrite("SendRequest error" & @CRLF)
        Return False
    EndIf

    $fStatus = _WinHttpReceiveResponse($hRequest)
    If Not $fStatus Then
        $iError = _WinAPI_GetLastError()
        ConsoleWrite("SendRequest error" & @CRLF)
        Return False
    EndIf

    ; Application should check what is the HTTP status code returned by the server and behave accordingly.
    ; WinHttpWebSocketCompleteUpgrade will fail if the HTTP status code is different than 101.

    $hWebSocket = _WinHttpWebSocketCompleteUpgrade($hRequest, 0)
    If $hWebSocket = 0 Then
        $iError = _WinAPI_GetLastError()
        ConsoleWrite("WebSocketCompleteUpgrade error" & @CRLF)
        Return False
    EndIf

    _WinHttpCloseHandle($hRequest)
    $hRequestHandle = 0

    ConsoleWrite("Succesfully upgraded to websocket protocol" & @CRLF)

    ; Send and receive data on the websocket protocol.

    $iError = _WinHttpWebSocketSend($hWebSocket, _
            $WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, _
            $sMessage)
    If @error Or $iError <> 0 Then
        ConsoleWrite("WebSocketSend error" & @CRLF)
        Return False
    EndIf

    ConsoleWrite("Sent message to the server: " & $sMessage & @CRLF)

    Local $iBufferLen = 1024
    Local $tBuffer = 0, $bRecv = Binary("")

    Local $iBytesRead = 0, $iBufferType = 0
    Do
        If $iBufferLen = 0 Then
            $iError = $ERROR_NOT_ENOUGH_MEMORY
            Return False
        EndIf

        $tBuffer = DllStructCreate("byte[" & $iBufferLen & "]")

        $iError = _WinHttpWebSocketReceive($hWebSocket, _
                $tBuffer, _
                $iBytesRead, _
                $iBufferType)
        If @error Or $iError <> 0 Then
            ConsoleWrite("WebSocketReceive error" & @CRLF)
            Return False
        EndIf

        ; If we receive just part of the message restart the receive operation.

        $bRecv &= BinaryMid(DllStructGetData($tBuffer, 1), 1, $iBytesRead)
        $tBuffer = 0

        $iBufferLen -= $iBytesRead
    Until $iBufferType <> $WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE

    ; We expected server just to echo single binary message.

    If $iBufferType <> $WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE Then
        ConsoleWrite("Unexpected buffer type" & @CRLF)
        $iError = $ERROR_INVALID_PARAMETER
        Return False
    EndIf

    ConsoleWrite("Received message from the server: '" & BinaryToString($bRecv) & "'" & @CRLF)

    ; Gracefully close the connection.

    $iError = _WinHttpWebSocketClose($hWebSocket, _
            $WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS)
    If @error Or $iError <> 0 Then
        ConsoleWrite("WebSocketClose error" & @CRLF)
        Return False
    EndIf

    ; Check close status returned by the server.

    Local $iStatus = 0, $iReasonLengthConsumed = 0
    Local $tCloseReasonBuffer = DllStructCreate("byte[123]")

    $iError = _WinHttpWebSocketQueryCloseStatus($hWebSocket, _
            $iStatus, _
            $iReasonLengthConsumed, _
            $tCloseReasonBuffer)
    If @error Or $iError <> 0 Then
        ConsoleWrite("QueryCloseStatus error" & @CRLF)
        Return False
    EndIf

    ConsoleWrite("The server closed the connection with status code: '" & $iStatus & "' and reason: '" & _
            BinaryToString(BinaryMid(DllStructGetData($tCloseReasonBuffer, 1), 1, $iReasonLengthConsumed)) & "'" & @CRLF)
EndFunc   ;==>Example

Func quit()
    If $hRequest <> 0 Then
        _WinHttpCloseHandle($hRequest)
        $hRequest = 0
    EndIf

    If $hWebSocket <> 0 Then
        _WinHttpCloseHandle($hWebSocket)
        $hWebSocket = 0
    EndIf

    If $hConnect <> 0 Then
        _WinHttpCloseHandle($hConnect)
        $hConnect = 0
    EndIf

    If $iError <> 0 Then
        ConsoleWrite("Application failed with error: " & $iError & @CRLF)
        Return -1
    EndIf

    Return 0
EndFunc

Func _WinHttpSetOptionNoParams($hInternet, $iOption)
    Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "bool", "WinHttpSetOption", _
            "handle", $hInternet, "dword", $iOption, "ptr", 0, "dword", 0)
    If @error Or Not $aCall[0] Then Return SetError(4, 0, 0)
    Return 1
EndFunc   ;==>_WinHttpSetOptionNoParams

Func _WinHttpWebSocketCompleteUpgrade($hRequest, $pContext = 0)
    Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketCompleteUpgrade", _
            "handle", $hRequest, _
            "DWORD_PTR", $pContext)
    If @error Then Return SetError(@error, @extended, -1)
    Return $aCall[0]
EndFunc   ;==>_WinHttpWebSocketCompleteUpgrade

Func _WinHttpWebSocketSend($hWebSocket, $iBufferType, $vData)
    Local $tBuffer = 0, $iBufferLen = 0
    If IsBinary($vData) = 0 Then $vData = StringToBinary($vData)
    $iBufferLen = BinaryLen($vData)
    If $iBufferLen > 0 Then
        $tBuffer = DllStructCreate("byte[" & $iBufferLen & "]")
        DllStructSetData($tBuffer, 1, $vData)
    EndIf

    Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "DWORD", "WinHttpWebSocketSend", _
            "handle", $hWebSocket, _
            "int", $iBufferType, _
            "ptr", DllStructGetPtr($tBuffer), _
            "DWORD", $iBufferLen)
    If @error Then Return SetError(@error, @extended, -1)
    Return $aCall[0]
EndFunc   ;==>_WinHttpWebSocketSend

Func _WinHttpWebSocketReceive($hWebSocket, $tBuffer, ByRef $iBytesRead, ByRef $iBufferType)
    Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketReceive", _
            "handle", $hWebSocket, _
            "ptr", DllStructGetPtr($tBuffer), _
            "DWORD", DllStructGetSize($tBuffer), _
            "DWORD*", $iBytesRead, _
            "int*", $iBufferType)
    If @error Then Return SetError(@error, @extended, -1)
    $iBytesRead = $aCall[4]
    $iBufferType = $aCall[5]
    Return $aCall[0]
EndFunc   ;==>_WinHttpWebSocketReceive

Func _WinHttpWebSocketClose($hWebSocket, $iStatus, $tReason = 0)
    Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketClose", _
            "handle", $hWebSocket, _
            "USHORT", $iStatus, _
            "ptr", DllStructGetPtr($tReason), _
            "DWORD", DllStructGetSize($tReason))
    If @error Then Return SetError(@error, @extended, -1)
    Return $aCall[0]
EndFunc   ;==>_WinHttpWebSocketClose

Func _WinHttpWebSocketQueryCloseStatus($hWebSocket, ByRef $iStatus, ByRef $iReasonLengthConsumed, $tCloseReasonBuffer = 0)
    Local $aCall = DllCall($hWINHTTPDLL__WINHTTP, "handle", "WinHttpWebSocketQueryCloseStatus", _
            "handle", $hWebSocket, _
            "USHORT*", $iStatus, _
            "ptr", DllStructGetPtr($tCloseReasonBuffer), _
            "DWORD", DllStructGetSize($tCloseReasonBuffer), _
            "DWORD*", $iReasonLengthConsumed)
    If @error Then Return SetError(@error, @extended, -1)
    $iStatus = $aCall[2]
    $iReasonLengthConsumed = $aCall[5]
    Return $aCall[0]
EndFunc   ;==>_WinHttpWebSocketQueryCloseStatus
Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

I forgot to add :

Minimum supported client

Windows 8 [desktop apps only]

I don't know wether it's possible to upgrade the winhttp version. Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

I'm trying to login to the website https://www.startrack.com.au/login/

however when I try the following, the result is blank:

$hSession = _WinHttpOpen('Mozilla/5.0 (Windows NT 5.1; rv:2.0) Gecko/20100101 Firefox/4.0')
$hConnect = _WinHttpConnect($hSession, "startrack.com.au")
$sHTM = _WinHttpSimpleFormFill($hConnect, 'login/', 'id:form1', 'id:__c1_txtUsername', 'test', 'id:__c1_txtPassword', 'test')
MsgBox(0,'', $sHTM)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hSession)

I was expecting $sHTM to at least come back with the page that shows that the username/password are incorrect but this is not happening...

Any help would be appreciated

Share this post


Link to post
Share on other sites

@trancexx,
i have a trouble with my code 

#include <winhttp.au3>

Global $hSession = _WinhttpOpen("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1")
Global $hConnect = _WinhttpConnect($hSession, "www.facebook.com", $INTERNET_DEFAULT_HTTPS_PORT)
$sHTml = _WinHttpSimpleSSLRequest($hConnect, "GET", "")
MsgBox(0,'', $sHTM)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hSession)

Why does $sHTml return nothing?
i try _WinHttpSetStatusCallback and receiced:
.....

!->Current status of the connection: 16384  An HTTP request is about to automatically redirect the request.
!->Current status of the connection: 4 Connecting to the server.
!->Current status of the connection: 8 Successfully connected to the server.
!->Current status of the connection: 65536 One or more errors were encountered while retrieving a Secure Sockets Layer (SSL) certificate from the server.
.....
What happened??
plz help me, thaks.  :)
 

Share this post


Link to post
Share on other sites

You have to ignore cert errors. That's done by calling _WinHttpSetOption() on request handle. Depending what you want to ignore you can call it like this:

;...
_WinHttpSetOption($hRequest, $WINHTTP_OPTION_SECURITY_FLAGS, BitOR($SECURITY_FLAG_IGNORE_CERT_DATE_INVALID, $SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE, $SECURITY_FLAG_IGNORE_UNKNOWN_CA, $SECURITY_FLAG_IGNORE_CERT_CN_INVALID))
;...
For your specific code it would be inside _WinHttpSimpleSendSSLRequest(), below:

Local $hRequest = _WinHttpOpenRequest(
...line.

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Hi there,

I'm reanimating this thread, because I have the same problem as the threadstarter, just without a solution jet. I use AutoIT v3.3.8.1, I compile my scripts on a Windows 7 Ultimate 32 Bit and they run on another machine, which is a Windows 7 Professional 64 Bit. Both Windows are fully patched. I use WinHttp v1.6.3.7. In the directory of my compiled exe of this script are also the files:WinHttp.au3 and WinHttpConstants.au3. My Script uses this library to make a HTTP Request and looks into the header and works with these information. The following doesn't trigger @error: #include <WinHttp.au3>, _WinHttpOpen(), _WinHttpConnect(), _WinHttpOpenRequest(), _WinHttpSendRequest(). The following functions trigger @error: _WinHttpReceiveResponse(), _WinHttpQueryHeaders() both with @error 1. The documentation says this "1 - DllCall failed".

Here is the relevant snip of my script:

#Region                                                                     ; **** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Compression=0
#EndRegion
#include <Misc.au3>
#include <File.au3>
#include <WinHttp.au3>
_Singleton( StringReplace(@ScriptName, ".exe", "") )                            ; prevents multiple starts of this script
;#NoEnv                                                                         ; recommended for performance and compatibility with future AutoHotkey releases
;#Warn                                                                          ; enable warnings to assist with detecting common errors
Opt("WinTitleMatchMode", 1)                                                     ; 1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=force lower case match according to other type of match.
Opt("MustDeclareVars", 1)
Global $HttpStatus = 0                                                          ; _MakeHttpRequest() will fill this variable.
Global $FilenameWithExtension = StringReplace(@ScriptName, ".exe", "") & ".log"


Func _MakeHttpRequest ()
    ;If Not _WinHttpCheckPlatform() Then                                        ; was tested the messagebox didn't show up.
    ;   MsgBox(48, "Caution", "WinHTTP not available on your system!")
    ;   Exit 1
    ;EndIf
    Local $hOpen = _WinHttpOpen()                                               ; Open needed handles
    _WinHttpSetOption($hOpen, $WINHTTP_OPTION_USER_AGENT, "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko")              ; Set User-Agent string
    Local $hConnect = _WinHttpConnect($hOpen, "google.com")                     ; Open needed handles
    If @error Then
        _WriteLogLine(" --> Error Nr. " & @error & ": using _WinHttpConnect().")
    EndIf
    Local $hRequest = _WinHttpOpenRequest($hConnect, Default, "index.html")     ; Specify the reguest
    If @error Then
        _WriteLogLine("--> Error Nr. " & @error & ": using _WinHttpOpenRequest().")
    EndIf
    $HttpStatus = 0
    _WinHttpSendRequest($hRequest)                                              ; Send request
    If @error Then
        _WriteLogLine("--> Error Nr. " & @error & ": using _WinHttpSendRequest().")
    EndIf
    _WinHttpReceiveResponse($hRequest)                                          ; Wait for the response
    If @error Then
        _WriteLogLine("--> Error Nr. " & @error & ": using _WinHttpReceiveResponse().")
    EndIf
    Local $sHeader = _WinHttpQueryHeaders($hRequest)                            ; ...get full header
    If @error Then
        _WriteLogLine("--> Error Nr. " & @error & ": using _WinHttpQueryHeaders().")
    EndIf
    Sleep(150)
    If StringLen($sHeader) < 10 Then
        $HttpStatus = 200
        _WriteLogLine("--> Error Nr. " & @error & ": in _MakeHttpRequest(), $sHeader contains: >>" & $sHeader & "<<")
    Else
        Local $aHeaderPart = StringSplit($sHeader," ")                                              ; extract HTTP Statuscode from full header
        $HttpStatus = $aHeaderPart[2]                                                               ; 2nd Array Element is the HTTP Status.
    EndIf
    _WinHttpCloseHandle($hRequest)                                                                  ; Clean
    _WinHttpCloseHandle($hConnect)                                                                  ; Clean
    _WinHttpCloseHandle($hOpen)                                                                     ; Clean
EndFunc


Func _WriteLogLine($StringToLog=Default)
    Local $hFile = FileOpen(@ScriptDir & "\" & $FilenameWithExtension, 257)                     ; Open logfile in the same directory named like the exe, but with log extension. Create logfile, if necessary.
                                                                                                ;   129 = Verwende Unicode-UTF8 Kodierung im Lese- und Schreib- Anhängmodus. Lesen überschreibt ein existierendes BOM nicht.
                                                                                                ;   256 = Verwende Unicode-UTF8 (ohne BOM) im Lese- und Schreib- Anhängmodus.
    _FileWriteLog($hFile, $StringToLog)                                                         ; Write string to logfile.
    Sleep(1000)                                                                                 ; Wait 1 second.
    FileClose($hFile)                                                                           ; Close logfile.
EndFunc


While True
    _MakeHttpRequest ()
    Sleep(600000)                                                                                   ; Wait 10 minutes.
Wend

My logfile contains multiple entries like this ones:

2014-06-27 14:11:22 : --> Error Nr. 1: using _WinHttpReceiveResponse().
2014-06-27 14:11:23 : --> Error Nr. 1: using _WinHttpQueryHeaders().
2014-06-27 14:11:24 : --> Error Nr. 0: in _MakeHttpRequest(), $sHeader contains: >><<

Help to solve this error is most appreciated. Currently I'm requesting a HTTP request, how can I request via HTTPS?  :)

Share this post


Link to post
Share on other sites

Hm, I started this thread, and I don't recall sharing my problem(s) with you. The main problem I have here (AutoIt forum) is a lack of penis on my side, and solution to that problem - I have not. I think I'll just wait till these trouble making vagina envy individuals die of natural death, they are kind of old, you know.

As for the problem you talk about later on, probably you should check your firewall settings. I don't see any issues with this UDF.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Hi there,

Hm, I started this thread, and I don't recall sharing my problem(s) with you. The main problem I have here (AutoIt forum) is a lack of penis on my side, and solution to that problem - I have not. I think I'll just wait till these trouble making vagina envy individuals die of natural death, they are kind of old, you know.

 

I'm sorry I can't understand what you express with that. If I had done something wrong, I apologize. If you wanted to tell me something please keep it simple enough to understand for my as English is not my mother tongue.

As for the problem you talk about later on, probably you should check your firewall settings. I don't see any issues with this UDF.

 

As I wrote my UDF compiles and runs. I just tested my UDF with a firewall turned off, I got the same errors. I copied both files (WinHttp.au3 and WinHttpConstants.au3) in the script directory and in the Autoit include directory. I guess I'm doing something wrong, because the WinHTTP-Function return @error 1, the docu tells me that means Dll call failed. I have no idea how to solve this error and my google search just returned these 2 posts for my problem. I hope somebody here can help me with these errors.

Share this post


Link to post
Share on other sites

First part means I don't know what are you talking about.

Second part means I have no idea what the problem could be. Post the exact code, the exact code you run without any sort of modifications. google.com doesn't have index.html.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

First part means I don't know what are you talking about.

 

I'm sorry the first part of my first post in this thread was me coping to much, just ignore it.

Second part means I have no idea what the problem could be. Post the exact code, the exact code you run without any sort of modifications. google.com doesn't have index.html.

 

I changed from an _WinHttpSendRequest() to _WinHttpSimpleSSLRequest() and the error of the failed DLL-Call is gone. I have no idea, why but it works now. I will post my working UDF with this post, maybe it is usefull for somebody.

#Region                                                                         ; **** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=my_icon.ico
#AutoIt3Wrapper_Compression=0
#EndRegion
#include <Misc.au3>
#include <File.au3>
#include <WinHttp.au3>
_Singleton( StringReplace(@ScriptName, ".exe", "") )                            ; prevents multiple starts of this script
;#NoEnv                                                                         ; recommended for performance and compatibility with future AutoHotkey releases
;#Warn                                                                          ; enable warnings to assist with detecting common errors
Opt("WinTitleMatchMode", 1)                                                     ; 1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=force lower case match according to other type of match.
Opt("MustDeclareVars", 1)
Global $HttpStatus = 0                                                          ; _MakeHttpRequest() will fill this variable.
Global $FilenameWithExtension = StringReplace(@ScriptName, ".exe", "") & ".log"


Func _MakeHttpRequest ()
    Local $hSession = _WinHttpOpen('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0')
    Local $sHost = 'google.com'
    Local $hConnect = _WinHttpConnect($hSession, $sHost)
    Local $sResult = _WinHttpSimpleSSLRequest($hConnect, 'GET', '', Default, Default, Default, True, Default)

    If @error Then
        $HttpStatus = -1
        _WriteLogLine("--> Error Nr. " & @error & ": in  _MakeHttpRequest(), the Funktion  _WinHttpSimpleSSLRequest() returned this error code.")
    Else
        Local $aHeaderPart = StringSplit($sResult[0]," ")                                       ; extract HTTP Statuscode from full header
        $HttpStatus = $aHeaderPart[2]                                                           ; 2nd Array Element is the HTTP Status.
        _WriteLogLine("HTTP Status is: " & $HttpStatus & ".")                                   ; write into the logfile.
    EndIf
    _WinHttpCloseHandle($hConnect)                                                              ; Clean
    _WinHttpCloseHandle($hSession)                                                              ; Clean
EndFunc


Func _WriteLogLine($StringToLog=Default)
    Local $hFile = FileOpen(@ScriptDir & "\" & $FilenameWithExtension, 257)                     ; Open logfile in the same directory named like the exe, but with log extension. Create logfile, if necessary.
                                                                                                ;   129 = Verwende Unicode-UTF8 Kodierung im Lese- und Schreib- Anhängmodus. Lesen überschreibt ein existierendes BOM nicht.
                                                                                                ;   256 = Verwende Unicode-UTF8 (ohne BOM) im Lese- und Schreib- Anhängmodus.
    _FileWriteLog($hFile, $StringToLog)                                                         ; Write string to logfile.
    Sleep(1000)                                                                                 ; Wait 1 second.
    FileClose($hFile)                                                                           ; Close logfile.
EndFunc


While True
    _MakeHttpRequest ()
    Sleep(600000)                                                                               ; Wait 10minutes.
Wend

Thanks for your responses trancexx. :)

Share this post


Link to post
Share on other sites

Hi trancexx,

Can you please show me any direction to send "multipart/form-data" from main loop or in asynchronous mode? because I am unable to control "_WinHttpWriteData" as I can do via $iNumberOfBytesToRead parameter of "_WinHttpReadData".

I am trying to create multiple file uploader and want to show progress of each file.
 

I read on MSDN about WinHttpWriteData:
 

 

If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to the server:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_DATA_WRITTEN
  • WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
  • WINHTTP_CALLBACK_STATUS_REQUEST_SENT

I am assuming that I can get the required details from WINHTTP_CALLBACK_STATUS_DATA_WRITTEN but this flag is not mentioned in UDF docs nor in MSDN docs, is there any other flag where from I can get the desired info ?

Edited by Digisoul

73 108 111 118 101 65 117 116 111 105 116

Share this post


Link to post
Share on other sites

Hi there,

is there a way to get the URL or parts of it from the response of _WinHttpSimpleSSLRequest()? What I do is querrieng a domain with an empty request path, I get the answer as an array like it is documented. I can extract the HTTP statuscode, the HTML sources and other information from that array, but I can't find the information in there if the response came from file_a.html or file_b.html. What I try to do is detecting the end of a maintenance of a game, which I play, since the game news take a day to be translated and the maintenance lasts 2-4 hours usually.

Regards

Share this post


Link to post
Share on other sites

I'm not sure if this is something that could be useful for you:

#include "WinHttp.au3"


; Register Callback function
$hWINHTTP_STATUS_CALLBACK = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword")

; Initialize and get session handle
$hOpen = _WinHttpOpen()

; Get connection handle
$hConnect = _WinHttpConnect($hOpen, "https://google.com")
; Set callback
_WinHttpSetStatusCallback($hConnect, $hWINHTTP_STATUS_CALLBACK)

; Read data
$sReturned = _WinHttpSimpleSSLRequest($hConnect)

; Clean
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)

ConsoleWrite($sReturned & @CRLF)

; THE END



; Define callback function
Func __WINHTTP_STATUS_CALLBACK($hInternet, $iContext, $iInternetStatus, $pStatusInformation, $iStatusInformationLength)
    ; Interpret the status
    If $iInternetStatus = $WINHTTP_CALLBACK_STATUS_REDIRECT Then
        $sStatus = "About to automatically redirect the request to: " & DllStructGetData(DllStructCreate("wchar[" & $iStatusInformationLength & "]", $pStatusInformation), 1) & "    "
        ConsoleWrite("!>" & $sStatus & @CRLF)
        MsgBox(4096, "REDIRECTION:", $sStatus)
    EndIf
EndFunc

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Hi @trancexx,
I'm trying to run WinHttp without waitting (because WinHttp that causes to lag my GUI, WinHttp wait for the response by _WinHttpReceiveResponse).
I think i have 2 way to do that:

1, Non ASYNC mode, i try put  _WinHttpReceiveResponse in Func __WINHTTP_STATUS_CALLBACK, like ASYNC mode, but it don't work, why?
2, ASYNC mode, i use example in _WinHttpSimpleReadDataAsync. I add a second request below code MsgBox (*dummy code for waiting*). when i run it:

sendrequest_1
msgbox(0,"",""); Some dummy code for waiting
sendrequest_2

+>While first request doesn't finish, if i press ok in msgbox (continue with second request), script will crash.
+>If i wait first request done ($WINHTTP_CALLBACK_STATUS_READ_COMPLETE return) and after that press ok, script will run correctly.
So i check request finish by add var "$data_available = True" in case $WINHTTP_CALLBACK_STATUS_READ_COMPLETE
 and don't use msgbox, like that:

while 1
..
   if $abc=true then
       sendrequest_1
   endif 
   if $data_available=true then
       sendrequest_2
       ...
   endif
..
wend

but my script still crash.
is this problem "another or the same callback is called and the old hasn't finished, it will interrupt the old callback, too and execute itself"??!
i also try volatile Func __WINHTTP_STATUS_CALLBACK?? (i don't know i use it for what :D ), and nothing changes except the script crash without notice "Variable used without being declared."..

i hope you can understand what I write, my english is so bad :wacko:

Thanks for your time to read it. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...