File-Upload in C++
-
Hallo,
ich habe mal eine Frage. Ich bekomme keine funktionierende Routine hin, mit der ich Daten auf einen Webserver hochladen kann. Sämtliche Formulardaten kriege ich mit getenv() getline(cin,..) usw. eingelesen. Egal ob GET oder POST. Das ist nicht das Problem.
Ist das Formular jedoch als "multipart/..." encodiert, weiss ich einfach nicht, was ich machen soll. Hab schon mehrere Lib´s ausprobiert, jedoch bekomme ich die garnicht ans rennen.
Deshalb will ich das Zeug´s selber coden. Dann ist man unabhängig.
Vielleicht hat ja jemand von euch ´nen Tip. Ihr würdet mir sehr helfen.Schöne Grüße und Besten Dank im voraus,
Dannyc
-
diese lib wollte ich irgendwann mal testen..
zumindest hat sie ein upload dabei.vielleicht hilfts.
-
Versuchs mal damit
-
Hallo!
Ich hab mal was gecodet. Ein Programm, welches die Formulardaten in C++ einliest. Ich gebe zu, das es etwas wild ist, aber egal.
Folgendes Problem:
Die GET und POST Daten lassen sich einlesen. Selbst, wenn das Formular als multipart/form-data encodiert ist. Lade ich jetzt eine Textdatei hoch, kommen alle Daten einwandfrei rein. Lade ich eine Binäre Datei hoch, erscheinen mir die übermittelten Daten irgendwie falsch.Wenn ich das richtig verstehe, kommen die Daten der hochgeladenen Datei nach dem Spruch "Content-Type: application/octet-stream", oder? Schaut euch mal die Debug-Ausgaben meines Programms an.
Info zu dem Formular: Es befinden sich zwei Textfelder mit den Namen "textfield1" und "textfield2" darin. Außerdem zwei file-Felder mit den Namen "file1" und "file2". Ja, auch ein Submit-Button ist drin.
Zuerst einmal der Code meines Programms:
#include <cstdio> #include <iostream> #include <string> using namespace std; int main() { /* Variablen deklarieren */ int pos; int postlen; char * pcReqMtd; char * pcQuery; char * pcContent; char * pcCType; char * post; char * tmp; string pcCINGET; string CType; /* HTML-Header printen */ cout<<"Content-type: text/html\n\n"<<endl; /* Request-Methode auslesen */ pcReqMtd = getenv("REQUEST_METHOD"); /* Ist der Request GET */ if(strcmp("GET",pcReqMtd) == 0) { pcQuery = getenv("QUERY_STRING"); cout<<"REQUEST_METHOD : "<<pcReqMtd<<"<br>"<<endl; cout<<"QUERY_STRING : "<<pcQuery<<"<br>"<<endl; } /* Ist der Request POST */ if(strcmp("POST",pcReqMtd) == 0) { /* Content-Type und Content-Length lesen */ pcCType = getenv("CONTENT_TYPE"); pcContent = getenv("CONTENT_LENGTH"); /* Umwandlung von char in string, und suchen nach einem Semikolon, um herauszufinden, ob der Content-Type normal, oder multipart... ist */ CType = pcCType; pos = CType.find(";",0); if(pos > -1) { CType.assign(pcCType,0,pos); } /* Normales POST-Form */ if(CType == "application/x-www-form-urlencoded") { getline(cin, pcCINGET); cout<<"REQUEST_METHOD : "<<pcReqMtd<<"<br>"<<endl; cout<<"CONTENT_TYPE : "<<pcCType<<"<br>"<<endl; cout<<"CONTENT_LENGTH : "<<pcContent<<"<br>"<<endl; cout<<"PARAMETER´S : "<<pcCINGET<<"<br>"<<endl; } /* POST-Formular mit multipart/form-data */ if(CType == "multipart/form-data") { /* Infos ausprinten */ cout<<"REQUEST_METHOD : "<<pcReqMtd<<"<br>"<<endl; cout<<"CONTENT_TYPE : "<<pcCType<<"<br>"<<endl; cout<<"CONTENT_LENGTH : "<<pcContent<<"<br>"<<endl; /* Daten einlesen */ postlen = atoi(pcContent); if (postlen > 0) { post = new char[postlen+1]; tmp = new char[postlen+1]; strcpy(post, ""); while(postlen>0) { strcpy(tmp, ""); fgets(tmp, postlen+1, stdin); postlen -= strlen(tmp)+1; strcat(post, tmp); } } /* POST-Daten ausgeben */ cout<<"POST : "<<post<<"<br>"<<endl; } } return 0; }
Das ist die DEBUG-Ausgabe, wenn ich eine Textdatei hochlade:
REQUEST_METHOD : POST
CONTENT_TYPE : multipart/form-data; boundary=---------------------------7d42cea4020a
CONTENT_LENGTH : 863
POST : -----------------------------7d42cea4020a Content-Disposition: form-data; name="textfield1" Wert1 -----------------------------7d42cea4020a Content-Disposition: form-data; name="textfield2" Wert2 -----------------------------7d42cea4020a Content-Disposition: form-data; name="file1"; filename="C:\test.txt" Content-Type: text/plain [TEXT_BEGIN] Hallo, und Willkommen zu diesem Testtext. Dieser Text wurde erstellt, um den File-Upload meines C++ Programms zu testen. Wenn man diesen Text jetzt lesen kann, hat der Test funktioniert. [TEXT_ENDE] -----------------------------7d42cea4020a Content-Disposition: form-data; name="file2"; filename="" Content-Type: application/octet-stream -----------------------------7d42cea4020a Content-Disposition: form-data; name="Submit" Abschicken -----------------------------7d42cea4020a--Das ist die DEBUG-Ausgabe, wenn ich eine binäre Datei hochlade:
Es ist ein EXE. Das compilierte EXE meines Programms.REQUEST_METHOD : POST
CONTENT_TYPE : multipart/form-data; boundary=---------------------------7d4251104020a
CONTENT_LENGTH : 90790
POST : -----------------------------7d4251104020a Content-Disposition: form-data; name="textfield1" Wert1 -----------------------------7d4251104020a Content-Disposition: form-data; name="textfield2" Wert2 -----------------------------7d4251104020a Content-Disposition: form-data; name="file1"; filename="C:\Server\cgi-bin\cgi.exe" Content-Type: application/octet-stream MZ$-‹MèójjèÉVielleicht könnt Ihr mir ja helfen!
Besten Dank im voraus.Gruß
Dannyc