2016-05-30 13 views
1

Ich bin ein C-Programm implementieren, die die Größe einer Remote-Datei aus dem Header Content-Length lesen muss (wenn Content-Length in den Antwortheadern gesendet wird).Wie kann ich mit CURLOPT_HEADERFUNCTION ein einzelnes Antwortheaderfeld lesen?

Ich habe über die Dokumente von libcurl nachgeschaut, und das Beste, was ich bis jetzt hatte, war eine Callback-Funktion für die CURLOPT_HEADERFUNCTION Einstellung. Ich habe zusammen ein Spielzeug Umsetzung eines Rückruf setzen, die die Header STDOUT drucken soll:

size_t hdf(char* b, size_t size, size_t nitems, void *userdata) { 
    printf("%s", b); 
    return 0; 
} 

Während ich möchte den Content-Length Header drucken können (oder zumindest alle Header drucken), habe ich diese Funktion nur bekommen kann den Antwortcode drucken:

$ ./curltest "some_url_which_sends_back_Content_Length" 
HTTP/1.1 200 OK 

Wenn ich die Zeile in meinem main Kommentar aus, die den Rückruf an die hdf oben definierte Funktion setzt, ist das Standardverhalten alle Header drucken zu STDOUT.

Als Referenz ist hier die main Funktion Ich verwende, basierend auf einem Gewinde auf der Libcurl Mailingliste:

int main(int argc, char *argv[]) 
{ 
    CURLcode ret; 
    CURL *hnd = curl_easy_init(); 
    curl_easy_setopt(hnd, CURLOPT_URL, argv[1]); 
    curl_easy_setopt(hnd, CURLOPT_HEADER, 1); 
    curl_easy_setopt(hnd, CURLOPT_NOBODY, 1); 
    curl_easy_setopt(hnd, CURLOPT_HEADERFUNCTION, hdf); 
    ret = curl_easy_perform(hnd); 
    curl_easy_cleanup(hnd); 
} 

Wie kann ich einen Rückruf für die CURLOPT_HEADERFUNCTION Option schreiben, die auf einen speziellen Header laden in den Speicher oder anderweitig manipulieren - oder zumindest alle Header in den Speicher laden?

Antwort

4

Ich kann nur diese Funktion erhalten den Antwortcode drucken:

Die Antwort darauf ist in der CURLOPT_HEADERFUNCTION Dokumentation:

Diese Funktion wird durch Libcurl wie es so schnell aufgerufen wird hat Kopfdaten erhalten. Der Header-Callback wird für jeden Header einmal aufgerufen und nur vollständige Header-Zeilen werden an den Callback übergeben. Parsing Header ist sehr einfach mit diesem. Die Größe der Daten, auf die der Puffer zeigt, ist die Größe multipliziert mit nmemb. Gehen Sie nicht davon aus, dass die Kopfzeile null terminiert ist! Der Zeiger userdata wird mit der Option CURLOPT_HEADERDATA definiert. Diese Callback-Funktion muss die Anzahl der tatsächlich betreuten Bytes zurückgeben. Weicht dieser Betrag von dem an Ihre Funktion übergebenen Betrag ab, wird ein Fehler in der Bibliothek angezeigt. Dies führt dazu, dass die Übertragung abgebrochen wird und die laufende libcurl-Funktion CURLE_WRITE_ERROR zurückgibt.

Ihr printf() Anruf wird unter der Annahme, Null-Terminierung und Ihr Rückruf wird weniger Bytes als vorgesehen zurückkehrt, so dass Sie Abbruch der Reaktion nach der ersten Antwortleitung empfangen wird.

Versuchen Sie es stattdessen.

size_t hdf(char* b, size_t size, size_t nitems, void *userdata) { 
    size_t numbytes = size * nitems; 
    printf("%.*s\n", numbytes, b); 
    return numbytes; 
} 

Wie kann ich einen Rückruf für die CURLOPT_HEADERFUNCTION Option schreiben, die auf einen speziellen Header in den Speicher geladen werden kann oder es anderweitig manipulieren - oder zumindest laden alle Header in den Speicher?

Sobald Sie Ihren Fehler beheben, sollten Sie in der Lage sein, alle Überschriften zu sehen. Sie können dann b auf der Suche nach dem Content-Length-Header analysieren, und wenn gefunden, speichern Sie die Daten in einem Puffer, den Sie an userdata über CURLOPT_HEADERDATA übergeben.

Nun, mit dem gesagt, gibt es eine einfachere Möglichkeit, den Content-Length-Wert abzurufen. Führen Sie eine HEAD Anfrage mit curl_easy_perform() (CURLOPT_NOBODY), und wenn sie erfolgreich als curl_easy_getinfo() verwenden, um Abrufen den CURLINFO_CONTENT_LENGTH_DOWNLOAD Wert:

CURLINFO_CONTENT_LENGTH_DOWNLOAD
Inhalt Länge von den Content-Length-Header.

+0

D'oh, ich muss mehr auf die Dokumente achten. Danke für die Erklärung! – Jules

Verwandte Themen