[C++] WebRequest POST fehler...



  • Also bin dabei mi Sockets und die HTTP-Request in C++ anzueignen
    Zu dem Zweck versuche ich nun mich mittels POST Beispielsweise auf schueler.cc einzuloggen.
    Verbindung etc sind erfolgreich nur der antwortstring bleibt leer.
    Hoffe jemand sieht vielleicht nen Fehler.

    Quellcode:

    #include <windows.h>
    #include <iostream>
    #include <string>
    
    using namespace std;
    const int BUFFER_SIZE = 65535;
    
    unsigned long GetIP( string host)
    {
       struct hostent* hp;
       unsigned long host_ip;
    
        host_ip = inet_addr( host.c_str() );
        if( host_ip == INADDR_NONE )
        {
    		hp = gethostbyname( host.c_str() );
            if( !hp )
            {
               return 0;
            }else
            {
               host_ip = *(unsigned long *)hp->h_addr;
           }
        }
        return host_ip;
    }
    
    string HTTPRequest( string server, int port, string request)
    {
        WSADATA w;
        int res = WSAStartup( MAKEWORD( 2,0 ), &w );
    
        if( res != 0 )
        {
            cout << "Winsock 2 konnte nicht gestartet werden!\n";
            cin.get();
            return "fail";
        }
        else
        {
            cout << "Winsock 2 gestartet!\n";
        }
    
        SOCKET sSocket = socket( AF_INET, SOCK_STREAM, 0 );
    
        if( sSocket == INVALID_SOCKET)
        {
            cout << "Socket konnte nicht erstellt werden!\n";
            cin.get();
            return "fail";
        }
        else
        {
            cout << "Socket wurde erstellt!\n";
        }
    
        unsigned long ip = GetIP( server );
    
        SOCKADDR_IN service;
        memset( &service, 0, sizeof( SOCKADDR_IN ) );
        service.sin_family = AF_INET;
        service.sin_port = htons( port );
        service.sin_addr.s_addr = ip;
    
        res = connect( sSocket, (SOCKADDR *)(&service), sizeof( SOCKADDR ) );
    
        if( res == SOCKET_ERROR )
        {
            cout << "Verbindung fehlgeschlagen!\n";
            cin.get();
            return "fail";
        }
        else
        {
            cout << "Verbindung erfolgreich!\n";
        }
    
        res = send( sSocket, request.c_str(), request.size(), 0 );
        char buffer[BUFFER_SIZE];
    	res = recv( sSocket, buffer, BUFFER_SIZE-1, 0);
    
    	buffer[res] = '\0';
        WSACleanup();
        string out = buffer;
        return out;
    }
    
    int main()
    {
    	string request =
    "POST / HTTP/1.1\r\n"
    "Host: www.schueler.cc\r\n"
    "Content-Type: application/x-www-form-urlencoded\r\n"
    "Content-Length: 73\r\n"
    "email=***MEINEMAIL***&passwort=***MEINPASSWORT***&button_login_login=Login\r\n";
    
    	string temp = HTTPRequest("www.schueler.cc", 80, request);
    	if( temp == "fail" )
    		return 1;
    	cout << temp << "\n";
    	cin.get();
    	return 0;
    }
    

    So sieht die Anfrage von FireFox aus:

    http://www.schueler.cc/
    
    POST / HTTP/1.1
    Host: www.schueler.cc
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 115
    Connection: keep-alive
    Referer: http://www.schueler.cc/
    Cookie: __utmz=107901184.1300619965.11.6.utmcsr=schueler.cc|utmccn=(referral)|utmcmd=referral|utmcct=/index.php; cookie_email=***MEINEMAIL***; u=1; e=21307189; POPUPCHECK=1300805174218; __utma=107901184.124801668.1300718695.1300718695.1300718946.2; __utmb=107901184.1.10.1300718946; PHPSESSID=1960dd5b84458fca29b63e8483b2e2df; __utmc=107901184
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 73
    email=***MEINEMAIL***&passwort=***MEINPASSWORT***&button_login_login=Login
    HTTP/1.1 302 Found
    Transfer-Encoding: chunked
    X-Powered-By: PHP/5.3.6
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Set-Cookie: cookie_***MEINEMAIL***; expires=Wed, 20-Apr-2011 14:49:58 GMT
    Set-Cookie: u=1; expires=Wed, 20-Apr-2011 14:49:58 GMT
    Set-Cookie: e=21307189; expires=Wed, 20-Apr-2011 14:49:58 GMT
    Location: index.php
    Content-Encoding: gzip
    Vary: Accept-Encoding
    Content-Type: text/html
    Date: Mon, 21 Mar 2011 14:49:58 GMT
    Server: lighttpd/1.4.19
    

    kanns vielleicht an cookies oder des POST strings liegen?



  • Dein Request ist einfach falsch.

    So hast du es gemacht:

    string request =
    "POST / HTTP/1.1\r\n"
    "Host: www.schueler.cc\r\n"
    "Content-Type: application/x-www-form-urlencoded\r\n"
    "Content-Length: 73\r\n"
    "email=***MEINEMAIL***&passwort=***MEINPASSWORT***&button_login_login=Login\r\n";
    

    So wäre es richtig:

    string request =
    "POST / HTTP/1.1\r\n"
    "Host: www.schueler.cc\r\n"
    "Content-Type: application/x-www-form-urlencoded\r\n"
    "Content-Length: 73\r\n\r\n" // <------- \r\n\r\n
    "email=***MEINEMAIL***&passwort=***MEINPASSWORT***&button_login_login=Login\r\n";
    


  • ahhh Dankeschöön.

    so funktionierts.. hab schon an mir gezweifelt.

    Nochmal des Verständniss halber:

    woher wusstest du das "\r\n\r\n" anstelle von "\r\n" dorthin kommt, bzw wie erkenne ich dies überhaupt im allgemeinen?



  • Ohh doch noch ewats falsch...

    ich bekomme jetzt folgende Antwort:
    http://img14.myimg.de/bluberae415.png

    Warum bekomme ich nun nicht die eingeloggte Seite, bzw wie stelle ich an das ich nun auch den html der eingeloggten seite bekomme?

    danke schonma.



  • Das ist so im HTTP-Protokoll festgelegt. Den Standard dazu findest du hier:
    http://tools.ietf.org/html/rfc2616

    Wie du am Umfang des Dokument erkennen kannst, ist das ein größerer Akt, wenn man das vollständig unterstützen will. Daher würde ich dir davon abraten das zu versuchen. Für Testzwecke ist das sicher eine nette Übung und Spielerei, aber für produktiven Code sollte man auf vorhandenes zurückgreifen. Zum Beispiel libcurl. Diese Lib bietet alles was man zum Zugriff auf eine Webseite über HTTP benötigt.



  • Dort steht:

    Location: index.php

    Das ist eine Weiterleitung auf eben diese Seite. Damit das klappt musst du das Cookie extrahieren und bei allen folgenden Aufrufen mitsenden.

    Sprich:
    Login-Seite ansteuern
    Cookie aus Antwort extrahieren
    Index-Seite ansteuern und ab jetzt immer das vorher extrahierte Cookie mitsenden



  • Danke schonmal.
    zur libcurl... gibts hierzu irgendwo ein nettes (möglichst deutsches) tutorial /docu ??? habe da schon nach c++ gesucht, aber finde nichts wirklich brauchbares

    //edit: uuuund: welcher teil der antwort ist der cookie (weil da steht ja mehrfach Set-cookie)



  • hmm ...push.. in der hoffnung jemand hat da doch was in peto



  • Ich weiß das jetzt auch nicht so genau. Was du machen könntest: Vergleiche die Anfrage von Firefox und schau da nach...

    An deiner Stelle würde ich mich aber lieber in libcurl einarbeiten. Damit hast du dann nicht nur Zeit gespart, sondern auch die Gewissheit, das es wirklich funktioniert und bereits von sehr vielen Leuten über einen langen Zeitraum getestet wurde.


Log in to reply