toby9999 Posted March 30, 2021 Posted March 30, 2021 (edited) Hi I've hit a strange issue when doing a HTTP POST call using the WinHTTP COM object in Windows 10. When I run a script in SCITE (pressing F5 - Run), my script works. When I run a script with "autoit3.exe myscript.au3" on the windows cmd prompt, it doesn't work - the WinHTTP COM object throws an error stating "the requested action with this object has failed". However, it gets weird... If I call $oHTTP.SetRequestHeader("Authorization", "Bearer xoxb-..."), ie with the string directly in the call, it works in both cases. If I call $sAuthString = '"Authorization", "Bearer xoxb-..."' (FYI for clarity in this posting, that's a pair of single quotes surrounding the string), followed by... $oHTTP.SetRequestHeader($sAuthString), ie with the string in a variable, it only works in SCITE, *not* on the command line. When I MsgBox both versions (direct string vs string variable), it shows both strings looking identical as far as I can tell. So it seems like, when calling from the command line, the $sAuthString... assignment is somehow mangling the string?? I'm fairly new to AutoIT, so maybe there's something special I need to setup? TIA Edited March 31, 2021 by toby9999
Dan_555 Posted March 30, 2021 Posted March 30, 2021 I can only guess. Maybe the processes (the autoit.exe and the com proccess) are on the different user level, when ran from the cmd. Have you tried to start the cmd on the admin mode ? Quote Press Windows+R to open the “Run” box. Type “cmd” into the box and then press Ctrl+Shift+Enter to run the command as an administrator Alternatively, try to set the autoit3.exe to run as admin, as well. Some of my script sourcecode
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 8 hours ago, Dan_555 said: I can only guess. Maybe the processes (the autoit.exe and the com proccess) are on the different user level, when ran from the cmd. Have you tried to start the cmd on the admin mode ? Alternatively, try to set the autoit3.exe to run as admin, as well. I've just tried all the "run as admin" options but the problem stills persists unfortunately.
argumentum Posted March 31, 2021 Posted March 31, 2021 if you compile it, does it fail ? Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 6 minutes ago, argumentum said: if you compile it, does it fail ? Yes, still failing unfortunately. Is there any advanced logging or something I can enable to capture for info maybe?
argumentum Posted March 31, 2021 Posted March 31, 2021 you can compile as CUI and ConsoleWrite() or FileWriteLine(). You can get fancier too. For fancier you'll have to look around as there are too many to mention. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 11 minutes ago, argumentum said: you can compile as CUI and ConsoleWrite() or FileWriteLine(). You can get fancier too. For fancier you'll have to look around as there are too many to mention. I'll give it a go, thanks
TheXman Posted March 31, 2021 Posted March 31, 2021 (edited) Can you provide your script with any sensitive parts, like the authorization token, redacted? There's not enough information to know what the issue is. Do you not have a COM error handler in your script? If you do, can you provide the .number, .windescription, .description, and .retcode property values of the error object? Edited March 31, 2021 by TheXman Fixed typo CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 7 minutes ago, TheXman said: Can you provide your script with any sensitive parts, like the authorization token, redacted? There's not enough information to know what the issue is. Do you not have a COM error handler in your script? If you do, can you provide the .number, .windescription, .description, and .retcode property values of the error object? Will do. I'll add the extra COM error capturing code and get back to you with the results. Thanks.
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 #include <MsgBoxConstants.au3> Local $sOut = "" Local $sAuthString = "" $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("POST", "https://slack.com/api/chat.postMessage", False) $oHTTP.SetRequestHeader("Content-Type", "application/json; charset=utf-8") ; OPTION 1: call SetRequestHeader with auth string directly - this works correctly with (a) Running within SCiTE (F5) and (b) Running from cmd prompt (both .exe and "autoit3.exe test.au3") $oHTTP.SetRequestHeader("Authorization", "Bearer xoxb-<obfuscated>") ; OPTION 2: call SetRequestHeader with auth string in a string variable - this works correctly with (a) Running within SCiTE (F5), BUT DOES NOT WORK with (b) Running from cmd prompt (both .exe and "autoit3.exe test.au3") ; When option 2 fails (at the $oHTTP.SetRequestHeader command), the error is "The requested action with this object failed" (see attached image) $sAuthString = '"Authorization", "Bearer xoxb-<obfuscated>"' $oHTTP.SetRequestHeader($sAuthString) $sOut = '{"channel":"#script-notifications", "text":"Test message", "icon_emoji":":information_source:"}' $oHTTP.Send($sOut) $sStatusCode = $oHTTP.Status $sResponse = $oHTTP.ResponseText MsgBox($MB_OK,"", "SlackOut: " & @CR & $sOut) MsgBox($MB_OK,"", "SlackStatus: " & @CR & $sStatusCode) MsgBox($MB_OK,"", "SlackResponse: " & @CR & $sResponse) 56 minutes ago, TheXman said: Can you provide your script with any sensitive parts, like the authorization token, redacted? There's not enough information to know what the issue is. Do you not have a COM error handler in your script? If you do, can you provide the .number, .windescription, .description, and .retcode property values of the error object? Will do. I'll add the extra COM error capturing code and get back to you with the results. Thanks.
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 I've added comments in the code I posted.
TheXman Posted March 31, 2021 Posted March 31, 2021 (edited) First, you do not need to quote the whole prior post. If you need to quote anything, make it just the relevant parts. Your option 2 is incorrect. The SetRequestHeader method takes 2 parameters, the header name and the header value. You cannot pass it in a single string like that. So either stick with option 1 or pass 2 variables, one for the name and one for the value, like: $sHeaderName = "Authorization" $sHeaderValue = "Bearer abc" $oHTTP.SetRequestHeader($sHeaderName, $sHeaderValue) Also, you said that option 2 worked when you executed it in scite with F5. It doesn't work for me so I'm not sure how it worked for you, unless you did it differently than the example that you posted. Other than that, I get back a valid json error response saying my authorization is invalid, which is expected. I get the same thing whether I run it within scite or from a command line in a cmd console. Where is your COM error handling? Actually, where is any error checking at all? You really should get in the habit of adding error and return checking. It will make your scripting life much easier. 😀 Edited March 31, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 That's great, it's working now. I had been working on the incorrect assumption that I needed to pass the full string as the header as a SINGLE PARAMETER, including the double quotes and the comma. Whereas your syntax passes TWO parameters to the header. Thanks so much for your assistance ... I'd probably have been stuck for days searching for an answer otherwise. Regarding error checking, I do have some basic error checking in the rest of my code (the code I posted here was just an extract of the problem section). Having said that, I'm actually not sure how to do error checking for the HTTP code because it's calling a COM object, so I can't use AutoIT commands like @error. If you don't mind, could you please point me to some documentation or a script example for that? I very much do want to add some HTTP/COM error checking if possible. P.S. I snuck a look at your HTTP Server function, and you've given me some good ideas for formatting my code more neatly (I'm very much a noob with AutoIT). Cheers
TheXman Posted March 31, 2021 Posted March 31, 2021 (edited) 7 minutes ago, toby9999 said: Having said that, I'm actually not sure how to do error checking for the HTTP code because it's calling a COM object, so I can't use AutoIT commands like @error. If you don't mind, could you please point me to some documentation or a script example for that? I very much do want to add some HTTP/COM error checking if possible. Here's a working example of an HTTP POST with error checking. If you force errors, like giving it a badly formatted URL or making a COM error like using .SetHeaders instead of .SetRequestHeader, you will see how the error checking and COM error handler works. expandcollapse popup#include <Constants.au3> http_post_example() Func http_post_example() Const $POST_DATA = '{"fld1": "This is a test string", "fld2": true}' Local $oHttp = Null, $oComErr = Null ;Register COM Error Handler $oComErr = ObjEvent("AutoIt.Error", com_error_handler) If @error Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Unable to register COM error handler - @error = " & @error) ;Create HTTP COM object $oHttp = ObjCreate("winhttp.winhttprequest.5.1") If @error Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Unable to create HTTP COM object - @error = " & @error) With $oHttp ;Open POST request, set request header(s), and send the request .Open("POST", "https://jsonplaceholder.typicode.com/posts") If @error Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", StringFormat("(0x%X) %s", $oComErr.RetCode, $oComErr.WinDescription)) .SetRequestHeader("Content-Type", "application/json") .Send($POST_DATA) If @error Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", StringFormat("(0x%X) %s", $oComErr.RetCode, $oComErr.Description)) ConsoleWrite(StringFormat("HTTP Status: %s %s", .Status, .StatusText) & @CRLF) ;If http status code not 201, exit with message If .Status <> 201 Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", StringFormat("HTTP Status Code = %s %s", .Status, .StatusText)) ;Display response ConsoleWrite(@CRLF & "HTTP Response:" & @CRLF) ConsoleWrite(.ResponseText & @CRLF) EndWith EndFunc Func com_error_handler($oError) With $oError ConsoleWrite(@ScriptName & " (" & .scriptline & ") : ==> COM Error intercepted !" & @CRLF) ConsoleWrite(@TAB & "Error Number........... " & "0x" & Hex(.number) & @CRLF) ConsoleWrite(@TAB & "Error WinDescription... " & StringStripWS(.windescription, $STR_STRIPTRAILING) & @CRLF) ConsoleWrite(@TAB & "Error Description...... " & StringStripWS(.description , $STR_STRIPTRAILING) & @CRLF) ConsoleWrite(@TAB & "Error ScriptLine....... " & .scriptline & @CRLF) ConsoleWrite(@TAB & "Error RetCode.......... " & "0x" & Hex(.retcode) & @CRLF) EndWith Return ; Return so @error can be trapped by the calling function EndFunc Edited March 31, 2021 by TheXman argumentum 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
TheXman Posted March 31, 2021 Posted March 31, 2021 8 minutes ago, toby9999 said: Thanks so much for your assistance You're welcome. 😀 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
toby9999 Posted March 31, 2021 Author Posted March 31, 2021 That's great ... exactly the example I was looking for. I also like the With/EndWith - much neater that way!
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