Jump to content

WinHTTP functions


trancexx
 Share

Recommended Posts

I want to send commands to a prog that has a webserver on port 81.

ie, this works on browser:

1) first connect to 192.168.1.8:81/login.htm

and login with user-pass

2) send command like:

192.168.1.8/admin?camera=***&trigger&user=***&pw=***

 

In the 1) there is a form like:

<form method="POST" action="javascript:login()" autocomplete="on" >
    <table border="0" width="100%">
        <tr>
            <td align="center"><input type="text" name="user" id="user" size="20"></td>
        </tr>
        <tr>
            <td align="center"><input type="password" name="password" id="password" size="20" onKeyPress="return submitenter(this,event)"></td>
        </tr>
        <tr>
            <td align="center">
    <input id='login-button' type='submit' value='Login'</td>
        </tr>
    </table>

So I tried this:

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

; Get connection handle
$hConnect = _WinHttpConnect($hOpen, "192.168.1.8", 81)

; Fill form
$sHTML = _WinHttpSimpleFormFill($hConnect, _
        "/login.htm", _ ; login page
        Default, _ ;  form without id
        "name:user", $sUserName, _
        "name:password", $sPassword )
        
If @error Then
    MsgBox(4096, "Error", "Error number = " & @error)
Else
    ConsoleWrite($sHTML & @CRLF)
    MsgBox(4096, "Returned", $sHTML)
EndIf

; send commands (?) 192.168.1.8/admin?camera=***&trigger&user=***&pw=***

; Close handles
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)
But I get error 4 Connection problems
Edited by frank10
Link to comment
Share on other sites

Hi trancexx, before I tried the 1.6.3.3 with autoit 3.3.12.0

Now I tried the 1.6.3.8 with the latest autoit beta 3.3.15.0

Besides I added:

ConsoleWrite("Returned:" & _WinHttpSimpleRequest($hConnect) )

To check the resulting page before using the SimpleFormFill and I got the correct htm page with the above form.

Always error number 4.

BTW, the program I want to access to, is BlueIris, to manage ipcam (there is also a free trial).

Link to comment
Share on other sites

Ok, I tried this, with 1.6.3.9:

global $sAddress = "http://192.168.1.8:81/login.htm" ; the address of the target
global $sUserName = "***"
global $sPassword = "***"

local $sForm = _
        '<form action="' & $sAddress & '" method="post" enctype="multipart/form-data">' & _
        '   <input type="text" name="user" />' & _ ;
        '   <input type="password" name="password"/>' & _ ;
        '</form>'

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

local $hConnect = $sForm ; will pass form as string so this is for coding correctness because $hConnect goes in byref

; Fill form
local $sHTML = _WinHttpSimpleFormFill($hConnect, $hOpen, _
        Default, _
        "name:user", $sUserName, _
        "name:password", $sPassword )

If @error Then
    MsgBox(4096, "Error", "Error number = " & @error )
Else
    ConsoleWrite($sHTML & @CRLF)
    MsgBox(4096, "Returned", $sHTML)
EndIf

; Close handles
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)

This time I put port 81 into the url: 192.168.1.8:81 instead of:

$hConnect = _WinHttpConnect($hOpen, "192.168.1.8", 81)

I still get error 4...

Link to comment
Share on other sites

Ok, I tried with this:

local $sHTML = _WinHttpSimpleFormFill($hConnect, $hOpen, _
        Default, _
        "name:user", $sUserName, _
        "name:password", $sPassword , _
        "X-Requested-With: XMLHttpRequest"); just to be able to confirm successful login)

If @error Then
    MsgBox(4096, "Error", "Error number = " & @error & " ex =" & @extended )
Else
    ConsoleWrite($sHTML & @CRLF)
    MsgBox(4096, "Returned", $sHTML)
EndIf
ConsoleWrite("answer:" & $sHTML & @CRLF)

I still get @error = 4 & @extended = 0  and  $sHTML = ''

weird...

Edited by frank10
Link to comment
Share on other sites

In the HTML page I get some javascript code like this:

<span>function getUrlVars() {
        var vars = {};
        var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {vars[key] = value;} );
        return vars;
    }
</span>
function getSession()
     {
        var i,x,y,ARRcookies=document.cookie.split(";");
        for (i=0; i<ARRcookies.length; i++ )
        {
            x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
            y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
            x=x.replace(/^\s+|\s+$/g,"");

            if (x=="session")
            {
                return unescape(y);
            }
        }
     }

    function hex_md5(a){return rstr2hex(rstr_md5(str2rstr_utf8(a)))}

     function login()
     {
        var a = document.getElementById('user').value+":"+getSession()+":"+ document.getElementById('password').value;
        window.location = "/?page=" + getUrlVars()["page"] + "&login=" + hex_md5( a );
     }

    window.onload = function()
    {
        document.getElementById('user').focus();
    }

So, clicking the input Login button, triggers the login() func and doesn't send only user/password, but also session/cookies and more...

 

 

Link to comment
Share on other sites

^^ That's better. It's actually easy to do it with WinHttp if you understand javascript just a bit.

Try it. If you fail, I'll help you more (if you can wait for few weeks). :).

There are other people around that can help you in the mean time, so feel free to post your tries. I'm sure they will take over from there.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Thank you trancexx.

Well, I got the session cookie and hashed the string with user/pwd with Md5: it seems it's the same done by javascript (I had to put also StringLower to make it identical).

After the login, I should send the trigger command, like sending the new address page in the browser: "192.168.1.8:81/admin?camera=camName&trigger&user=***&pw=***"

So, I did:

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

    Global $hConnect = _WinHttpConnect($hOpen, "192.168.1.8", 81 )

    ; Create request
    $hRequest = _WinHttpOpenRequest($hConnect)
    ; Send it
    _WinHttpSendRequest($hRequest)

    ; Wait for the response
    _WinHttpReceiveResponse($hRequest)
    Global $sHeader = _WinHttpQueryHeaders($hRequest)
    $aSession = _StringBetween($sHeader,"session=", ";")
    $sCredentials = $sUserName & ":" &  $aSession[0]  & ":" & $sPassword ; ie: "***:5c7313fe7c6e46c00e1414c7597a4b29:****"
    ;ConsoleWrite($sCredentials & @CRLF)
    $hash = _Crypt_HashData ( $sCredentials, $CALG_MD5 )  ; ie. 0xF3A61FAED6CDDB98683E77D54A0EA7BC
    ;ConsoleWrite( $hash & @CRLF)

    global $newPage = "/?page=undefined" & "&login=" & StringLower(StringMid($hash,3));
    ;ConsoleWrite($newPage & @CRLF)  ; ie. /?page=undefined&login=f3a61faed6cddb98683e77d54a0ea7bc

    ; Request make login:
    Global $hRequest = _WinHttpOpenRequest($hConnect, _
            "POST", _ ; verb
            $newPage)
    _WinHttpSendRequest($hRequest)
;~  ConsoleWrite($hRequest & " _ err:" & @error & "_ext:" & @extended & @CRLF) ; print to console

    ; Request trigger camera:
    $hRequest = _WinHttpOpenRequest($hConnect, _
            "POST", _ ; verb
            "/admin?camera="& $camName & "&trigger&user=" & $sUserName & "&pw=" & $sPassword )
    ; Send it
    _WinHttpSendRequest($hRequest)
    ConsoleWrite($hRequest & " trigg_ err:" & @error & "_ext:" & @extended & @CRLF) ; print to console

    ; Close handles
    _WinHttpCloseHandle($hRequest)
    _WinHttpCloseHandle($hConnect)
    _WinHttpCloseHandle($hOpen)

But it doesn't work, especially after the $newPage login it doesn't really login.

I don't know what I did before of this code, but I succeded in login: now instead I can't did it again and I don't remember what I've done!! :'(

What do you see wrong in this code?

Edited by frank10
Link to comment
Share on other sites

I redid it! :lmao:

The functioning code is:

Global $hRequest = _WinHttpSimpleRequest($hConnect, _
            "GET", _ ; verb
            $newPage)

instead of the not functioning one:

Global $hRequest = _WinHttpOpenRequest($hConnect, _
            "GET", _ ; verb
            $newPage)
     _WinHttpSendRequest($hRequest)

Now, if someone can tell me why the HttpSimpleRequest works and the OpenRequest no...

Anyway I solved my task, thank you trancexx for the support.

Edited by frank10
Link to comment
Share on other sites

  • 2 weeks later...

Hi @trancexxx 

Somehow I managed to connenct and open some web page using winhttp, but I have a little problem here, the page I need to load using authentication, after successfull login, the page redirect to loading page, before going to page that i want, so it's basicalli like this,

[login page] >> [loading page] >> [page i want]

using "_WinHttpSimpleFormFill" and _WinHttpSimpleSSLRequest I only get the html source of loading page, how I can get the html of the page after loading page?

my code look like this

Local $sReportLink = "https://go.xero.com/Bank/BankTransactions.aspx?accountID=9E6416D4-90EA-4E23-BDA5-35BB37871AE1"

Local $sHtml = _WinHttpSimpleSSLRequest($hConnect, Default, $sReportLink, Default, Default, Default, Default, 0)

 

Thanks,

Edited by ngskicker
Link to comment
Share on other sites

Hi trancexx,

Is there any way to send a post with a big data content request but into a different TCP segments?

I need to send each TCP segment as a maximum of 1460bytes length.

 

Thanks in advance!

So break it into chunks and send them like that.

You need to be more precise about what you want to do to get better reply.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Hi @trancexxx 

Somehow I managed to connenct and open some web page using winhttp, but I have a little problem here, the page I need to load using authentication, after successfull login, the page redirect to loading page, before going to page that i want, so it's basicalli like this,

[login page] >> [loading page] >> [page i want]

using "_WinHttpSimpleFormFill" and _WinHttpSimpleSSLRequest I only get the html source of loading page, how I can get the html of the page after loading page?

my code look like this

Local $sReportLink = "https://go.xero.com/Bank/BankTransactions.aspx?accountID=9E6416D4-90EA-4E23-BDA5-35BB37871AE1"

Local $sHtml = _WinHttpSimpleSSLRequest($hConnect, Default, $sReportLink, Default, Default, Default, Default, 0)

 

Thanks,

After you've logged in don't close the connection handle and use it to navigate to whatever page you want.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

After you've logged in don't close the connection handle and use it to navigate to whatever page you want.

Here is my full source 

Func _DownloadReport($sReportLink, ByRef $sFilePath)

    ; get username and password
    Local $sUserName = IniRead($sAccFile, "data", "u", "")
    Local $sPassword = IniRead($sAccFile, "data", "p", "")

    ; initialize and get session handle
    Local $hOpen = _WinHttpOpen()
    ; get connection handle
    Local $hConnect = _WinHttpConnect($hOpen, "login.xero.com", $INTERNET_DEFAULT_HTTPS_PORT)

    ; fill login form:
    Local $sRead = _WinHttpSimpleFormFill($hConnect, _
                    Default, _ ; location of the form
                    "LoginForm", _ ; id of the form
                    "name:userName", $sUserName, _
                    "name:password", $sPassword)

    If @error Then
        MsgBox(262144 + 8192 + 256 + 16, "Error: 1756", "Script can not open connection to xero, script will skip this bank.")
        _WinHttpCloseHandle($hConnect)
        _WinHttpCloseHandle($hOpen)
        Return False
    EndIf

    ; Close connection handle
    _WinHttpCloseHandle($hConnect)

    ; Open new connection handle to get report and statementDBId
    Local $hConnect = _WinHttpConnect($hOpen, "go.xero.com", $INTERNET_DEFAULT_HTTPS_PORT)
    Local $sHtml = _WinHttpSimpleSSLRequest($hConnect, Default, $sReportLink, Default, Default, Default, Default, 0)

    ; Close connection handle
    _WinHttpCloseHandle($hConnect)

    ; Get report and statementDBId from html source
    Local $reportId, $statementDBId
    _GetReportID($reportId, $statementDBId, $sHtml)

    ; here I get the error, because $sHtml does not contain page what I want, page that contain $reportId and $statementDBId
    If $reportId = "" Or $statementDBId = "" Then
        MsgBox(262144 + 8192 + 256 + 16, "Error: 1777", "Script can not get reportId or statementDBId value, script will skip this bank.")
        _WinHttpCloseHandle($hOpen)
        Return False
    EndIf

    Local $sFileLink = "Reports/ExcelReport.aspx?reportId=" & $reportId & "&report=&statement=" & $statementDBId & "&attPage="

    ; Open new connection handle to download report
    Local $hConnect = _WinHttpConnect($hOpen, "go.xero.com", $INTERNET_DEFAULT_HTTPS_PORT)
    Local $hXls = _WinHttpSimpleSSLRequest($hConnect, Default, $sFileLink, Default, Default, Default, True, 2)

    ; Close connection handle
    _WinHttpCloseHandle($hConnect)
    ; Close session handle
    _WinHttpCloseHandle($hOpen)

    ; get provided filename from http header
    Local $aArray = StringRegExp($hXls[0], '(?<=filename=")(.*)(?=.xls")', 1)
    ; check if filename returned
    If Not IsArray($aArray) Then
        MsgBox(262144 + 8192 + 256 + 16, "Error: 1797", "Script can not download the report, script will skip this bank.")
        Return False
    EndIf
    ; define filename and directory
    Local $aFileName = StringSplit($aArray[0], "[")
    $sFilePath = $sDataDir & "\" & StringTrimRight($aFileName[1], 22)
    If Not FileExists($sFilePath) Then DirCreate($sFilePath)

    ; generate new filename and path
    Local $sFileName = $sFilePath & "\" & $sTitle & " - Bank Reconcilliation"
    If FileExists($sFileName & ".xls") Then
        Local $n = 0
        Do
            $n += 1
        Until FileExists($sFileName & "(" & $n & ").xls") = False
        $sFileName = $sFileName & "(" & $n & ")"
    EndIf

    ; save file
    Local $hFile = FileOpen($sFileName & ".xls", 18)
    FileWrite($hFile, $hXls[1])
    FileClose($hFile)

    ProcessClose($SplashPID)

    Return $sFileName & ".xls"
EndFunc

 

Edited by ngskicker
Link to comment
Share on other sites

You can do it like this:

;...
    
    ; initialize and get session handle
    Local $hOpen = _WinHttpOpen()
    ; get connection handle
    Local $hConnect = _WinHttpConnect($hOpen, "https://login.xero.com")

    ; fill login form:
    Local $sRead = _WinHttpSimpleFormFill($hConnect, _
            Default, _ ; location of the form
            "LoginForm", _ ; id of the form
            "name:userName", $sUserName, _
            "name:password", $sPassword)

    While StringInStr($sRead, "<title>Working...</title>")
        ; Fill the confirmation form (WinHttp will do everything internally, no worries)
        $sRead = _WinHttpSimpleFormFill($hConnect)
    WEnd

    _WinHttpCloseHandle($hConnect)
    
;...

Latest Winhttp.au3 is at https://raw.githubusercontent.com/dragana-r/autoit-winhttp/master/WinHttp.au3

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Hi trancexx

unfortunately the solution you provide is not working, I will investigating more why this not working, I found something interesting, when I open the page using IE8, i'm unable to login, so come to my mind, is this related, I didn't know when the code started to not working, but a years ago, the code is working.

You can do it like this:

;...
    
    ; initialize and get session handle
    Local $hOpen = _WinHttpOpen()
    ; get connection handle
    Local $hConnect = _WinHttpConnect($hOpen, "https://login.xero.com")

    ; fill login form:
    Local $sRead = _WinHttpSimpleFormFill($hConnect, _
            Default, _ ; location of the form
            "LoginForm", _ ; id of the form
            "name:userName", $sUserName, _
            "name:password", $sPassword)

    While StringInStr($sRead, "<title>Working...</title>")
        ; Fill the confirmation form (WinHttp will do everything internally, no worries)
        $sRead = _WinHttpSimpleFormFill($hConnect)
    WEnd

    _WinHttpCloseHandle($hConnect)
    
;...

Latest Winhttp.au3 is at https://raw.githubusercontent.com/dragana-r/autoit-winhttp/master/WinHttp.au3

 

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...