[C++] libCurl & CURLOPT_WRITEFUNCTION Problem

DasIrrlicht

Grünschnabel
Guten Abend!

Ich versuche mich gerade mit der libCurl und bin auf ein kleines Problem gestoßen. In meinem Programm melde ich mich an einer Website an und lade im Anschluss eine weitere Seite. Diese verwende ich um den Login zu verifizieren. Ist dies gut gegangen lade ich eine dritte Seite und geben diese vorerst nach stdout aus. Da ich mit CURLOPT_WRITEFUNCTION arbeite versuche ich den Speicher vor dem Laden der dritten Seite zu leeren, um keine falschen Daten zu erhalten. Dies funktioniert jedoch nicht, oder zumindest "komisch". ;)

Mit folgendem Code versuche ich es:

C:
struct MemoryStruct{
    char *memory;
    size_t size;
};

static struct MemoryStruct chunk;

// [...]

if(chunk.memory){
   chunk.memory = NULL;
   chunk.size = 0;
}
curl_easy_setopt(curl_handle, CURLOPT_COOKIEFILE, "cookies.txt");
curl_easy_setopt(curl_handle, CURLOPT_COOKIEJAR, "cookies.txt");
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://example.com/dosomething.php");
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
if(curl_easy_perform(curl_handle) != CURLE_OK) return -1;

if(chunk.memory){
   if(!((string)chunk.memory).find(nid)){
      cout << "Session lost!" << endl;
   }
   else {
      cout << "Done! Output:" << endl << endl;
      cout << chunk.memory << endl << endl;
   }
}

Das ist der Aufruf der dritten Seite. Ich hoffe alle wichtigen Informationen sind vorhanden. Hier steht trotz des Zurücksetzens von chunk.memory und chunk.size die Seite auf die ich nach dem Aufruf der Login-Seite weitergeleitet werde. Diese Seite lade ich meines Erachtens nie in den Speicher. Es läuft so ab:

- Aufruf login.php mit Benuztzerdaten
- direkt im Anschluss Abfrage von index.php
- leeren des Speichers
- Abfrage von dosomething.php
- Ausgabe des Speichers

Wichtig ist noch, wenn ich den exakt gleich Code noch einmal ausführe, steht die richtige Seite im Speicher.

Hoffe jemand kann mir erklären was da vor sich geht. :)

Gruß,
Daniel
 
Zuletzt bearbeitet:
WriteMemoryCallback ist definiert wie folgt:

C:
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data){
   size_t realsize = size * nmemb;
   struct MemoryStruct *mem = (struct MemoryStruct *)data;

   mem->memory = myrealloc(mem->memory, mem->size + realsize + 1);
   if (mem->memory) {
      memcpy(&(mem->memory[mem->size]), ptr, realsize);
      mem->size += realsize;
      mem->memory[mem->size] = 0;
   }
   return realsize;
}

Mein Code basiert auf dem Tutorial von http://curl.haxx.se/lxr/source/docs/examples/getinmemory.c

Danke!

Daniel
 
Zuletzt bearbeitet:
Hi.

Das sieht alles OK aus.

Das verleitet mich zu der Vermutung, das der Server genau das sendet was dann dort im Speicher steht. Hast du mal mit Wireshark oder ähnlichem geschaut was dort über die Leitung geht?

Gruß
 
Hi!

Das kann eigentlich nicht sein, da die Seite die im Speicher ist so eine "Anmeldung erfolgreich, hier klicken um fortzufahren" Seite ist. Sprich, die kommt nur ein Mal nach der Anmeldung und dann nie wieder. Da ich ja nach der Seite noch zwei weitere aufrufe, kann ich es mir nur schwer vorstellen.

Bin gerade nicht daheim, werde aber trotzdem mal die Pakete mitsniffen und schauen was wirklich drin steht. Danke fuer den Tip! Wenn das nicht hinhaut, poste ich mal den gesamten Code hier rein (ist nicht so viel) und hoffe dass dann der Fehler gefunden wird :)

Gruesse,
Daniel

PS: Entschuldigt die fehlenden Umlaute, ich habe zwecks dem Programmieren ein US-Layout auf der Tastatur.
 
Guten Abend,

erst mal entschuldigt die arge Verspätung. Ich kam die letzte Woche gar nicht dazu meinen Computer einzuschalten. :(

Ich habe jetzt per Wireshark festgestellt, dass die dritte Anfrage, die ich starte immer noch die POST Daten enthält für die erste Anfrage. Ich gehe davon aus, dass ich für alle Anfragen das selbe curl_handle verwenden muss, damit die Session erkannt werden kann. Muss ich jedoch hier dann die Daten die ich mit curl_easy_setopt() und curl_formadd() aktiviere wieder deaktivieren oder dergleichen? Mir scheint, als vergäße libCurl nicht, was ich bereits erledigt habe und fügt nur neue Daten an. Muss ich dass manuell wieder auf den Null-Zustand setzen? Wenn ja, wie?

Danke,
Daniel
 
Hi.
Ich habe jetzt per Wireshark festgestellt, dass die dritte Anfrage, die ich starte immer noch die POST Daten enthält für die erste Anfrage. Ich gehe davon aus, dass ich für alle Anfragen das selbe curl_handle verwenden muss, damit die Session erkannt werden kann. Muss ich jedoch hier dann die Daten die ich mit curl_easy_setopt() und curl_formadd() aktiviere wieder deaktivieren oder dergleichen? Mir scheint, als vergäße libCurl nicht, was ich bereits erledigt habe und fügt nur neue Daten an. Muss ich dass manuell wieder auf den Null-Zustand setzen? Wenn ja, wie?
Evlt. mit http://curl.haxx.se/libcurl/c/curl_easy_reset.html ?

Gruß
 
Zurück