POST Upload klappt nicht?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

POST Upload klappt nicht?

Beitrag von Blackskyliner »

Warum klappt dieser POST Upload nicht, ich bekomme einfach nichts ans PHP-Script übergeben :-\

Code: Alles auswählen

If InitNetwork() = 0
	MessageRequester("Error", "Can't initialize the network !", 0)
	End
EndIf

; POST RAW-Header
; 
; POST /test.php?works HTTP/1.1
; Host: localhost:8080
; User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
; Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
; Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
; Accept-Encoding: gzip,deflate
; Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
; Keep-Alive: 115
; Connection: keep-alive
; Referer: http://localhost:8080/test.html
; 
; Content-Type: multipart/form-Data; boundary=---------------------------11538186919912 
; Content-Length: 926 
; 
; -----------------------------11538186919912 
; Content-Disposition: form-Data; name="datei"; filename="crashreporter-override.ini" 
; Content-Type: application/octet-stream 
; 
; # This file is in the UTF-8 encoding
; [Strings]
; # LOCALIZATION NOTE (CrashReporterProductErrorText2): The %s is replaced With a string containing detailed information.
; CrashReporterProductErrorText2=Ein Problem ist aufgetreten und Firefox ist abgestürzt.Es wird versucht, Ihre Tabs und Fenster bei einem Neustart wiederherzustellen.\n\nBedauerlicherweise kann der Absturz-Melder diesen Absturz nicht melden.\n\nDetails: %s
; CrashReporterDescriptionText2=Ein Problem ist aufgetreten und Firefox ist abgestürzt. Es wird versucht, Ihre Tabs und Fenster bei einem Neustart wiederherzustellen.\n\n\nUm uns zu helfen, dieses Problem zu erkennen und zu reparieren, können Sie uns eine Absturz-Meldung schicken.




; 
; POST /upload/upload.php HTTP/1.1
; Host: deinehp.de
; Content-Type: multipart/form-data; boundary=-------------------------------test
; Content-Length: ;Anzahl der Bytes nach der Leerzeile
; 
; -------------------------------test
; Content-Disposition: form-data; name="myfile"; filename="bild.jpg"
; Content-Type: image/jpeg
; 
; ;Bilddaten
; -------------------------------test
Global EOL$ 
EOL$ = Chr(13)+Chr(10) 

; http://localhost:8080/test.php
server$ = "localhost"
Port = 8080

; Alles was nach dem SERVER kommt
url$ = "/"
filename$ = "test.php"

uploadFile$ = OpenFileRequester("Bla", "", "*.*|*.*", 0);"C:\\loaderSettings.ini"

; Mal noch was besseres einfallen lassen :-\
; Boundary name
RandomSeed(Date())
GUID.l = Random(Date())

Debug GUID

; Content Size + Header + Boundary
Size.l = 0;


boundary$ = "-------------------------------"+Str(GUID)+EOL$
FileHeader$ = "Content-Disposition: form-data; name="+Chr(34)+"datei"+Chr(34)+"; filename="+Chr(34)+"bild.txt"+Chr(34)+EOL$
FileHeader$ + "Content-Type: application/octet-stream"+EOL$+EOL$


*buff = AllocateMemory(FileSize(uploadFile$)+1)
If ReadFile(1, uploadFile$)
	Debug "File Loaded"
	ReadData(1,*buff, MemorySize(*buff))
	CloseFile(1)
EndIf 

; Boundary oben und unten
Size + 2*Len(boundary$)
; Header Size
Size + Len(FileHeader$)
; Datei size
Size + MemorySize(*buff)

Debug "Content Length:"+Str(Size)

ConnectionID = OpenNetworkConnection(server$, Port) 

If ConnectionID

	SendNetworkString(ConnectionID, "POST "+url$+filename$+"?upload HTTP/1.1"+EOL$) 
	SendNetworkString(ConnectionID, "Host: "+server$+":"+Str(Port)+EOL$) 
	SendNetworkString(ConnectionID, "Accept: */*"+EOL$) 
	
	SendNetworkString(ConnectionID, "Content-Type: multipart/form-data; boundary="+boundary$)
	SendNetworkString(ConnectionID, "Content-Length: "+Str(Size))
	
	SendNetworkString(ConnectionID, boundary$)
	SendNetworkString(ConnectionID, FileHeader$)
	
	SendNetworkData(ConnectionID, *buff, MemorySize(*buff))
	
	SendNetworkString(ConnectionID, boundary$)

	
	SendNetworkString(ConnectionID, EOL$) 
	Debug "File has been sent"
	
	CloseNetworkConnection(ConnectionID)
Else
	MessageRequester("PureBasic - Client", "Can't find the server (Is it launched ?).", 0)
EndIf

End   
Ich weiß nicht warum, denn eigentlich sollte alles hinhaun... :(
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
X360 Andy
Beiträge: 1206
Registriert: 11.05.2008 00:22
Wohnort: Bodensee
Kontaktdaten:

Re: POST Upload klappt nicht?

Beitrag von X360 Andy »

(Hab mir den Cod nicht angeschaut ... da meine Glaskugel dein PHP Script nicht kennt )

Schau dir mit Firebug ( FF Addon ) an was du normal über den Browser alles an dein Formular sendest damit es klappt.

[In Firebug unter Netzwerk findest Anfrage-Header des Post Requests]

Kopier den Anfrage-Header des POST Request´s in dein Programm ( erstmal Statisch, ohne die Datei auszuwechseln ! ) und schau ob es dann geht.
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Re: POST Upload klappt nicht?

Beitrag von Blackskyliner »

Meine güte, ein Upload Script sieht immer gleich aus xD, da braucht man keine Glaskugel...

Code: Alles auswählen

<?php
function writeToFile($file, $label, $array, $indent = 1){
	$_newLine = "\r\n";
	if($label != NULL)
		fwrite($file, $label.$_newLine);
		
	$_intendString = "";
	
	for($i = 0; $i < $indent; $i++)
		$_intendString .= "\t";
	
	foreach($array as $k => $sub){
		if(is_array($sub))
		{
			fwrite($file, $_intendString."[".$k."]".$_newLine);
			writeToFile($file, NULL, $sub, ++$indent);
		}else
			fwrite($file, $_intendString."[".$k."] => ".$sub.$_newLine);
	}
}


$f = fopen("log.txt", "w+");

print_r($_POST);
print_r($_FILES);
print_r($_GET);

writeToFile($f, "POST", $_POST);
writeToFile($f, "FILES", $_FILES);
writeToFile($f, "GET", $_GET);

$target_path = basename( $_FILES['datei']['name']); 

if(move_uploaded_file($_FILES['datei']['tmp_name'], $target_path)) {
    echo "The file ".  basename( $_FILES['datei']['name']). 
    " has been uploaded";
} else{
    echo "There was an error uploading the file, please try again!";
}

fclose($f);

?>
Wobei das erstere nur wegen Debugging Zwecken mit drin ist damit ich weiß was überhaupt so alles übergeben wurde...
Und ein Firebug Report sieht man ja als Kommentar im Script ganz oben... Von daher weiß ich schon das der Firefox das Addon mit der Möglichkeit bietet... Wenigstens mal kurz drüber schauen hätte geholfen... Aber ich werde mal das mit dem statischen Ausprobieren was du da schreibst... Vielleicht klappt es da ja, dann muss es ja irgendwo an mir liegen :), wobei ich syntaktisch und Reihenfolge technisch richtig sein müsste...
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Re: POST Upload klappt nicht?

Beitrag von Blackskyliner »

Sooo ich habe jetzt mal rum Probiert und das statische hier geht auch nicht:

Code: Alles auswählen

	SendNetworkString(ConnectionID, "POST /test.php?works HTTP/1.1"+EOL$)
	SendNetworkString(ConnectionID, "Host: localhost:8080"+EOL$)
	SendNetworkString(ConnectionID, "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"+EOL$)
	SendNetworkString(ConnectionID, "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"+EOL$)
	SendNetworkString(ConnectionID, "Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3"+EOL$)
	SendNetworkString(ConnectionID, "Accept-Encoding: gzip,deflate"+EOL$)
	SendNetworkString(ConnectionID, "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7"+EOL$)
	SendNetworkString(ConnectionID, "Keep-Alive: 115"+EOL$)
	SendNetworkString(ConnectionID, "Connection: keep-alive"+EOL$)
	SendNetworkString(ConnectionID, "Referer: http://localhost:8080/test.html"+EOL$)
	SendNetworkString(ConnectionID, ""+EOL$)
	SendNetworkString(ConnectionID, "Content-Type: multipart/form-Data; boundary=---------------------------11538186919912 "+EOL$)
	SendNetworkString(ConnectionID, "Content-Length: 926 "+EOL$)
	SendNetworkString(ConnectionID, ""+EOL$)
	SendNetworkString(ConnectionID, "-----------------------------11538186919912"+EOL$)
	SendNetworkString(ConnectionID, "Content-Disposition: form-Data; name="+Chr(34)+"datei"+Chr(34)+"; filename="+Chr(34)+"crashreporter-override.ini"+Chr(34)+EOL$)
	SendNetworkString(ConnectionID, "Content-Type: application/octet-stream "+EOL$)
	SendNetworkString(ConnectionID, ""+EOL$)
	SendNetworkString(ConnectionID, "# This file is in the UTF-8 encoding"+EOL$)
	SendNetworkString(ConnectionID, "[Strings]"+EOL$)
	SendNetworkString(ConnectionID, "# LOCALIZATION NOTE (CrashReporterProductErrorText2): The %s is replaced With a string containing detailed information."+EOL$)
	SendNetworkString(ConnectionID, "CrashReporterProductErrorText2=Ein Problem ist aufgetreten und Firefox ist abgestürzt.Es wird versucht, Ihre Tabs und Fenster bei einem Neustart wiederherzustellen.\n\nBedauerlicherweise kann der Absturz-Melder diesen Absturz nicht melden.\n\nDetails: %s"+EOL$)
	SendNetworkString(ConnectionID, "CrashReporterDescriptionText2=Ein Problem ist aufgetreten und Firefox ist abgestürzt. Es wird versucht, Ihre Tabs und Fenster bei einem Neustart wiederherzustellen.\n\n\nUm uns zu helfen, dieses Problem zu erkennen und zu reparieren, können Sie uns eine Absturz-Meldung schicken."+EOL$)
	SendNetworkString(ConnectionID, "-----------------------------11538186919912"+EOL$)
	
Also muss der Fehler woanders liegen? Aber wo?

Oder wäre es besser, alles in eine String Buffer zu klatschen und das gesamte Paket mit einmal zu übertragen?
Wie groß darf dann die Datei sein damit man alles mit einmal senden darf? Ist das dann egal? oder kann man dann auch chunked die Daten übertragen? Also in k.A. 200Byte Fetzen, und der Webserver wartet geduldig bis alles da ist, bevor er verarbeitet?
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Dark
Beiträge: 93
Registriert: 24.08.2007 20:36
Kontaktdaten:

Re: POST Upload klappt nicht?

Beitrag von Dark »

Hallo,

der Fehler liegt da drinne, das erstmal ein paar Zeilenumbrüche fehlten und zweitens auch die Information mit dem Boundary (die du auch teilweise von mir übernommen hattest :roll:) nicht 100% korrekt waren.

So, als Entschädigung für die falschen Informationen habe ich dir ein kleines System geschrieben, was auf deinem code basiert. Bei mir funktioniert es:

Code: Alles auswählen

If InitNetwork() = 0
   MessageRequester("Error", "Can't initialize the network !", 0)
   End
EndIf


Global EOL$
EOL$ = Chr(13)+Chr(10)

; http://localhost:8080/test.php
server$ = "192.168.1.9"
Port = 80

; Alles was nach dem SERVER kommt
url$ = "/"
filename$ = "upload.php"

uploadFile$ = OpenFileRequester("Bla", "", "*.*|*.*", 0);"C:\\loaderSettings.ini"

; Mal noch was besseres einfallen lassen :-\
; Boundary name
RandomSeed(Date())
GUID.l = Random(Date())

Debug GUID

; Content Size + Header + Boundary
Size.l = 0;

Structure ContentData
  Size.i
  *Memory
EndStructure

Structure PostRequest
  Header.s
  Boundary.s
  List Content.ContentData()
EndStructure

Procedure Post_CreateRequeset(URL.s, Host.s, Port.i, Boundary.s)
  Protected *Request.PostRequest = AllocateMemory(SizeOf(PostRequest))
  
  If *Request
    InitializeStructure(*Request,PostRequest) 
    *Request\Boundary = Boundary
    *Request\Header = "POST /"+URL+" HTTP/1.1"+EOL$
    *Request\Header + "Host: "+Host+":"+Str(Port)+EOL$
    *Request\Header + "Accept: */*"+EOL$
    *Request\Header + "Content-Type: multipart/form-data; boundary="+Boundary+EOL$
    ProcedureReturn *Request
    
  EndIf 
  
  ProcedureReturn #False
EndProcedure

Procedure Post_AddFileContent(*Request.PostRequest, ParameterName.s, FileName.s, *Memory, Length.i, Last.i=#False)
  If *Request
    
    Protected ContentHeader.s = "--" + *Request\Boundary + EOL$
    
    ContentHeader + "Content-Disposition: form-Data; name="+Chr(34)+ParameterName+Chr(34)+"; filename="+Chr(34)+FileName+Chr(34) + EOL$ 
    ContentHeader + "Content-Type: application/octet-stream"+EOL$+EOL$
    
    Protected ContentEnd.s = ""
    
    ContentEnd = EOL$ + "--" + *Request\Boundary
    If Last
      ContentEnd + "--" 
    EndIf
    ContentEnd + EOL$
    
    AddElement(*Request\Content())
    
    *Request\Content()\Size = Len(ContentHeader) + Length + Len(ContentEnd)
    *Request\Content()\Memory = AllocateMemory(*Request\Content()\Size+1) ;0 Character which we do not need..
    
    If *Request\Content()\Memory
    
      PokeS(*Request\Content()\Memory,ContentHeader, Len(ContentHeader),#PB_Ascii)
      CopyMemory(*Memory, *Request\Content()\Memory + Len(ContentHeader), Length)
      PokeS(*Request\Content()\Memory + Len(ContentHeader) + Length, ContentEnd, Len(ContentEnd),#PB_Ascii) 
      
      ProcedureReturn #True
      
    EndIf
    
    DeleteElement(*Request\Content()) 
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure Post_SendRequest(*Request.PostRequest, ConnectionID)
  If *Request
  
    Protected ContentLength.i = 0
    
    ForEach *Request\Content()
      ContentLength + *Request\Content()\Size
    Next
    
    *Request\Header + "Content-Length: "+Str(ContentLength)+EOL$+EOL$
    
    SendNetworkString(ConnectionID, *Request\Header)
    
    ForEach *Request\Content()
      SendNetworkData(ConnectionID, *Request\Content()\Memory,*Request\Content()\Size)
    Next
    
    SendNetworkString(ConnectionID,EOL$)
    ProcedureReturn #True
  
  EndIf

EndProcedure


Procedure Post_Free(*Request.PostRequest)
  If *Request
    
    ForEach *Request\Content()
      FreeMemory(*Request\Content()\Memory)
      DeleteElement(*Request\Content())
    Next    
    
    ClearStructure(*Request, PostRequest) 
    FreeMemory(*Request)
  
  EndIf

EndProcedure


*buff = AllocateMemory(FileSize(uploadFile$))
If ReadFile(1, uploadFile$)
   Debug "File Loaded"
   ReadData(1,*buff, MemorySize(*buff))
   CloseFile(1)
EndIf


ConnectionID = OpenNetworkConnection(server$, Port)

If ConnectionID

  Test = Post_CreateRequeset(filename$,server$, Port, "-------------------------------"+Str(GUID))
  
  If Test
  
    If Post_AddFileContent(Test, "datei","test.png",*buff, MemorySize(*buff),#True)
      Post_SendRequest(Test, ConnectionID)
      Debug "File has been sent!"
    EndIf
    
    Post_Free(Test)
  EndIf 
  
 
   CloseNetworkConnection(ConnectionID)
Else
   MessageRequester("PureBasic - Client", "Can't find the server (Is it launched ?).", 0)
EndIf

End   


habe ein phpscript mit var_dump($_FILES); geschrieben und bekomme

Code: Alles auswählen

array(1) {
  ["datei"]=>
  array(5) {
    ["name"]=>
    string(8) "test.png"
    ["type"]=>
    string(24) "application/octet-stream"
    ["tmp_name"]=>
    string(14) "/tmp/phpwlplVW"
    ["error"]=>
    int(0)
    ["size"]=>
    int(260)
  }
Die Infos stimmen alle, also müsste es funktionieren.

mfg,
Dark
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Re: POST Upload klappt nicht?

Beitrag von Blackskyliner »

You are my Hero!

Und jetzt ab ins PureArea Codearchiv damit!
Damit das nicht verloren geht...

Was die Frage wirft, warum PB sowas nicht native via Http Libary kann?
Also POST und GET Daten senden, etc...
Währe ne schöne Vereinfachung und dafür sind doch die integrierten Libarys da...

Aber ich danke dir nochmals :)
Fast wie ein Geburtstagsgeschenk <)
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Dark
Beiträge: 93
Registriert: 24.08.2007 20:36
Kontaktdaten:

Re: POST Upload klappt nicht?

Beitrag von Dark »

Hallo,

ich wollte aber noch vor eine Sache warnen, die ich eben vergessen hatte zu schreiben. Es kann bei SendNetworkData auch passieren, das nicht alle Daten gesendet werden (Der Rückgabewert gibt an wie viel gesendet wurde). Dies passiert zum Beispiel, wenn der TCP Stack des Betriebsystems voll ist und die Daten einfach durch die langsame Internet verbindung nicht schnell gnug übermittelt werden konnten. Es muss also noch eine Schleife hinzugefügt werden, bei dem SendNetworkData() die Bytes übermittelt, die beim ersten Aufruf der Funktion nicht übermittelt wurden. Andernfalls könnt es Probleme bei größeren Dateien geben. (Theoretisch könnte es auch passieren, das bei SendNetworkString der Buffer voll ist, aber das ist eher unwahrscheinlich) Es sollte desweiteren am besten auch eine maximale Zeit eingebaut werden, in der Versucht wird die Daten erneut zu senden, sonst wird es lustig, wenn das gegenüber die Verbindung zu früh schließt und du in einer Endlosschleife hängst. (Ich habe im englischen Forum bei Tipps&Tricks auch einen Code gepostet, mit dem man ein Disconnect beim Client feststellt, könnte ggf. helfen :wink: )

mfg,
Dark
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

Re: POST Upload klappt nicht?

Beitrag von Sunny »

Also wenn ich den Code kompilieren will, Dann wird mir immer gesagt: "Eine Variable in einer 'Structure' benötigt einen deklarierten Typ" der Fehler ist in Zeile 38 (List Content.ContentData())
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: POST Upload klappt nicht?

Beitrag von STARGÅTE »

Laut deiner Signatur hast du PB 4.40, die ist zu alt für den Code, du benötigst 4.50 !
7. Juni 2010 : Version 4.50

- Hinzugefügt: Unterstützung für Array, List, Map innerhalb von Strukturen
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Dark
Beiträge: 93
Registriert: 24.08.2007 20:36
Kontaktdaten:

Re: POST Upload klappt nicht?

Beitrag von Dark »

Sunny hat geschrieben:Also wenn ich den Code kompilieren will, Dann wird mir immer gesagt: "Eine Variable in einer 'Structure' benötigt einen deklarierten Typ" der Fehler ist in Zeile 38 (List Content.ContentData())
Hallo,
der Code benötigt die PureBasic Version 4.50, für ältere Versionen könnte man eine globale Liste oder eine selfmade Linkedlist verwenden. Der Nachteil einer globalen Liste wäre, das man nicht mit mehren POST Requests gleichzeitig arbeiten kann. Ich möchte aber nochmal daran erinnern, das dieser Code Schwächen enthält, welche noch behoben werden sollten, bevor der Code produktiv verwendet wird. Ich habe diesen Code geschrieben um zu zeigen, wie ich das ganze aus meiner Sicht aufbauen würde, habe dabei aber wie bereits erwähnt einige Überprüfungen etc. weg gelassen.

mfg,
Dark
Antworten