frank10 Posted June 4, 2011 Share Posted June 4, 2011 (edited) Can you give me the exact code? I can't make it crash here (win 7 x64) no matter what I do. What system are you running the script on? I tried this script with dozens calls every 1sec at different server with no crash at all. WinXP SP2, all working well, here. Example code: expandcollapse popup#include "WinHttp.au3" ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; Reserve memory space for asynchronous work ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; The size Global Const $iSizeBufferAsync = 1048576 ; 1MB for example, should be enough ; The buffer Global Static $tBufferAsync = DllStructCreate("byte[" & $iSizeBufferAsync & "]") ; Get pointer to this memory space Global $pBufferAsync = DllStructGetPtr($tBufferAsync) php("google.com", "") Sleep(1000) php("msdn.microsoft.com","en-us/library/aa383917(v=vs.85).aspx") Sleep(1000) exit func php($server,$url) ; Register Callback function Global $hWINHTTP_STATUS_CALLBACK = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword") ; Initialize and get session handle. Asynchronous flag. Global $hOpen = _WinHttpOpen(Default, Default, Default, Default, $WINHTTP_FLAG_ASYNC) ; Assign callback function _WinHttpSetStatusCallback($hOpen, $hWINHTTP_STATUS_CALLBACK) ; Get connection handle Global $hConnect = _WinHttpConnect($hOpen, $server) ; Make request Global $hRequest = _WinHttpOpenRequest($hConnect, Default, $url) ; Send it _WinHttpSendRequest($hRequest) ; Some dummy code for waiting Sleep(2000) ; Close handles _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) ; Free callback. Redundant here DllCallbackFree($hWINHTTP_STATUS_CALLBACK) EndFunc ;php ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; Define callback function ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Func __WINHTTP_STATUS_CALLBACK($hInternet, $iContext, $iInternetStatus, $pStatusInformation, $iStatusInformationLength) #forceref $hInternet, $iContext, $pStatusInformation, $iStatusInformationLength ConsoleWrite(">> ") ; Interpret the status 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." ConsoleWrite($sStatus & @CRLF) ;************************************* ; Receive Response ;************************************* _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 Edited June 4, 2011 by frank10 Link to comment Share on other sites More sharing options...
frank10 Posted June 4, 2011 Share Posted June 4, 2011 Ok, I found a crash... but I don't know why, repeating the exact code worked well.. Another problem is If one call to a server and it doesn't respond immediately, you put the msgbox after the sendRequest, but in a real script how can you wait asyncronously for the server's answer? If you put a Do... until linked to some @error or other check, you block the script and it's no more async. If you put a generic sleep, you can't fit the exact server time and if you put a sleep too short the connection close and the server's echo doesn't get anymore... So it seems it's not real async. Link to comment Share on other sites More sharing options...
ProgAndy Posted June 4, 2011 Share Posted June 4, 2011 (edited) It is strange. Currently I cannot reproduce the error no matter what I do. I only get it to crash if I use _WinHttpReceiveResponse outside of __WINHTTP_STATUS_CALLBACK now. AutoIt:3.3.6.1 X64, AutoIt:3.3.6.1 X86, AutoIt:3.3.7.8/X64 AutoIt:3.3.7.8/X86 (Os:WIN_7/SP1/X64 OSLang:0407) This was the script: expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include "WinHttp.au3" #include "Debug.au3" ConsoleWrite( _DebugBugReportEnv( ) & @CRLF) Opt("MustDeclareVars", 1) ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; Reserve memory space for asynchronous work ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; The size Global Const $iSizeBufferAsync = 1048576 ; 1MB for example, should be enough ; The buffer Global Static $tBufferAsync = DllStructCreate("byte[" & $iSizeBufferAsync & "]") ; Get pointer to this memory space Global $pBufferAsync = DllStructGetPtr($tBufferAsync) ; Register Callback function Global $hWINHTTP_STATUS_CALLBACK = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword") ; Initialize and get session handle. Asynchronous flag. Global $hOpen = _WinHttpOpen(Default, Default, Default, Default, $WINHTTP_FLAG_ASYNC) ; Assign callback function _WinHttpSetStatusCallback($hOpen, $hWINHTTP_STATUS_CALLBACK) ; Get connection handle Global $hConnect = _WinHttpConnect($hOpen, "msdn.microsoft.com") ; Make request Global $hRequest = _WinHttpOpenRequest($hConnect, Default, "en-us/library/aa383917(v=vs.85).aspx") ; Send it _WinHttpSendRequest($hRequest) ; Some dummy code for waiting MsgBox(64 + 262144, "Wait...", "Wait for the results if they are not shown already.") ; 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 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." 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." 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." 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." Case $WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE $sStatus = "Data was successfully written to the server." EndSwitch ; Print it ConsoleWrite($sStatus & @CRLF) EndFunc ;==>__WINHTTP_STATUS_CALLBACK Edit: This is a game of luck. I added _WinHttpQueryDataAvailable($hInternet) to $WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE and _WinHttpReceiveResponse($hInternet) to $WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE. Now I got some crashes again. (AutoIt simply exits with exitcode 1 or "Variable not declared" or a windows crash message.) It just depends on when the callback is actially called I think. Edited June 4, 2011 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
wraithdu Posted June 4, 2011 Share Posted June 4, 2011 I don't think you should be testing with a blocking function like MsgBox. It would be safer to use a while - sleep - wend loop that checks for a global flag to exit the loop. It's kinda like the warning AutoIt has about using blocking functions inside a GuiRegisterMsg callback. Link to comment Share on other sites More sharing options...
wraithdu Posted June 4, 2011 Share Posted June 4, 2011 Another problem is If one call to a server and it doesn't respond immediately, you put the msgbox after the sendRequest, but in a real script how can you wait asyncronously for the server's answer?If you put a Do... until linked to some @error or other check, you block the script and it's no more async.That's not true. AutoIt can do whatever it wants during Sleep(), it is not considered a 'blocking' function like MsgBox. So a while - sleep - wend loop with a global exit flag is perfect for async and callbacks. You just have to know when to set the loop's exit flag from the callback. Link to comment Share on other sites More sharing options...
ProgAndy Posted June 4, 2011 Share Posted June 4, 2011 Asynchronous WinHttp has to be able to execute multiple requests at the same time. Here is an example that is crashing each time I execute it. expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include "WinHttp.au3" #include "Debug.au3" ConsoleWrite( _DebugBugReportEnv( ) & @CRLF) Opt("MustDeclareVars", 1) ; Register Callback function Global $hWINHTTP_STATUS_CALLBACK = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword") ; Initialize and get session handle. Asynchronous flag. Global $hOpen = _WinHttpOpen(Default, Default, Default, Default, $WINHTTP_FLAG_ASYNC) ; Assign callback function _WinHttpSetStatusCallback($hOpen, $hWINHTTP_STATUS_CALLBACK) Global $EXIT = 0 Global $hConnect[10], $hRequest[10] Global $aSites[10] = ["google.de", "autoitscript.com", "autoit.de", "msdn.microsoft.com", "google.com", "live.com", "web.de", "aol.com", "miranda-im.org", "dropbox.com"] For $i = 0 To 9 ; Get connection handle $hConnect[$i] = _WinHttpConnect($hOpen, $aSites[$i]) ; Make request $hRequest[$i] = _WinHttpOpenRequest($hConnect[$i], Default, "/") ; Send it _WinHttpSendRequest($hRequest[$i]) Next Do Sleep(20) Until $EXIT = 10 ; Close handles For $i = 0 To 9 _WinHttpCloseHandle($hRequest[$i]) _WinHttpCloseHandle($hConnect[$i]) Next _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 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." 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." _WinHttpQueryDataAvailable($hInternet) $EXIT += 1 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." 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) Case $WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE $sStatus = "Data was successfully written to the server." EndSwitch ; Print it ConsoleWrite($sStatus & @CRLF) EndFunc ;==>__WINHTTP_STATUS_CALLBACK *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
frank10 Posted June 4, 2011 Share Posted June 4, 2011 Well, yes but he has put MsgBox after the SendRequest, not into the callback func. So if you make a Func to handle the http calls to the server and put some While-Sleep, you end up blocking the entire script. He should put the While-sleep inside the callback func, so if it's fired several times can have some instances blocked by the while-sleep while the rest of script continues. I hope understanding how autoit uses callback func and sleep cycles... But in the way he coded the async example, if you substitute a msgbox with a sleep you block the entire script. Link to comment Share on other sites More sharing options...
frank10 Posted June 4, 2011 Share Posted June 4, 2011 Asynchronous WinHttp has to be able to execute multiple requests at the same time. Here is an example that is crashing each time I execute it. expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include "WinHttp.au3" #include "Debug.au3" ConsoleWrite( _DebugBugReportEnv( ) & @CRLF) Opt("MustDeclareVars", 1) ; Register Callback function Global $hWINHTTP_STATUS_CALLBACK = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword") ; Initialize and get session handle. Asynchronous flag. Global $hOpen = _WinHttpOpen(Default, Default, Default, Default, $WINHTTP_FLAG_ASYNC) ; Assign callback function _WinHttpSetStatusCallback($hOpen, $hWINHTTP_STATUS_CALLBACK) Global $EXIT = 0 Global $hConnect[10], $hRequest[10] Global $aSites[10] = ["google.de", "autoitscript.com", "autoit.de", "msdn.microsoft.com", "google.com", "live.com", "web.de", "aol.com", "miranda-im.org", "dropbox.com"] For $i = 0 To 9 ; Get connection handle $hConnect[$i] = _WinHttpConnect($hOpen, $aSites[$i]) ; Make request $hRequest[$i] = _WinHttpOpenRequest($hConnect[$i], Default, "/") ; Send it _WinHttpSendRequest($hRequest[$i]) Next Do Sleep(20) Until $EXIT = 10 ; Close handles For $i = 0 To 9 _WinHttpCloseHandle($hRequest[$i]) _WinHttpCloseHandle($hConnect[$i]) Next _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 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." 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." _WinHttpQueryDataAvailable($hInternet) $EXIT += 1 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." 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) Case $WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE $sStatus = "Data was successfully written to the server." EndSwitch ; Print it ConsoleWrite($sStatus & @CRLF) EndFunc ;==>__WINHTTP_STATUS_CALLBACK In my pc your code ( copy & paste ) works every time. Link to comment Share on other sites More sharing options...
trancexx Posted June 4, 2011 Author Share Posted June 4, 2011 (edited) ProgAndy is right of course. I'll add few notes to the help file for the next release. Strangely, it just won't crash for me. I should play the lottery. Just to clear one thing up... ProgAndy if you split the code to 10 sessions running at the same time and you set one callback for every session (the same callback function registered 10 times or just once), does it crash then? Edited June 4, 2011 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
frank10 Posted June 4, 2011 Share Posted June 4, 2011 (edited) I deleted the msgbox or the sleep after the SendRequest and moved the closeHandles into the callback func after the print data: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) _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen)the rest of code is like my previous This way it automatically waits from the server and only when it gots all, closes handles.This works also with multi calls that 'overlaps' themselves: if one call hasn't finished its job, you can continue calling other urls, and when the old data arrives it works well.I found consistent crash if I add DllCallbackFree($hWINHTTP_STATUS_CALLBACK) after closing handles in the callback func.Anyway it doesn't seem to be necessary...EDIT: CallbackFree shouldn't be used when some handles are still alive, so it should be checked when the last handle closes, then use DllCallBackFree...BUT, even with one unique call, after closing all handles, it crashes if called from Callback func. Edited June 5, 2011 by frank10 Link to comment Share on other sites More sharing options...
liuyifan494 Posted June 5, 2011 Share Posted June 5, 2011 Thank you for sharing ! Link to comment Share on other sites More sharing options...
ProgAndy Posted June 5, 2011 Share Posted June 5, 2011 (edited) Just to clear one thing up... ProgAndy if you split the code to 10 sessions running at the same time and you set one callback for every session (the same callback function registered 10 times or just once), does it crash then? It still crashes: expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include "WinHttp.au3" #include "Debug.au3" ConsoleWrite( _DebugBugReportEnv( ) & @CRLF) Opt("MustDeclareVars", 1) Global Const $count = 10 ; How many pages shall be opened (10 is maximum) Global $EXIT = 0 Global $hConnect[10], $hRequest[10] Global $hWINHTTP_STATUS_CALLBACK[10], $hOpen[10] For $i = 0 To $count-1 ; Register Callback function $hWINHTTP_STATUS_CALLBACK[$i] = DllCallbackRegister("__WINHTTP_STATUS_CALLBACK", "none", "handle;dword_ptr;dword;ptr;dword") ; Initialize and get session handle. Asynchronous flag. $hOpen[$i] = _WinHttpOpen(Default, Default, Default, Default, $WINHTTP_FLAG_ASYNC) ; Assign callback function _WinHttpSetStatusCallback($hOpen[$i], $hWINHTTP_STATUS_CALLBACK[$i]) Global $aSites[10] = ["google.de", "autoitscript.com", "autoit.de", "msdn.microsoft.com", "google.com", "live.com", "web.de", "aol.com", "miranda-im.org", "dropbox.com"] ; Get connection handle $hConnect[$i] = _WinHttpConnect($hOpen[$i], $aSites[$i]) ; Make request $hRequest[$i] = _WinHttpOpenRequest($hConnect[$i], Default, "/") ; Send it _WinHttpSendRequest($hRequest[$i]) Next Do Sleep(20) Until $EXIT = $count ; Close handles For $i = 0 To 9 _WinHttpCloseHandle($hRequest[$i]) _WinHttpCloseHandle($hConnect[$i]) _WinHttpCloseHandle($hOpen[$i]) ; Free callback. Redundant here DllCallbackFree($hWINHTTP_STATUS_CALLBACK[$i]) Next ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; Define callback function ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Func __WINHTTP_STATUS_CALLBACK($hInternet, $iContext, $iInternetStatus, $pStatusInformation, $iStatusInformationLength) #forceref $hInternet, $iContext, $pStatusInformation, $iStatusInformationLength ConsoleWrite(">> ") ; Interpret the status 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." 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." _WinHttpQueryDataAvailable($hInternet) $EXIT += 1 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." 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) Case $WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE $sStatus = "Data was successfully written to the server." EndSwitch ; Print it ConsoleWrite($sStatus & @CRLF) EndFunc ;==>__WINHTTP_STATUS_CALLBACK AutoIt:3.3.6.1/X64 (Os:WIN_7/X64/Service Pack 1 Language:0407 Keyboard:00000407 Cpu:X64) D:\Dokumente\AutoIt3\UDF\WinHttp.au3 (795) : ==> Subscript used with non-Array variable.: If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) If @error Or Not $aCall^ ERROR ... D:\Dokumente\AutoIt3\winhttptest.au3 (59) : ==> Variable used without being declared.: Switch $iInternetStatus Switch ^ ERROR Similar errors with beta and in x86 mode. Sometimes even a Windows crash dialog. Edited June 5, 2011 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
Fly By Night Posted June 16, 2011 Share Posted June 16, 2011 Hi I'm trying to catch a 302 redirect but when i disable redirects using _WinHttpSetOption, the request still goes on to the final page. My code is based on one of your examples. Also i'm not sure if i'm using _WinHttpAddRequestHeaders correctly. Any help would be appreciated, thanks. ; Initialize and get session handle Global $hOpen = _WinHttpOpen() _WinHttpSetOption($hOpen, $WINHTTP_OPTION_DISABLE_FEATURE, $WINHTTP_DISABLE_REDIRECTS) ; Get connection handle Global $hConnect = _WinHttpConnect($hOpen, "u.to") ; Request Global $hRequest = _WinHttpOpenRequest($hConnect, "GET", "/6GECAQ") _WinHttpAddRequestHeaders($hRequest, "Host: u.to") _WinHttpAddRequestHeaders($hRequest, "User-Agent: Sausage Head/5.0") _WinHttpSendRequest($hRequest) _WinHttpReceiveResponse($hRequest) Global $sHeader = _WinHttpQueryHeaders($hRequest) ; Close handles _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) MsgBox(0, "Header", $sHeader) Link to comment Share on other sites More sharing options...
ProgAndy Posted June 16, 2011 Share Posted June 16, 2011 If you want to disable redirects globally, you have to use _WinHttpSetOption($hOpen, $WINHTTP_OPTION_REDIRECT_POLICY, $WINHTTP_OPTION_REDIRECT_POLICY_NEVER)$WINHTTP_OPTION_DISABLE_FEATURE works only for request handles, in your case $hRequest.This infomration can be found in the Remarks-section hereThe two calls to _WinHttpAddRequestHeaders are unneccessary since Host is automatically set and the User-Agent is set with _WinHttpOpen *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
Fly By Night Posted June 16, 2011 Share Posted June 16, 2011 (edited) If you want to disable redirects globally, you have to use _WinHttpSetOption($hOpen, $WINHTTP_OPTION_REDIRECT_POLICY, $WINHTTP_OPTION_REDIRECT_POLICY_NEVER) $WINHTTP_OPTION_DISABLE_FEATURE works only for request handles, in your case $hRequest. This infomration can be found in the Remarks-section here The two calls to _WinHttpAddRequestHeaders are unneccessary since Host is automatically set and the User-Agent is set with _WinHttpOpen Thanks for the quick reply. All working now, typical i missed the one setting when looking at the options. I have one scenario where i need to replicate a feature of cURL (SSL) This option explicitly allows curl to perform "insecure" SSL connections and transfers. All SSL connections are attempted to be made secure by using the CA certificate bundle installed by default. This makes all connections considered "insecure" fail unless -k/--insecure is used. I'm using cURL just now a few functions but trying to move them in AutoIt. For the above, i'm grabbing a link from multiupload.com and it's redirecting to rapidshare which seems to use https. I use the -k option to get around the certificate issue which seems to get me the data required. I've tried setting a few options in WinHTTP but no luck. Do you have any idea how to do this at all? Thanks again. WINHTTP_OPTION_CLIENT_CERT_CONTEXT seems to be the nearest option but i'm not sure how to get this working with WinHTTP.au3 as it doesn't seem supported. Edited June 16, 2011 by Fly By Night Link to comment Share on other sites More sharing options...
FireFox Posted June 16, 2011 Share Posted June 16, 2011 @trancexx When submitting a post form with a file, is it possible to : -Avoid the gui to freeze -Have a progress bar of file upload/form submit ? Br, Firefox. Link to comment Share on other sites More sharing options...
trancexx Posted June 16, 2011 Author Share Posted June 16, 2011 @trancexxWhen submitting a post form with a file, is it possible to :-Avoid the gui to freeze-Have a progress bar of file upload/form submit ?Br, Firefox.You can do that with AutoItObject. Compile server script to a3x and include it with installation. Make it export upload object. It would be very advanced besides simple. Use your imagination. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
ProgAndy Posted June 16, 2011 Share Posted June 16, 2011 (edited) As an alternative, do the post manually. Send the data in chunks with _WinHttpSendData. To improve the GUI-response, you could create a thread in assembler that sends the data. (The thread could be in a DLL, too) Edited June 16, 2011 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
FireFox Posted June 16, 2011 Share Posted June 16, 2011 As an alternative, do the post manually. Send the data in chunks with _WinHttpSendData.Good idea, not sure I will be able to make it work.To improve the GUI-response, you could create a thread in assembler that sends the data. (The thread could be in a DLL, too)That's what I want but with my knowledge it's impossible...Br, FireFox. Link to comment Share on other sites More sharing options...
Mithrandir Posted June 17, 2011 Share Posted June 17, 2011 I have a problem working with this API: http://linksave.in/api Here it's what it says: For registered users: The following data has to be sent by POST to our API: They are: URL: http://linksave.in/protect?api=[username]:[Password] Field name: Value: *save = TRUE *links = [Links](seperated each by a line break "\n") mirrors = [Mirrorlinks](seperated each by a line break "\n") foldername = [Name of the folder] myprotection = container_js (Container and webprotection) container_plain (Container and premiumlinks) container (only container plain (only Premiumlinks) js (only Webprotection) container_types = rsdf ccf and/or dlc(not seperated) container_name = [only Webprotection](if empty then foldername) category = [name or number of the cateorgy, in which the folder will be moved; 0 for no category] advertisement = banner bannerurl = [bannerurl](URL to bannerpicture) bannerlink = [bannerlink](Link banner with this URL) location = captchaseite(Show banner on captchapage) frame(Show banner in hosterframe) unten(Show banner below the links) oben(Show banner above the links) adminpassword = [adminpassword](if empty then random password) visitorpassword = [Password to visit the folder] cover = [Describing picture of the folder contents] website = URL to your website captcha = on or off notify = 1 or 0 (Notification if files are offline) email = [E-mail-address for notifications] * = Required Improtant: If you leave one or more fields empty, the corresponding value from your userCP-settings will apply. Return values: Standard = http://linksave.in/[Folder-ID] [On error(s)] = ERROR [Exact Errormessage(s)](seperated each by"|") The problem that I found is that I find the documentation quite ambiguous or maybe it's my lack of experience, anyway I coded this: #include <WinHttp.au3> Global $sUserName = "Myuser" Global $sPassword = "Mypass" Global $sDomain = "www.linksave.in" Global $sLinks = "http://www.fileserve.com/file/bByhbBm" Global $sAdditionalData = "save=TRUE&links="&$sLinks&"foldername=testfolder&captcha=off" ;Global $sAdditionalData = "ordnername=testfolder&links=http%3A%2F%2Fwww.fileserve.com%2Ffile%2FbByhbBm"& _ ;"myschutz=container_js&container_rsdf=1&container_ccf=1&container_dlc=1&captcha=N" Global $hOpen = _WinHttpOpen("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6") Global $hConnect = _WinHttpConnect($hOpen, $sDomain) Global $hRequest = _WinHttpOpenRequest($hConnect, "POST","/protect?api="&$sUserName&":"&$sPassword) _WinHttpSendRequest($hRequest, "Content-Type: application/x-www-form-urlencoded", $sAdditionalData) _WinHttpReceiveResponse($hRequest) Global $sReturned If _WinHttpQueryDataAvailable($hRequest) Then Do $sReturned &= _WinHttpReadData($hRequest) Until @error EndIf _WinHttpCloseHandle($hRequest) _WinHttpCloseHandle($hConnect) _WinHttpCloseHandle($hOpen) MsgBox(0, "Returned", $sReturned) ConsoleWrite($sReturned) FileWrite(@ScriptDir&'/htmlreturned.html',$sReturned) I even saved a link manually and traced the process with live http headers in firefox. I saw that the additional data was sent in german so I try that -That's the 'Global...' that is commented in the code- but it didn't function either. In both cases it returns the page in the html as if I had used a get request and not http://linksave.in/[Folder-ID] or ERROR I'm quite puzzled. Could you help me or give me some directions? Thanks for your help! Help with SOAP message!! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now