Seite 1 von 1

Problem mit POST und Session-Cookies

Verfasst: 18.11.2014 16:36
von Andesdaf
Hallo,

ich wollte mich jüngst mal von WinAPI-Funktionen in einem Projekt entledigen, deshalb habe ich mir für einen alten Code einen neuen geschrieben.

alter Code (irgendwo hier gefunden und angepasst):

Code: Alles auswählen

#_INTERNET_OPEN_TYPE_DIRECT = 1
#_HTTP_ADDREQ_FLAG_ADD = $20000000
#_HTTP_ADDREQ_FLAG_REPLACE = $80000000
#_INTERNET_FLAG_SECURE = 0
#_INTERNET_SERVICE_HTTP = 3
#_INTERNET_DEFAULT_HTTP_PORT = 80
#_HTTP_QUERY_COOKIE = 44

Procedure.s SendPOST(psPostData.s)
  Protected sUserAgent.s
  Protected sBuffer.s
  Protected sResult.s
  Protected sDomain.s
  Protected sPostHeader.s
  Protected sHost.s
  Protected iOpenHandle.i
  Protected iConnectHandle.i
  Protected iRequestHandle.i
  Protected iSendHandle.i
  Protected iBytesRead.i
  Protected iStatus.i
  
  sHost       = "test.testseite.de"
  sDomain     = ".testseite.de"
  sPostHeader = "Content-Type: application/x-www-form-urlencoded " + #CRLF$
  sPostHeader + "Cookie: testSession=IrgendEineSessionId; path=/; domain=" + sDomain + "; HttpOnly;" + #CRLF$
  sUserAgent  = "IrgendeinUserAgent"
  sBuffer     = Space(1024)
    
  If sHost <> "" And psPostData <> "" And sPostHeader <> ""
    iOpenHandle = InternetOpen_(sUserAgent, #_INTERNET_OPEN_TYPE_DIRECT, "", "", 0)
    If iOpenHandle
      iConnectHandle = InternetConnect_(iOpenHandle, sHost, #_INTERNET_DEFAULT_HTTP_PORT, "", "", #_INTERNET_SERVICE_HTTP, 0, 0)
      If iConnectHandle
        iRequestHandle = HttpOpenRequest_(iConnectHandle, "POST", "http://test.testseite.de/api.php", "", "", 0, #_INTERNET_FLAG_SECURE, 0)
        If iRequestHandle
          HttpAddRequestHeaders_(iRequestHandle, sPostHeader, Len(sPostHeader), #_HTTP_ADDREQ_FLAG_REPLACE | #_HTTP_ADDREQ_FLAG_ADD)
          iSendHandle = HttpSendRequest_(iRequestHandle, "", 0, psPostData, Len(psPostData))
          If iSendHandle
            Repeat
              InternetReadFile_(iRequestHandle, @sBuffer, 1024, @iBytesRead)
              sResult + Left(sBuffer, iBytesRead)
              sBuffer = Space(1024) 
            Until iBytesRead = 0
            
            iStatus = #True       
          Else
            iStatus = -3
          EndIf
        Else
          iStatus = -2
        EndIf
      Else
        iStatus = -1
      EndIf
    Else 
      iStatus = 0 
    EndIf
  Else
    iStatus = 0 
  EndIf
  
  If iStatus < 0 Or iStatus = #True
    InternetCloseHandle_(iOpenHandle)
  EndIf
  
  ProcedureReturn sResult
EndProcedure
neuer Code:

Code: Alles auswählen

Procedure.s httpRequest(psType.s, psData.s)
  Protected iDataLen.i    
  Protected iBffSize.i    
  Protected iConnection.i 
  Protected iRqTime.i     
  Protected iNwEvent.i    
  Protected iRcvSize.i    
  Protected iHdrEnd.i     
  Protected sServer.s     
  Protected sDomain.s     
  Protected sURL.s        
  Protected sCookie.s     
  Protected sRequest.s    
  Protected sRcvData.s    
  Protected *RcvBff       
  
  sServer  = "test.testseite.de"
  sDomain  = Right(sServer, Len(sServer) - FindString(sServer, ".") + 1)
  sURL     = "http://" + sServer + "/api.php"
  sCookie  = "testSession=IrgendEineSessionId"
  iDataLen = StringByteLength(psData, #PB_Ascii)
  iBffSize = 65536
  
  Select psType
    Case "get"
      ; egal
    Case "post"
      sRequest + "POST " + sURL + " HTTP/1.0"                                                  + #CRLF$
      sRequest + "User-Agent: IrgendeinUserAgent"                                              + #CRLF$
      sRequest + "Host: " + sServer                                                            + #CRLF$
      sRequest + "Content-Type: application/x-www-form-urlencoded"                             + #CRLF$
      sRequest + "Content-Length: " + Str(iDataLen)                                            + #CRLF$
      sRequest + "Cookie: " + sCookie + "; path=/; domain=" + sDomain + "; HttpOnly;" + #CRLF$ + #CRLF$
      sRequest + psData
    Default
  EndSelect
  
  iConnection = OpenNetworkConnection(sServer, 80, #PB_Network_TCP | #PB_Network_IPv4)
  If iConnection
    SendNetworkString(iConnection, sRequest, #PB_Ascii)
    iRqTime = ElapsedMilliseconds()
    Repeat
      Delay(10)
      iNwEvent = NetworkClientEvent(iConnection)
    Until iNwEvent
    
    Select iNwEvent
      Case #PB_NetworkEvent_None
      Case #PB_NetworkEvent_Disconnect
      Case #PB_NetworkEvent_Data
        *RcvBff = AllocateMemory(iBffSize)
        If *RcvBff = 0
          ProcedureReturn ""
        EndIf
        Repeat
          iRcvSize = ReceiveNetworkData(iConnection, *RcvBff, iBffSize)
          sRcvData + PeekS(*RcvBff, iRcvSize, #PB_UTF8)
        Until Not iRcvSize
        FreeMemory(*RcvBff)
        
        iHdrEnd = FindString(sRcvData, #LFCR$, 1)
                
        If iHdrEnd
          ProcedureReturn Mid(sRcvData, iHdrEnd + 3)
        Else
          ProcedureReturn sRcvData
        EndIf
    EndSelect
    CloseNetworkConnection(iConnection)
  EndIf
  
EndProcedure
(nur schnell zusammengekürzt)

Zuvor führe ich einen Login aus, aus dem ich dann die Session-ID ermittele und wieder übergebe. Abhängig davon, ob ich angemeldet bin, bekomme ich bei einer Folgeanfrage Daten ausgeliefert oder nicht. Benutze ich den alten Code, klappt alles wunderbar. Wenn ich den neuen Code benutze, klappt zwar der Login, aber ich bekomme die Daten in der Folgeabfrage nicht angezeigt. Es muss also irgendwie daran liegen, dass ich die Cookies im neuen Code nicht richtig übergebe und meine Sitzung nicht erkannt wird. Aber ich sende soweit ich weiß den gleichen Header...

Was macht der zweite (neue) Code anders bzw. wie bekomme ich die Cookies korrekt übertragen?

Re: Problem mit POST und Session-Cookies

Verfasst: 18.11.2014 19:21
von NicTheQuick
Ich glaube normalerweise kommt am Anfang immer nur ein #LF$ hin und nur nach der letzten Zeile ein #CRLF$.

Re: Problem mit POST und Session-Cookies

Verfasst: 18.11.2014 19:40
von Andesdaf
Laut http://de.wikipedia.org/wiki/Hypertext_ ... tionsweise werden Headerfelder durch CRLF abgetrennt.

Ich hab es spaßenshalber trotzdem mal probiert, brachte aber kein Ergebnis.

Dennoch danke für deine Antwort.

Re: Problem mit POST und Session-Cookies

Verfasst: 18.11.2014 19:43
von NicTheQuick
Interessant. Her hat auch #LF$ gereicht: http://www.purebasic.fr/german/viewtopic.php?f=3&t=28508

Edit:
Ach, moment. Ich glaube jetzt habe ich den Fehler. Du darfst nicht "http://domain.tld/pfad/file.php" nach dem POST schreiben, sondern einfach nur "/pfad/file.php". Dass es sich hier um HTTP-Protokol handelt, ist ja sowieso schon klar. Und der Host wird ja auch nochmal extra angegeben. Das muss man nicht nochmal angeben.

Re: Problem mit POST und Session-Cookies

Verfasst: 18.11.2014 21:40
von Andesdaf
Auch das hilft leider nicht.

An sich funktioniert der POST request, ich bekomme ein Ergebnis (XML-Struktur) zurück, nur
sind einige Attribute eben leer, da mein Session-Cookie irgendwie nicht erkannt wird (so vermute ich).

Das sende ich im Header:

Code: Alles auswählen

POST /w/api.php HTTP/1.0
User-Agent: abcd
Host: test.testseite.de
Accept-Charset: utf-8
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 45
Cookie: Session=xyz; path=/; domain=.testseite.de; HttpOnly;
Das bekomme ich:

Code: Alles auswählen

HTTP/1.1 200 OK
Server: Apache
X-Content-Type-Options: nosniff
Cache-control: private
X-Frame-Options: DENY
Content-Type: text/xml; charset=utf-8
Vary: Accept-Encoding,X-Use-HHVM
X-Varnish: 1065548698, 834413282, 1427052042
Via: 1.1 varnish, 1.1 varnish, 1.1 varnish
Content-Length: 347
Accept-Ranges: bytes
Date: Tue, 18 Nov 2014 19:35:27 GMT
Age: 0
Connection: keep-alive
X-Cache: cp1052 miss (0), amssq48 miss (0), amssq38 frontend miss (0)
X-Analytics: php=zend
Set-Cookie: GeoIP=xyz; Path=/; Domain=.testseite.de
Könnte es evtl. ein Kodierungsproblem sein? Ich bin im Ascii-Compilermodus. Die SessionID bekomme ich über die Loginabfrage
in einer UTF8-XML-Struktur zurück. Die SessionID kommt in eine Map und wird von dort aus bei den folgenden requests übermittelt.

Re: Problem mit POST und Session-Cookies

Verfasst: 18.11.2014 23:07
von NicTheQuick
Komisch ist das ganze schon. Sicher, dass das Cookie für .testseite.de gedacht ist und nicht für test.testseite.de?
Ansonsten würde ich mal Firebug in Firefox aktivieren und das ganze manuell kurz durchspielen und anschauen, was genau passiert. Oder die harte Tour nehmen und mit Wireshark mitschneiden, was passiert.
Ansonsten habe ich auch zu wenig Erfahrung damit und kann dir an dieser Stelle nicht mehr weiterhelfen.

Re: Problem mit POST und Session-Cookies

Verfasst: 23.11.2014 16:55
von Andesdaf
Danke für den Hinweis auf Wireshark :allright:, damit hab ich die Headerfelder abgeglichen und meinen Fehler gefunden.

Re: Problem mit POST und Session-Cookies

Verfasst: 23.11.2014 20:00
von NicTheQuick
Was war es nun?

Re: Problem mit POST und Session-Cookies

Verfasst: 28.11.2014 16:28
von Andesdaf
Ich musste eigentlich noch weitere Cookies senden, das stand aber serverseitig nirgendwo beschrieben.
Der API-Code handelt die Cookies automatisch, daher hat es dort funktioniert, bei meinem Code ohne
genaues Cookie-Handling aber nicht. Mit Wireshark hab ich dann geschaut, was der API-Code sendet
und meinen dann entsprechend angepasst.