Jump to content

WinHttp Invalid Server Response


 Share

Recommended Posts

In an attempt to gather everything into a single screen, I've started working on GETting (like what I did there?) my notifications from GitHub. I'm really bad with the WinHttp UDF, but I think I'm nearly there. I managed to make another function pull info from GitHub using a similar setup to get the latest release of a repo. There seems to be an issue with using HTTPS and authentication, however. Neither function will work (_WinHttpReceiveResponse returns Error 1 and _WinAPI_GetLastError returns 12152) if I use Https. Using Http works for getting un-authenticated data, but returns a 401- Unauthorized error when attempting to get notifications.

(I created a token in lieu of using my password, in hopes of not deleting anything from GitHub)

#include <WinHttp.au3>
#include <WinAPI.au3>

Global $__g_GitHub_TOKEN = "--Redacted--"

ConsoleWrite(_GitHub_Notifications() & @CRLF)

Func _GitHub_Notifications()

    Local $hOpen = _WinHttpOpen()
    ErrMsg(_WinHttpOpen)
    Local $hConnect = _WinHttpConnect($hOpen, 'http://api.github.com')
    ErrMsg(_WinHttpConnect)
    Local $hRequest = _WinHttpOpenRequest($hConnect, "GET", "/notifications");, Default, Default, "Accept: application/vnd.github.v3+json")
    ErrMsg(_WinHttpOpenRequest)
    _WinHttpSetCredentials($hRequest, $WINHTTP_AUTH_TARGET_SERVER, $WINHTTP_AUTH_SCHEME_BASIC, "seadoggie01", $__g_GitHub_TOKEN)
    ErrMsg(_WinHttpSetCredentials)
    _WinHttpSendRequest($hRequest)
    ErrMsg(_WinHttpSendRequest)
    _WinHttpReceiveResponse($hRequest)
    If ErrMsg(_WinHttpReceiveResponse) Then ConsoleWrite("WinAPI Error Code: " & _WinAPI_GetLastError() & @CRLF)
    Local $sJson = _WinHttpReadData($hRequest)
    ErrMsg(_WinHttpReadData)
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)

    Return $sJson

EndFunc

Func ErrMsg($sMsg, $iError = @error, $iExtended = @extended)
    If $iError Then
        If IsFunc($sMsg) Then $sMsg = FuncName($sMsg)
        ConsoleWrite("! Error: " & $iError & ($iExtended ? " Extended: " & $iExtended : "") & " - " & $sMsg & @CRLF)
    EndIf
    Return SetError($iError, $iExtended, $iError)
EndFunc

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

As I'm sure that you already know, Github API requests using BASIC authentication is deprecated.  The preferred method is to use OAUTH or personal tokens.  When you use personal tokens as authentication, you pass the token in the "Authorization" request header, not as a BASIC authentication password for your username.

The example script that I have created below works for me.  Make sure that you check and modify all of the lines that are marked "Modify as needed".  The example token that I used in the script is NOT a valid token.  So if you use it, you will generate the following error in the console:  "HTTP Status Code = 401 Unauthorized".  Make sure to use a personal token that has been granted access to the required API endpoints.

#include <Constants.au3>
#include <MyIncludes\WinHttp\WinHttp.au3>         ;Modify as needed
#include <MyIncludes\WinHttpRequestConstants.au3> ;Modify as needed
#include <MyIncludes\json\json.au3>               ;Modify as needed


github_notifications_request()

Func github_notifications_request()

    Local $hSession = -1, $hConnection = -1, $hRequest = -1
    Local $oJson = Null
    Local $sResponse = "", $sStatusCode = "", $sStatusText = ""


    ;Establish WinHTTP session handle
    $hSession = _WinHttpOpen()
    If @error Then Exit MsgBox($MB_TOPMOST + $MB_ICONERROR, "ERROR", "_WinHttpOpen failed - @error = " & @error)

    ;Establish WinHTTP connection handle
    $hConnection = _WinHttpConnect($hSession, "https://api.github.com")
    If @error Then Exit MsgBox($MB_TOPMOST + $MB_ICONERROR, "ERROR", "_WinHttpConnect failed - @error = " & @error)

    ;Establish WinHTTP requests handle
    $hRequest = _WinHttpOpenRequest($hConnection, _
                                    "GET", _
                                    "/notifications", _
                                    Default, Default, Default, _
                                    BitOR($WINHTTP_FLAG_SECURE, $WINHTTP_FLAG_ESCAPE_DISABLE))
    If @error Then Exit MsgBox($MB_TOPMOST + $MB_ICONERROR, "ERROR", "_WinHttpOpenRequest failed - @error = " & @error)

    ;Set request headers
    _WinHttpAddRequestHeaders($hRequest, "Accept: application/vnd.github.v3+json")
    _WinHttpAddRequestHeaders($hRequest, "Authorization: Token 159bc76fd252a4c1f02e9f7f940fef0000000000") ;Modify as needed

    ;Send request and wait for the response
    _WinHttpSendRequest($hRequest)
    If @error Then Exit MsgBox($MB_TOPMOST + $MB_ICONERROR, "ERROR", "_WinHttpSendRequest failed - @error = " & @error)

    _WinHttpReceiveResponse($hRequest)
    If @error Then Exit MsgBox($MB_TOPMOST + $MB_ICONERROR, "ERROR", "_WinHttpReceiveResponse - @error = " & @error)

    ;Get response status code and status text
    $sStatusCode = _WinHttpQueryHeaders($hRequest, $WINHTTP_QUERY_STATUS_CODE)
    $sStatusText = _WinHttpQueryHeaders($hRequest, $WINHTTP_QUERY_STATUS_TEXT)

    ;If good status code
    If $sStatusCode = "200" Then
        ;Get response
        $sResponse = _WinHttpReadData($hRequest)

        ;Format JSON response
        $oJson     = Json_Decode($sResponse, 2000)           ;Convert JSON string to object
        $sResponse = Json_Encode($oJson, $JSON_PRETTY_PRINT) ;Pretty print json object

        ConsoleWrite("-> API Response:" & @CRLF & $sResponse & @CRLF)
    Else
        ConsoleWrite(StringFormat("-> HTTP Status Code = %s %s", $sStatusCode, $sStatusText) & @CRLF)
    EndIf

    _WInHttpCloseHandle($hRequest)
    _WInHttpCloseHandle($hConnection)
    _WInHttpCloseHandle($hSession)

EndFunc

 

Edited by TheXman
Slight aesthethic modification to the example script
Link to comment
Share on other sites

19 minutes ago, TheXman said:

you pass the token in the "Authorization" request header, not as a BASIC authentication password for your username

Ah. This is what got me. I'm trying to become more familiar with networking related programming and documentation doesn't always explain it low enough for me to grasp. I indeed saw that basic authentication was becoming depreciated, so I tried getting a token, but I thought it would directly replace the password because I thought the token might not be specific to a single user

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

I don't have anything against using the WinHttp.au3 UDF.  However, if using the WinHttp.WinHttpRequest.5.1 COM object is feasible, I usually prefer it just because it requires less code to get the same result and doesn't require as many details (like getting handles for sessions, connections, and requests, and making sure that you have passed/set the correct flags).  Admittedly, adding a COM error handler would add a little more code but isn't a necessity.  Below is the same example using COM.

#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d

#include <Constants.au3>
#include <MyIncludes\json\json.au3> ;Modify as needed


github_notifications_request()

Func github_notifications_request()

    Local $oJson = Null
    Local $iStatusCode = 0
    Local $sResponse = "", $sStatusText = ""

    Local $oComError = ObjEvent("AutoIt.Error", com_error_handler)
    #forceref $oComError

    With ObjCreate("winhttp.winhttprequest.5.1")

        ;Open GET request, set request headers, and send the request synchronous
        .Open("GET", "https://api.github.com/notifications")
        .SetRequestHeader("Accept", "application/vnd.github.v3+json")
        .SetRequestHeader("Authorization", "Token 159bc76fd252a4c1f02e9f7f940fef918d301900") ;Modify as needed
        .Send()

        ;Get status code and response
        $iStatusCode = .Status
        $sStatusText = .StatusText
        $sResponse   = .ResponseText

    EndWith

    ;If bad request status code
    If $iStatusCode <> 200 Then
        ;Display bad response info
        ConsoleWrite(StringFormat("HTTP Status  : %s %s", $iStatusCode, $sStatusText) & @CRLF)
        ConsoleWrite(StringFormat("HTTP Response: \r\n%s", $sResponse) & @CRLF)
        Return
    EndIf

    ;Display JSON API response
    $oJson     = Json_Decode($sResponse, 2000) ;Convert JSON string to object
    $sResponse = Json_Encode($oJson, $JSON_PRETTY_PRINT) ;Convert JSON object to pretty printed string

    ConsoleWrite("API Response:" & @CRLF & $sResponse & @CRLF)

EndFunc

Func com_error_handler($oComErr)
    Local $sErrMsg = ""

    With $oComErr
        $sErrMsg =  @CRLF
        $sErrMsg &= ">>>  COM ERROR  <<<" & @CRLF
        $sErrMsg &= StringFormat("Script Line Number : %s", .ScriptLine) & @CRLF
        $sErrMsg &= StringFormat("HRESULT            : 0x%x (%s)", .Number, .Number) & @CRLF
        $sErrMsg &= StringFormat("Windows Error      : %s", StringStripWS(.WinDescription, $STR_STRIPTRAILING)) & @CRLF
    EndWith

    ConsoleWrite($sErrMsg)

    Exit 1
EndFunc

 

Edited by TheXman
Link to comment
Share on other sites

The only reason I don't use the object is that it never has worked for me in the past... likely because I was using it incorrectly :) That looks much easier

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

Did you saw my GH API UDF ?

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

  • 3 months later...
1 hour ago, samibb said:

i need help please.

In advance :

- Please do not post script code as a graphic

- Ask questions about WinHttp.au3 rather in the thread :  winhttp-functions

Back to topic :
I can't detect any problems. The message states "Data from google.com is available!", therefore it is ok !"

Edited by Musashi

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

That message box is not from that script. Try again? I think you used two example scripts and got confused about which you were running :) 

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

Dear

when i run Demo.au3 script  it gave  me this error

 

_WD_IsLatestRelease: True
_WD_IsLatestRelease ==> Success
_WDStartup: OS: WIN_10 WIN32_NT 14393 
_WDStartup: AutoIt: 3.3.14.5
_WDStartup: WD.au3: 0.3.1.0 (Up to date)
_WDStartup: WinHTTP:    1.6.4.2
_WDStartup: Driver: msedgedriver.exe
_WDStartup: Params: --verbose
_WDStartup: Port:   9515
_WD_Startup ==> General Error: Error launching web driver!
+>11:43:12 AutoIt3.exe ended.rc:-1
+>11:43:12 AutoIt3Wrapper Finished.
>Exit code: 4294967295    Time: 11.2

i have insert 

MicrosoftWebDriver.exe

to same folder with run script

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...