Fehler 302 und 400 bei HTTP-Request mit curl



  • Hallo zusammen

    ich schreibe momentan ein C-Programm das unterschiedliche URLs aufrufen soll um den Inhalt auszulesen bzw. per HTTP-Get auch Werte übergeben soll.

    Bei der Testanwendung habe ich das Problem das der Aufruf der Webseite entweder mit der Fehlermeldung 302 oder 400 quittiert wird. Hier erstmal das Code:

    #include <stdio.h>
    #include <string.h>
    #include <curl/curl.h>
    
    static int wait_on_socket(int sockfd, int for_recv, long timeout_ms) {
        struct timeval tv;
        fd_set infd, outfd, errfd;
        int res;
    
        tv.tv_sec = timeout_ms / 1000;
        tv.tv_usec= (timeout_ms % 1000) * 1000;
    
        FD_ZERO(&infd);
        FD_ZERO(&outfd);
        FD_ZERO(&errfd);
    
        FD_SET(sockfd, &errfd); /* always check for error */
    
        if(for_recv) {
            FD_SET(sockfd, &infd);
        } else {
            FD_SET(sockfd, &outfd);
        }
    
        /* select() returns the number of signalled sockets or -1 */
        res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
        return res;
    }
    
    int main(void) {
        CURL *curl;
        CURLcode res;
    
        const char *request = "GET / /pfad/zur/datei/xyz.php HTTP/1.0\r\n Host: www.example.net\r\n\r\n";
        const char *request = "GET / HTTP/1.0\r\nHost: www.example.net/pfad/zur/datei/xyz.php\r\n\r\n";
    
        size_t iolen;
        int sockfd; /* socket */
        printf("%s\n", request);
    
        curl = curl_easy_init();
        if(curl) {
            curl_easy_setopt(curl, CURLOPT_URL, "www.example.net/pfad/zur/datei/xyz.php");
            curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
            res = curl_easy_perform(curl);
            if(!res) {
                printf("OK\n");
                res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockfd);
                res = curl_easy_send(curl, request, strlen(request), &iolen);
                if(!res) {
                    char buffer[1024];
                    wait_on_socket(sockfd, 1, 60000L);
                    res = curl_easy_recv(curl, buffer, 1024, &iolen);
                    int i = 0;
                    for(i; i<1024; i++) {
                        printf("%c", buffer[i]);
                    }
                    printf("%d\n", res);
                } else {
                    printf("Fehler: %d\n", res);
                }
    
            } else {
                printf("Fehler: %d\n", res);
            }
        }
        return 0;
    }
    

    Nutze ich den Request aus Zeile 34 erhalte ich die Meldung 302 und bei Zeile 35 erhalte ich die Meldung 400. Die Datei liegt aber zu 100% an dem angegebenen Pfad und ein redirect wird nicht vorgenommen, denn wenn ich die URL in einem Browser eingebe wird die Seite korrekt angezeigt. Ich habe das auch schon mit google ausprobiert

    //const char *request = "GET / HTTP/1.1\r\nHost: www.google.de\r\n\r\n";
    

    und da geht es 😕

    Wo liegt denn mein Denkfehler?



  • Das Problem ist gelöst.

    In Zeile 34 steht:

    const char *request = "GET / /pfad/zur/datei/xyz.php HTTP/1.0\r\n Host: www.example.net\r\n\r\n";
    

    Richtig wäre aber:

    const char *request = "GET /pfad/zur/datei/xyz.php HTTP/1.0\r\n Host: www.example.net\r\n\r\n";
    

    Nach dem GET war also ein "/" zu viel und genau dort war auch der besagte redirect.



  • Warum konstruierst du überhaupt deine eigenen Requests, wenn du libcurl verwendest? Normalerweise nutzt man setopt um die Parameter des Aufrufs einzustellen und nimmt dann curl_easy_perform um libcurl den Aufruf durchzuführen.



  • Später sollen über die URL Werte an den Webserver übergeben werden bzw. die Antwort des Aufrufs ausgewertet werden.

    Ein Aufruf über curl_easy_perform() gibt aber die Antwort direkt aus aber ich muss auch noch den Inhalt auswerten (Statusmeldungen, Quelltext, etc.)



  • 302 ist keine Fehlermeldung

    Statuscodes mit 3xx deuten auf eine Umleitung hin. Im Location-Feld des Antwort-Headers steht die Adresse, wo die Ressource zu finden ist

    bei 400 ist dein Request einfach fehlerhaft



  • crazykay schrieb:

    Später sollen über die URL Werte an den Webserver übergeben werden bzw. die Antwort des Aufrufs ausgewertet werden.

    Ein Aufruf über curl_easy_perform() gibt aber die Antwort direkt aus aber ich muss auch noch den Inhalt auswerten (Statusmeldungen, Quelltext, etc.)

    Das ist nur die Standardoption. Normalerweise setzt man ja vorher mit curl_easy_setopt einen Writebuffer oder eine Writefunktion. Den Aufruf selbst zusammen bauen und abzuschicken ist echt nicht der Sinn hinter libcurl!

    Der Sinn ist ja gerade, dass man libcurl den ganzen http kram erledigen lässt. Weil dort ist ja schon die richtige Behandlung für 302 (redirection) eingebaut. Ich weiß libcurl hat eine beschissene API. Aber du solltest dir noch einmal die Optionen durchschauen, es kann wirklich alles was du brauchst (ohne eigene http requests zu konstruieren).


Anmelden zum Antworten