Datei uploaden mit WINNET?

pepsi_gx

Erfahrenes Mitglied
Hallo Forum,

ein Programm mit WININET in VC++ 2008 schreibe ich, um eine Datei auf nen Server hochzuladen. Libcurl und andere ähnliche Bibiotheken habe ich aus persönlichem Grund ausgeschlossen. D.h., ich schreibe zuerst lieber eine Eigene Funktion, die mit z.B. WINNET(ggf. vielleicht auch WinSock) zusammenarbeitet.

Hier der Code von mir:

C++:
void Upload()
{

	HINTERNET inet = InternetOpen("Http Upload", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
               
	if(inet != NULL)
    {    
		HINTERNET connection    = NULL;
		HINTERNET request       = NULL;
		unsigned long flags     = INTERNET_FLAG_PRAGMA_NOCACHE;
		char buffer[1024];
		DWORD InfoLevel, BufferLength;

	                connection = InternetConnect(inet,
                                     "xxx.xx.x.x/upload", // Adresse vom Server
                                     INTERNET_DEFAULT_HTTP_PORT,
                                     NULL, //String
                                     NULL,  //String
                                     INTERNET_SERVICE_HTTP,
                                     flags,
	                1);

                        
		if(connection != NULL)
		{                         
			const char* ContentType = "multipart/form-data";  // Eine Datei (kein Bild oder was anderes) wird hochgeladen
			
                                		request = HttpOpenRequest(connection,                                                         
		                                       "POST", // Verb
                                                                                   "C:\\xxx\\x", // Pfad der hochzuladenen Datei
                                                                                   NULL,       //HTTP standard Version
                                                                                   NULL,      //keine Referenz
                                                                                   &ContentType,
                                                                                   NULL,
			                   NULL);

				if(HttpQueryInfo(request, HTTP_QUERY_CONTENT_LENGTH, (LPVOID)buffer, &BufferLength, NULL))
					cout << "Getting Query Info: " << buffer;
				else
					cout << "Error of getting Query Info: " << GetLastError() << endl; 

			if(!request)
				cout << "Error of requesting: " << GetLastError();
			else
				cout << "Upload succeeded!" << endl;
		}                        
                     
		InternetCloseHandle(request);                        
		InternetCloseHandle(connection);                        
		InternetCloseHandle(inet);

	}
}

Mit der Funktion HttpQueryInfo möchte ich abfragen, wie viele Bytes hochgeladen sind.

Dann mit der Funktion GetLastError habe ich den Fehlercode 12150 bekommen, der nach MSDN "The requested header could not be located" bedeutet, also es müsste irgendwie ein Fehler im Http Head stecken.

Kann jemand mir helfen?

LG

[edit]
Sorry für den Tippfehler im Titel. "WININET" soll statt WINNET stehen.
[/edit]
 
Zuletzt bearbeitet:
Ich bin mit WinInet auch nicht wirklich sattelfest, aber soweit ich begriffen habe, gehört in InternetConnect() nur der Domainname, Pfad und Dateiname dann in HttpOpenRequest()

Code:
...
connection = InternetConnect(inet, "www.domain.com", ... );

...

request = HttpOpenRequest(connection, "POST" , folder/file.php, ...);
...

Ausserdem reicht es dem Header nicht, wenn der Variablenname ContentType ist, das muss schon mit im string stehen

Code:
const char* ContentType = "Content-Type: multipart/form-data";

edit:
Ohne HttpSendRequest() gehts dann aber immer noch nicht.
 
Zuletzt bearbeitet:
Danke zuerst, Thomasio.

Ich bin mit WinInet auch nicht wirklich sattelfest, aber soweit ich begriffen habe, gehört in InternetConnect() nur der Domainname, Pfad und Dateiname dann in HttpOpenRequest()

Code:
...
connection = InternetConnect(inet, "www.domain.com", ... );

...

request = HttpOpenRequest(connection, "POST" , folder/file.php, ...);
...
Wenn man deinen und meinen Code verglicht, ist der dritte Parameter meiner Funktion HttpOpenRequest der Pfad und Dateiname, welche auf die hochzuladene Datei verweist, während er von deiner auf ein PHP Skript (folder/file.php) verweist. Ist es korrekt (oder meinst du doch, daß du das Skript als Beispiel hochladen willst)?

Ausserdem reicht es dem Header nicht, wenn der Variablenname ContentType ist, das muss schon mit im string stehen

Code:
const char* ContentType = "Content-Type: multipart/form-data";

Mit und ohne "Content-Type: " im Variablennamen habe ich schon ausprobiert, leider ändert es nix.

Ohne HttpSendRequest() gehts dann aber immer noch nicht.

Eigentlich wollte ich HttpSendRequest() auch einbinden, aber das Konzept verstehe ich irgendwie nicht. Nachdem ich in MSDN nachgeschlagen habe, soll sie für optionalen Daten dienen. Aber alle Daten einschliessich des Headers, des Dateipfades der hochzuladenen Datei sind m. E. schon in InternetConnect() und HttpOpenRequest() enthalten. :confused:

Und ich frage mich schon immer, soll ich in meinem Fall HttpOpenRequest() bzw. HttpSendRequest() benutzen oder InternetWriteFile()?

Wenn jemand ein lauffähliges Beispiel bieten kann, wäre mir schon sehr geholfen.
 
Der dritte Wert im HttpOpenRequest() ist NICHT die Datei auf deinem Rechner, sondern die Zieldatei auf dem Server, sprich das .php Script, was die Daten empfängt.
HttpOpenRequest() stellt lediglich eine Verbindung zwischen deinem Rechner und der Zieldatei her, erst HttpSendRequest() sendet deine Daten.
Ich kann dir nicht sagen, wie das mit Dateiupload aussieht, aber das dürfte nicht viel anders sein als mit strings.

Was ich dir geben kann ist ein funktionierendes Beispiel, wie man einen string sendet:

Code:
std::string tosend = "SomeText";

HINTERNET inet = InternetOpen("MyAgent",INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
HINTERNET connection;
HINTERNET request;
unsigned long flags;
connection = InternetConnect(inet,"www.domain.com",INTERNET_DEFAULT_HTTP_PORT,0,0,INTERNET_SERVICE_HTTP,0,1);
flags = INTERNET_FLAG_PRAGMA_NOCACHE;
request = HttpOpenRequest(connection,"POST","folder/file.php",0,0,0,flags,1);
HttpSendRequest(request,"Content-Type: application/x-www-form-urlencoded",47,(void*)tosend.c_str(),tosend.size());
InternetCloseHandle(request);
InternetCloseHandle(connection);
InternetCloseHandle(inet);

Ich nehme an, alles was du tun musst ist nichts weiter als den Content-Type ändern und deinen Dateiinhalt als void* senden.
 
Zuletzt bearbeitet:
Hi,

Hmm verstehe ich das richtig?
Du versucht direkt über HTTP eine Datei auf den Server zu übertragen?!
Soweit ihc weiß geht das doch nicht oder?

Du kannst nur die Datei wie Thomasio schon angedeutet hat an ein Script schicken, welches die Datei auf dem Server ablegt.
Ansonsten müsstest du FTP benutzen oder nicht?

Gruß
Anfänger
 
Zuletzt bearbeitet:
Du versucht direkt über HTTP eine Datei auf den Server zu übertragen?!
Soweit ihc weiß geht das doch nicht oder?

Ja, genau das will ich. Und das geht nicht, meinst du damit daß es nicht geht mit Bibliotheken von z.B. WINNET oder WINSock sondern mit z.B. libcurl, oder?
Auch daß das nicht geht, kann ich dir gut glauben. Aber ich gehe davon aus, wenn man ne Verbindung mit dem Server aufbauen kann, sollte das Basteln einer eigenen Hochladefunktion auch nicht möglich, oder?
Sage mir bitte nicht, daß ich libcurl benutzen soll. Den Grund habe ich am Anfang schon erwähnt.;)

Du kannst nur die Datei wie Thomasio schon angedeutet hat an ein Script schicken, welches die Datei auf dem Server ablegt.
Ansonsten müsstest du FTP benutzen oder nicht?

Wenn ich dich richtig verstanden hab, bist du der Meinung, daß das Hochladen über HTTP nur dann geht, wenn man ein Skript wie z.B. PHP auf dem Server vorhanden hat? Ansonsten über FTP?

PS: Bei mir steht nirgendwo ein PHP Skript auf dem Server und den Server hab ich selber nicht hergestellt.

LG
 
Ich schätze da müssen wir bei den alleruntersten Grundlagen anfangen:

JEDE Verbindung zwischen 2 Computern besteht aus 2 Enden, also nicht nur 2 Stück Hardware, sondern auch 2 Stück Software.
Ob du sie nun Server/Client oder sonstwie nennst, einer sendet, der andere empfängt.
Der Sender kann ganz grundsätzlich NICHTS am Empfänger-Ende machen, er kann nur dem Empfänger mitteilen, was er von ihm will, also z.B. zusätzlich zu einer hochgeladenen Datei angeben, wohin sie soll.
Ob du das über WinInet macht, oder FTP oder sonstwas, du brauchst IMMER am Empfänger-Ende eine Software, die die Daten entgegennimmt und weiter verarbeitet, z.B. eine empfangene Datei im richtigen Ordner ablegt.

Natürlich gib es diverse Wege dazu, aber jeder Weg braucht trotzdem einen Empfänger, bei FTP müssen also beide Enden eine FTP Software laufen haben, was meistens auch ein Login erfordert, bei HTTP muss am Server ein PHP (oder ähnliches) Script aufgerufen werden, usw.
 
Ich schätze da müssen wir bei den alleruntersten Grundlagen anfangen:

JEDE Verbindung zwischen 2 Computern besteht aus 2 Enden, also nicht nur 2 Stück Hardware, sondern auch 2 Stück Software.
Ob du sie nun Server/Client oder sonstwie nennst,...

Ich glaube das sollte jedem klar sein oder?
Wollte nur sagen das es ohne ein Script über reine HTTP Anweisungen nicht möglich ist eine Datei zu übertragen oder ist das falsch?

Bei FTP muss natürlich an beiden Seiten die entsprechende Software vorhanden sein, aber wenn dort wo die Datei hin soll ein FTP Server installiert / gestartet ist, muss er nicht noch einen Script auf den Server packen der alles richtig verarbeitet, sondern nur sein Programm schreiben das die Verbindung aufbaut und die Datei an den Server sendet.

Gruß Anfänger
 
Zurück