Jump to content

Strange wininet problem


Recommended Posts

I'm trying to make a request to a caldav server and I'm using WinINet.au3 for this. The problem is, that the payload I'm using in my request gets mangled. Every second byte is 0x0, which obviously is wrong and the server won't understand that.

I can't use winhttp requests, as the environment I'm in is using a proxy with NTLM authentication and as far as I know winhttp is not capable of using that.

My code:

_WinINet_Startup()
$io = _WinINet_InternetOpen(Default,$INTERNET_OPEN_TYPE_PRECONFIG)
$ic = _WinINet_InternetConnect($io,$INTERNET_SERVICE_HTTP,$dest,80,Default,$username,$password)
$ho = _WinINet_HttpOpenRequest($ic,"REPORT","remote.php/dav/calendars/username/default/",$INTERNET_FLAG_RELOAD)
_WinINet_HttpAddRequestHeaders($ho,"Content-Type: application/xml; charset=utf-8" & @CRLF, $HTTP_ADDREQ_FLAG_ADD)
_WinINet_HttpAddRequestHeaders($ho,"Depth: 1" & @CRLF, $HTTP_ADDREQ_FLAG_ADD)
$hs = _WinINet_HttpSendRequest($ho,Default,'<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav"><d:prop><d:getetag /><c:calendar-data /></d:prop><c:filter><c:comp-filter name="VCALENDAR"><c:comp-filter name="VEVENT"><c:time-range  start="20190401T000000" end="20190402T235959"/></c:comp-filter></c:comp-filter></c:filter></c:calendar-query>')
$data=_WinINet_InternetReadFile($ho,1048576)
ConsoleWrite($data)
_WinINet_InternetCloseHandle($ho)
_WinINet_InternetCloseHandle($ic)
_WinINet_InternetCloseHandle($io)
_WinINet_Shutdown()

Relevant code from WinINet.au3:

Func _WinINet_HttpSendRequest($hHttpOpenRequest, $sHeaders = Default, $vOptional = Default)
    ; Set data/structures up
    Local $iHeaders = 0, $pHeaders = 0
    If $sHeaders <> Default Then
        $iHeaders = StringLen($sHeaders)
        Local $tHeaders = DllStructCreate($WIN32_TCHAR & "[" & ($iHeaders+1) & "]")
        DllStructSetData($tHeaders, 1, $sHeaders)
        $pHeaders = DllStructGetPtr($tHeaders)
    EndIf

    Local $iOptional = 0, $pOptional = 0
    If $vOptional <> Default Then
        If IsDllStruct($vOptional) Then
            $iOptional = DllStructGetSize($vOptional)
            $pOptional = DllStructGetPtr($vOptional)
        Else
            Local $tOptional
            If IsBinary($vOptional) Then
                $iOptional = BinaryLen($vOptional)
                $tOptional = DllStructCreate("byte[" & $iOptional & "]")
            Else
                $iOptional = StringLen($vOptional)
                $tOptional = DllStructCreate($WIN32_TCHAR & "[" & ($iOptional+1) & "]")
            EndIf

            DllStructSetData($tOptional, 1, $vOptional)
            $pOptional = DllStructGetPtr($tOptional)
        EndIf
    EndIf

    ; Make DLL call
    Local $avResult = DllCall($__WinINet_hDLL, _
        "int", "HttpSendRequest" & $WIN32_FTYPE, _
            "ptr",   $hHttpOpenRequest, _
            "ptr",   $pHeaders, _
            "dword", $iHeaders, _
            "ptr",   $pOptional, _
            "dword", $iOptional _
    )

    ; Return response
    If @error Or Not $avResult[0] Then Return SetError(1, 0, False)
    Return True
EndFunc   ;==>_WinINet_HttpSendRequest

HTTP request:

REPORT /remote.php/dav/calendars/username/default/ HTTP/1.1
Connection: Keep-Alive
Content-Type: application/xml; charset=utf-8
Accept: */*
Depth: 1
User-Agent: AutoIt/3.3.14.5
Host: myhost.com
Content-Length: 317
Cache-Control: no-cache
Cookie: cookie_test=test

<.c.:.c.a.l.e.n.d.a.r.-.q.u.e.r.y. .x.m.l.n.s.:.d.=.".D.A.V.:.". .x.m.l.n.s.:.c.=.".u.r.n.:.i.e.t.f.:.p.a.r.a.m.s.:.x.m.l.:.n.s.:.c.a.l.d.a.v.".>.<.d.:.p.r.o.p.>.<.d.:.g.e.t.e.t.a.g. ./.>.<.c.:.c.a.l.e.n.d.a.r.-.d.a.t.a. ./.>.<./.d.:.p.r.o.p.>.<.c.:.f.i.l.t.e.r.>.<.c.:.c.o.m.p.-.f.i.l.t.e.r. .n.a.m.e.=.".V.C.A.L.E.N

Anyone has an idea?

Link to comment
Share on other sites

What you see is not what I receive, it's what I *send* as a request. The answer from the webserver is an error message saying, that he can't interpret 0x0 at the first byte of payload - which is understandable. Somewhere between my function call _WinINet_HttpSendRequest and the actual packet that is leaving my computer the string '<c:calendar-query ...' gets messed up and I have no clue why or how to prevent that.

Link to comment
Share on other sites

  • Developers

The remark still stands, so you are trying to send double byte characters.  ;)

So what is the file encoding of your script? 

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Solved the problem myself. The direction unicode was not bad. If I change the the SendRequest function like this it works:

 

Func _MyWinINet_HttpSendRequest($hHttpOpenRequest, $sHeaders = Default, $vOptional = Default)
    ; Set data/structures up
    Local $iHeaders = 0, $pHeaders = 0
    If $sHeaders <> Default Then
        $iHeaders = StringLen($sHeaders)
        Local $tHeaders = DllStructCreate($WIN32_TCHAR & "[" & ($iHeaders+1) & "]")
        DllStructSetData($tHeaders, 1, $sHeaders)
        $pHeaders = DllStructGetPtr($tHeaders)
    EndIf

    Local $iOptional = 0, $pOptional = 0
    If $vOptional <> Default Then
        If IsDllStruct($vOptional) Then
            $iOptional = DllStructGetSize($vOptional)
            $pOptional = DllStructGetPtr($vOptional)
        Else
            Local $tOptional
            If IsBinary($vOptional) Then
                $iOptional = BinaryLen($vOptional)
                $tOptional = DllStructCreate("byte[" & $iOptional & "]")
            Else
                $iOptional = StringLen($vOptional)
                ; using $WIN32_TCHAR here will not work when trying to send additional paylod
                ; with the request, e.g. when trying REQUEST for a webdav service
                $tOptional = DllStructCreate("char[" & ($iOptional+1) & "]")
            EndIf

            DllStructSetData($tOptional, 1, $vOptional)
            $pOptional = DllStructGetPtr($tOptional)
        EndIf
    EndIf

    ; Make DLL call
    Local $avResult = DllCall($__WinINet_hDLL, _
        "int", "HttpSendRequest" & $WIN32_FTYPE, _
            "ptr",   $hHttpOpenRequest, _
            "ptr",   $pHeaders, _
            "dword", $iHeaders, _
            "ptr",   $pOptional, _
            "dword", $iOptional _
    )

    ; Return response
    If @error Or Not $avResult[0] Then Return SetError(1, 0, False)
    Return True
EndFunc   ;==>_MyWinINet_HttpSendRequest

Thanks for pointing me in the right direction.

Link to comment
Share on other sites

5 minutes ago, Jos said:

The remark still stands, so you are trying to send double byte characters.  ;)

So what is the file encoding of your script? 

Jos

Scite says "code page property" as file encoding, but I tried using other encodings with the same result. Strange thing is, that using $WIN32_TCHAR (which stands for "wchar") works completly fine a couple of lines earlier, when setting the headers.

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