Problem mit POST und Session-Cookies

Für allgemeine Fragen zur Programmierung mit PureBasic.
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Problem mit POST und Session-Cookies

Beitrag 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?
Win11 x64 | PB 6.20
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8837
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Problem mit POST und Session-Cookies

Beitrag von NicTheQuick »

Ich glaube normalerweise kommt am Anfang immer nur ein #LF$ hin und nur nach der letzten Zeile ein #CRLF$.
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Problem mit POST und Session-Cookies

Beitrag 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.
Win11 x64 | PB 6.20
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8837
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Problem mit POST und Session-Cookies

Beitrag 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.
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Problem mit POST und Session-Cookies

Beitrag 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.
Win11 x64 | PB 6.20
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8837
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Problem mit POST und Session-Cookies

Beitrag 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.
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Problem mit POST und Session-Cookies

Beitrag von Andesdaf »

Danke für den Hinweis auf Wireshark :allright:, damit hab ich die Headerfelder abgeglichen und meinen Fehler gefunden.
Win11 x64 | PB 6.20
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8837
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Problem mit POST und Session-Cookies

Beitrag von NicTheQuick »

Was war es nun?
Andesdaf
Moderator
Beiträge: 2673
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Problem mit POST und Session-Cookies

Beitrag 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.
Win11 x64 | PB 6.20
Antworten