Jump to content

WinHTTP functions


trancexx
 Share

Recommended Posts

Here's the entire script thats inside my loop.

Global $sDomain = "PDFwebsite.com"
        $spage = "url-to-the-pdf.com"
        $additional = "username=MyUserName&password=MyPassWord&Read=true&Read=false&SelectedLanguage=en"

        Global $hOpen = _WinHttpOpen()
        Global $hConnect = _WinHttpConnect($hOpen,$sDomain,$INTERNET_DEFAULT_HTTPS_PORT)
        Global $hRequest = _WinHttpOpenRequest($hConnect, "GET", $sPage,Default,Default,Default,$WINHTTP_FLAG_SECURE)

        _WinHttpSimpleFormFill($hConnect, "", 0, "name:username", "MyUserName","name:password","MyPassword","name:Read","true")
        _WinHttpSendRequest($hRequest,"Content-Type:application/x-www-form-urlencoded",$additional)
        _WinHttpReceiveResponse($hRequest)
        $sHeader = _WinHttpQueryHeaders($hRequest)

        If StringInStr($sHeader,"application/pdf") Then
            ; Read if available
            Global $bChunk, $bData, $hFile
            If _WinHttpQueryDataAvailable($hRequest) Then
                While 1
                    $bChunk = _WinHttpReadData($hRequest, 2) ; read binary
                    If @error Then ExitLoop
                    $bData = _WinHttpSimpleBinaryConcat($bData, $bChunk) ; concat two binary data
                WEnd
                ; Save it to the file
                $hFile = FileOpen("C:\MyFile " & ".pdf", 26)
                FileWrite($hFile, $bData)
                FileClose($hFile)
            Else
                MsgBox(48, "Error occurred", "No data available. " & @CRLF)
            EndIf
            _WinHttpCloseHandle($hRequest)
            _WinHttpCloseHandle($hConnect)
            _WinHttpCloseHandle($hOpen)
Edited by RickB75
Link to comment
Share on other sites

I guess my question is, I don't understand why my downloaded file size keeps getting bigger and bigger on each download. The normal size for these files is 300KB to 500KB at the largest. If the script downloads 10 - 12 files, the last downloaded file is in excess of 5,000KB's  

Link to comment
Share on other sites

That's simple. Learn how to declare variables properly in AutoIt. Your second:

Global $bChunk, $bData, $hFile

...does nothing. All the data is still there and the content of $bData is not cleared.

See this:

Global $x = 5
A()

ConsoleWrite($x & @CRLF)

Func A()
    Global $x
    $x +=34
EndFunc

What would you expect ConsoleWrite to print?

Link to comment
Share on other sites

Trance, I have one other quick question. To download each pdf, do I have to open a new session each time? Open, Connect, OpenReqest, etc...? Or, can I open the request, connect outside the loop and do the rest inside the loop? If I can only connect once outside the loop, is there a simple way to check and see if I'm still connected inside the loop? Just curious.

BTW- thanks for all your help!!!

Link to comment
Share on other sites

 

You're "connected" until you disconnect. I see no particularly good reason to repeat unnecessary steps.

 

That was my thoughts as well. I'm not sure what the reason is but, When I move httpOpen and httpConnect outside of my loop (Above), I can only do one request (First file) that gets processed (200 response back). The others responses after are 404 Not Founds. When I move everything back inside the loop, it works ok. 

I am using FTP functions immediately after the file is downloaded that sit inside the loop. Do you think this may be causing an issue / conflict??

Link to comment
Share on other sites

I think its a policy issue.

I just had a quick thought. I can use winHttp to upload the pdf's to my server. Do I still need to do SimpleBinaryConcat when I download it? I apologize if thats a dumb question. I don't dont know. Would it be more efficient to use winHttp instead of the FTP UDF??

I'm just thinking, I could use the same variable I use to store the data in to upload the same data to my server and completely bypass saving the pdf to my pc. 

Edited by RickB75
Link to comment
Share on other sites

I'm not sure why do you use _WinHttpSimpleBinaryConcat at all, when there is _WinHttpSimpleSSLRequest() function that does everything for you.

Uploading from variable is of course possible, but if you want to do it correctly you have to write new function (similar to internal __WinHttpFileContent) that will format the data. It's not that hard really, so try it.

Link to comment
Share on other sites

  • 3 weeks later...

Hi, first of all I need to say thanks for your great work with winhttp. It is really successfully for me when I need to get some information in one charge station (yes, electric charge point).

But now I'm a little bit stuck with _WinHttpConnect because if the web server stays in port 80, then it is ok, but if the port is another one than 80 I cannot get this work.

I have found following info in the help file:

_WinHttpConnect($hSession, $sServerName [, $iServerPort = Default ])

If I force to get information in port 4000 (as example), then the function is still getting information from port 80 instead of 4000. Have you tried to get information from other port than 80?Did work?

Can you help me on this?

Many thanks.

Link to comment
Share on other sites

AFAICT _WinHttpConnect will force specific port numbers for $sServerName argument if URI scheme is specified.
I mean that if specified server name is in form "http://..." then forced port will be 80, and for "https://..." port is 443. In this case $iServerPort argument is ignored.
Help file and function header states this also. This was added to the UDF some time ago to simplify usage.
If you want to force other ports through $iServerPort argument then omit URI scheme.

In case I'm wrong with my assumption, post your code.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

can someone help me i need help translating this C# code into AutoIT code to push notifications trought Pushover application to my android device

var parameters = new NameValueCollection {
    { "token", "APP_TOKEN" },
    { "user", "USER_KEY" },
    { "message", "hello world" }
};

using (var client = new WebClient())
{
    client.UploadValues("https://api.pushover.net/1/messages.json", parameters);
}

my understanding of this WinHTTP functions is non existing so any help would be great

i have a thread open in the help section: '?do=embed' frameborder='0' data-embedContent>>

Edited by Raizeno
Link to comment
Share on other sites

can someone help me i need help translating this C# code into AutoIT code to push notifications trought Pushover application to my android device

 

Hey Raizeno,

try this:

#include "WinHttp.au3"

$sAddress = "https://api.pushover.net/1/messages.json"

$sApiToken = "av26ac2nAXLyPKg2QMy4zf9YcUjz2G" ; <-yours here
$sUserKey = "uMQf396GvMgrsDroaryKEvVyWkgfkw" ; <-yours here
$sMessage = "hello world"

; Construct the form
Const $sForm = '<form action="' & $sAddress & '" method="post">' & _
'<input name="token" value="' & $sApiToken & '"/>' & _
'<input name="user" value="' & $sUserKey & '"/>' & _
'<input name="message" value="' & $sMessage & '"/>' & _
'</form>'

; Open session
$hOpen = _WinHttpOpen()
; To collect connection handle (because the form is inlined)
$hConnect = $sForm

; Fill the form
$sRead = _WinHttpSimpleFormFill($hConnect, $hOpen)

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

; Tada mtfk!
MsgBox(4096, "Simon says", $sRead)
Link to comment
Share on other sites

  • 2 weeks later...

Hello Trancexx,

I have an interesting conundrum concerning HTTP(S) requests, Here is a sample script

 

#include "WinHttp.au3"
global $schunk=""
global $sdata=""


while 1
global $hOpen = _WinHttpOpen('Mozilla/5.0 (Windows NT 6.1; rv:6.0.1) Gecko/20100101 Firefox/6.0.1')

_WinHttpSetTimeouts($hOpen,3000,3000,3000,3000)

global $hconnect = _WinHttpConnect($hOpen, "www.maxmind.com",$INTERNET_DEFAULT_HTTPS_PORT) ;Https connection
global $hrequest = _WinHttpOpenRequest($hconnect,"GET","/geoip/v2.0/city_isp_org/me",default,Default,default,$WINHTTP_FLAG_SECURE) ; Https connection.

_WinHttpAddRequestHeaders($hrequest, "Accept: */*")
_WinHttpAddRequestHeaders($hrequest, "Accept-Language: en-US,en;q=0.8")
_WinHttpAddRequestHeaders($hrequest, "Referer: http://www.maxmind.com/en/locate_my_ip")
_WinHttpAddRequestHeaders($hrequest, "X-Requested-With: XMLHttpRequest")



;_WinHttpSetCredentials($hRequest, $WINHTTP_AUTH_TARGET_SERVER, $WINHTTP_AUTH_SCHEME_BASIC, "test", "test")    ; *****for some reason, this set credentials option lets the connection close*****

;Send request
_WinHttpSendRequest($hrequest)

;Wait for the response
_WinHttpReceiveResponse($hrequest)



; See if there is data to read

If _WinHttpQueryDataAvailable($hrequest) Then
    ; Read
    While 1
        $sChunk = _WinHttpReadData($hrequest)
        If @error Then ExitLoop
        $sData &= $sChunk
    WEnd

endif

msgbox(4096,'','The connection should still be open, check netstat')
_WinHttpCloseHandle($hRequest)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)
$sdata=""
$schunk=""
msgbox(4096,'','The connection should now be closed, check netstat')
WEnd

The issue i'm having is that the initial connection stays open, despite closing all the handles, and if i were to allow the script to continue looping, it would continue sending requests through that same open connection instead of closing it / opening a new one.

I have found a couple of 'hacks' to remedy this

1) comment out the WinHttpQueryDataAvailable section

2) Enable the _WinHttpSetCredentials option

Both of these workarounds seem to force the connection to close properly.  What gives?

Edited by phatzilla
Link to comment
Share on other sites

WinHTTP follows server's settings regarding connection. If you check the response header you'll probably notice "Connection: keep-alive", meaning that the server wants the connection alive anyway.

If you want to force "Connection: close" behavior you would need to call
_WinHttpSetOption($hrequest, $WINHTTP_OPTION_DISABLE_FEATURE, $WINHTTP_DISABLE_KEEP_ALIVE)
before sending request.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Thanks, jchd, that seems to have worked.

I didn't realize that the client follows the servers command regarding keeping/closing a connection.  Is there any other way to forcefully close it without altering the headers that you're sending over to the server?  I realize that the server will probably still have their side of the connection open, but that's inconsequential to me.

Edited by phatzilla
Link to comment
Share on other sites

  • 1 month later...

Hello, I am now writing a simple function which is based on this UDF. the function is like InetRead but the advantage in this function is that you can set time limit.

It supports HTTP and HTTPS protocols and you don't need to decide for yourself how to call WinHttp functions based on the protocol type.

It all done inside this function.

I hope that it will be useful. Please let me know if you find any problems or bugs. It is important for me to know

The function

#include "WinHttp.au3"
#include <Array.au3>




; Read page in HTTPS protocol
$Return = WinHttp_InetRead('https://googledrive.com/host/0B-dsGBArc-IuVHdIRFFyUV8xSXc/host-in-drive.html')
If @error Then ConsoleWrite($Return&' (error '&@error&')' &" (Line "&@ScriptLineNumber&")"&@CRLF)
ConsoleWrite($Return &" (Line "&@ScriptLineNumber&")"&@CRLF)

MsgBox(0,'','Done')

; Read page in HTTP protocol
$Return = WinHttp_InetRead('http://www.autoitscript.com/forum/topic/84133-winhttp-functions/')
If @error Then ConsoleWrite($Return&' (error '&@error&')' &" (Line "&@ScriptLineNumber&")"&@CRLF)
ConsoleWrite($Return &" (Line "&@ScriptLineNumber&")"&@CRLF)


Func WinHttp_InetRead($sUrl,$TimeOut = 6000)

    If Not _WinHttpCheckPlatform() Then Return SetError(1,0,'The WinHttp service is not available in your system')


    Local $aUrl = _WinHttpCrackUrl($sUrl)
    If @error Then Return SetError(2,0,'Error: url invalid.')

    Local $aHandls[0]

    ; Initialize and get session handle
    Local $hOpen = _WinHttpOpen(),$erMsg,$error
    If @error Then Return SetError(3,0,'Error getting connection handle.')
    _ArrayAdd($aHandls,$hOpen)

    Local $nTimeOut = Int($TimeOut/4)
    _WinHttpSetTimeouts($hOpen,$nTimeOut,$nTimeOut,$nTimeOut,$nTimeOut)

    ;                                         Domain    port
    Local $hConnect = _WinHttpConnect($hOpen, $aUrl[2],$aUrl[3])
    If @error Then
        _WinHttpCloseHandle($hOpen)
        Return SetError(4,0,'Error getting connection handle.')
    EndIf
    _ArrayAdd($aHandls,$hConnect)



    Local $sRetun
    Switch $aUrl[0]

        Case 'http'

            Local $hRequest = _WinHttpOpenRequest($hConnect, Default, $aUrl[6]&$aUrl[7])
            If @error Then
                WinHttpCloseAllHandls($aHandls)
                Return SetError(5,0,'Error in _WinHttpOpenRequest.')
            EndIf
            _ArrayAdd($aHandls,$hRequest)

            _WinHttpSendRequest($hRequest)
            If @error Then
                WinHttpCloseAllHandls($aHandls)
                Return SetError(6,0,'Error in _WinHttpOpenRequest.')
            EndIf

            _WinHttpReceiveResponse($hRequest)
            If @error Then
                WinHttpCloseAllHandls($aHandls)
                Return SetError(7,0,'Error in _WinHttpReceiveResponse.')
            EndIf

            $aVData = _WinHttpQueryDataAvailable($hRequest)
            If @error Or Not $aVData Then
                WinHttpCloseAllHandls($aHandls)
                Return SetError(8,0,'Error in _WinHttpQueryDataAvailable')
            EndIf


            Do
                $sRetun &= _WinHttpReadData($hRequest)
            Until @error


        Case 'https'

            $sRetun = _WinHttpSimpleSSLRequest($hConnect, Default, $aUrl[6]&$aUrl[7])
            If @error Then
                WinHttpCloseAllHandls($aHandls)
                Return SetError(9,0,'Error in _WinHttpOpenRequest.')
            EndIf

        Case Else
            WinHttpCloseAllHandls($aHandls)
            Return SetError(10,0,'Error: protocol "'&$aUrl[0]&'" is unsupported.')
    EndSwitch

    WinHttpCloseAllHandls($aHandls)
    Return $sRetun


EndFunc


Func WinHttpCloseAllHandls($aHandls)
    For $a = 0 To UBound($aHandls)-1
        _WinHttpCloseHandle($aHandls[$a])
    Next
EndFunc

Have a nice day

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