PHP-Upload-Script mit PB nutzen...

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
Frogger
Beiträge: 425
Registriert: 14.03.2006 19:27
Kontaktdaten:

PHP-Upload-Script mit PB nutzen...

Beitrag von Frogger »

Hallo, ich habe einen PHP-Script, mit dem man eine Datei auf den FTP-Server
hochladen kann.
Es funktioniert mit dem Formfeld ganz gut.
Aber ich will das aus PB heraus machen.
Das heist ich übergebe den Pfad zu einer Datei auf der Festplatte dem Upload-Script und diese soll dan hochgeladen werden.

PHP-Script:

Code: Alles auswählen

<?PHP
if(isset($_POST['send']) && $_POST['send'] == "ja")
{
  $uploaddir = 'upload/';
  if(move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name']))
  {
    echo "Datei erfolgreich hochgeladen.\n";
  }
  else
  {
    echo "Fehler beim Hochladen der Datei. Fehlermeldung:\n<br />";
    print_r($_FILES);
  }
}
?>

<form enctype="multipart/form-data" action="<?PHP echo $PHP_SELF; ?>" method="post">
<input type="file" name="userfile" />
<input type="hidden" name="send" value="ja" />
<input type="submit" value="Datei hochladen" />
</form>
Ansatz mit PB aus diesem Thread: http://www.purebasic.fr/german/viewtopi ... php+upload

Code: Alles auswählen

InitNetwork()

ConnectionID = OpenNetworkConnection("www.domain.de", 80)

Content.s = "datei: 12345"
buf$=buf$+"POST /upload.php HTTP/1.0"+Chr(13)+Chr(10)
buf$=buf$+"Host: www.domain.de"+Chr(13)+Chr(10)
buf$=buf$+"Content-type: multipart/form-data"+Chr(13)+Chr(10)
buf$=buf$+"Content-length: "+Str(Len(Content))+Chr(13)+Chr(10)
buf$=buf$+Content+Chr(13)+Chr(10)
buf$=buf$+Chr(13)+Chr(10)

SendNetworkData(ConnectionID, buf$, Len(buf$))

CloseNetworkConnection(ConnectionID)
Was musst ich an dem PHP-Code ändern und was am PB-Code, damit es funktioniert?
(mal abgesehen von dem Domainnamen und dem Scriptnamen)

Ein Rückgabewert vom PHP-Code muss nicht unbedingt sein, wäre aber von Vorteil.
[PB4.20]
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Ich hab es nicht geschafft via POST mit meinen Scripten zu kommunizieren. Nur Get bisher. Viel Glück.
Mal abgesehen davon: Warum gehst du nicht gleiche über FTP? Wozu der Umweg? Willst du dein ftp-Password nicht ins Programm implementieren?
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Code: Alles auswählen

; HTTP Commands - DarkDragon
; ***************************
; Commands:
; ---------
; HTTPRequest(URL.s, *EndSize.LONG, PacketSize, *Callback) - Result: Pointer to a buffer containing the webdata
; URL.s       - [in]  Nullterminated string with the link to the file
; *EndSize    - [out] Pointer to a long variable which receives the size of the resulting buffer
; PacketSize  - [in]  Long variable containing the size of the packets(steps) to download
; *Callback   - [in]  Pointer to a callback method receiving the following parameters: CurrentDownloadedSize.l, MaximumLength.l

; HTTPRequest_Password(URL.s, *EndSize.LONG, PacketSize, Username.s, Password.s, *Callback) - Result: Pointer to a buffer containing the webdata
; URL.s       - [in]  Nullterminated string with the link to the file
; *EndSize    - [out] Pointer to a long variable which receives the size of the resulting buffer
; PacketSize  - [in]  Long variable containing the size of the packets(steps) to download
; Username.s  - [in]  Nullterminated string containing the username
; Password.s  - [in]  Nullterminated string containing the password(NOT encoded)
; *Callback   - [in]  Pointer to a callback method receiving the following parameters: CurrentDownloadedSize.l, MaximumLength.l

InitNetwork()

#TIMEOUT = 1500

Procedure.s ReceiveLine(ConnectionID)
  Text.s = ""
  While char.b <> #LF
    char = 0
    ReceiveNetworkData(ConnectionID, @char, 1)
    If char <> 0
      Text.s + Chr(char)
    EndIf
  Wend
  
  ProcedureReturn RemoveString(RemoveString(Text, #CR$), #LF$)
EndProcedure

Procedure HTTPRequest(URL.s, *EndSize.LONG, PacketSize, *Callback)
  Protected Size.l, Data_.s, s.l, Method.s, File.s, Content.s, Text.s, Length.l, Line.s
  Protected CurSize.l, oSize.l, t.l, ConnectionID.l
  
  If Left(URL, 7) = "http://" : URL = Right(URL, Len(URL)-7) : EndIf
  s = FindString(URL, "/", 1)
  Host.s = "" : File.s = ""
  If s <> 0 : Host.s = Left(URL, s-1) : File.s = Right(URL, Len(URL)-s) : Else : Host = URL : EndIf
  
  s = FindString(File, "?", 1)
  If s <> 0
    Method.s = "POST"
    Content.s = Right(File, Len(File)-s)
    File = Left(File, s-1)
  Else
    Method.s = "GET"
    Content.s = ""
  EndIf
  
  ConnectionID = OpenNetworkConnection(Host, 80)
  If ConnectionID
    Data_.s = Method+" /"+File+" HTTP/1.0"+#CRLF$
    Data_.s + "Host: "+Host+#CRLF$
    Data_.s + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7"+#CRLF$
    If Content <> ""
      Data_.s + "Connection: close"+#CRLF$
      Data_.s + "Content-Type: application/x-www-form-urlencoded"+#CRLF$
      Data_.s + "Content-Length: "+Str(Len(Content))+#CRLF$
      Data_.s + #CRLF$ + Content.s + #CRLF$+#CRLF$
    Else
      Data_.s + "Connection: close"+#CRLF$+#CRLF$
    EndIf
    
    SendNetworkString(ConnectionID, Data_)
    While NetworkClientEvent(ConnectionID) <> 2 : Delay(10) : Wend
    
    Length = 0
    Line.s = ""
    Repeat
      Line = ReceiveLine(ConnectionID)
      Select LCase(StringField(Line, 1, ":"))
        Case "content-length"
          
          Length = Val(Trim(StringField(Line, 2, ":")))
      EndSelect
    Until Len(Trim(Line)) <= 4
    
    Size = 0
    If Length <> 0
      
      *Result = AllocateMemory(Length)
      
      While Size < Length
        If CurSize > 0
          Size + CurSize
          If *Callback
            CallFunctionFast(*Callback, Size, Length)
          EndIf
        EndIf
        If Size > (Length-PacketSize)
          PacketSize = Length-Size
        EndIf
        If PacketSize > 0
        CurSize = ReceiveNetworkData(ConnectionID, *Result+Size, PacketSize)
        EndIf
      Wend
      
    Else
      
      *Buffer = AllocateMemory(PacketSize)
      *Result = AllocateMemory(1)
      t = ElapsedMilliseconds()
      While ElapsedMilliseconds()-t <= #TIMEOUT
        If NetworkClientEvent(ConnectionID) = 2
          CurSize = ReceiveNetworkData(ConnectionID, *Buffer, PacketSize)
          If CurSize > 0
            oSize = Size
            Size + CurSize
            *Result = ReAllocateMemory(*Result, Size)
            CopyMemory(*Buffer, *Result+oSize, CurSize)
            If *Callback
              CallFunctionFast(*Callback, Size, 0)
            EndIf
          EndIf
          t = ElapsedMilliseconds()
        EndIf
      Wend
      Length = Size
      
    EndIf
    
    *EndSize\l = Length
    If *Callback
      CallFunctionFast(*Callback, Size, Length)
    EndIf
    
    CloseNetworkConnection(ConnectionID)
    
    ProcedureReturn *Result
  EndIf
EndProcedure

Procedure HTTPRequest_Password(URL.s, *EndSize.LONG, PacketSize, Username.s, Password.s, *Callback)
  Protected Size.l, Data_.s, s.l, Method.s, File.s, Content.s, Text.s, Length.l, Line.s
  Protected CurSize.l, oSize.l, t.l, ConnectionID.l
  
  If Left(URL, 7) = "http://" : URL = Right(URL, Len(URL)-7) : EndIf
  s = FindString(URL, "/", 1)
  Host.s = "" : File.s = ""
  If s <> 0 : Host.s = Left(URL, s-1) : File.s = Right(URL, Len(URL)-s) : Else : Host = URL : EndIf
  
  s = FindString(File, "?", 1)
  If s <> 0
    Method.s = "POST"
    Content.s = Right(File, Len(File)-s)
    File = Left(File, s-1)
  Else
    Method.s = "GET"
    Content.s = ""
  EndIf
  
  InputBuffer.s = Username+":"+Password
  OutputBuffer.s = Space(256)
  Base64Encoder(@InputBuffer, Len(InputBuffer), @OutputBuffer, 255)
  
  ConnectionID = OpenNetworkConnection(Host, 80)
  If ConnectionID
    Data_.s = Method+" /"+File+" HTTP/1.0" + #CRLF$
    Data_.s + "Host: "+Host + #CRLF$
    Data_.s + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7" + #CRLF$
    Data_.s + "Authorization: Basic "+ OutputBuffer + #CRLF$
    If Content <> ""
      Data_.s + "Connection: close" + #CRLF$
      Data_.s + "Content-Type: application/x-www-form-urlencoded"+#CRLF$
      Data_.s + "Content-Length: "+Str(Len(Content))+#CRLF$
      Data_.s + #CRLF$ + Content.s + #CRLF$+#CRLF$
    Else
      Data_.s + "Connection: close" + #CRLF$ + #CRLF$
    EndIf
    
    SendNetworkString(ConnectionID, Data_)
    While NetworkClientEvent(ConnectionID) <> 2 : Delay(10) : Wend
    
    Length = 0
    Line.s = ""
    Repeat
      Line = ReceiveLine(ConnectionID)
      Select LCase(StringField(Line, 1, ":"))
        Case "content-length"
          
          Length = Val(Trim(StringField(Line, 2, ":")))
      EndSelect
    Until Len(Trim(Line)) <= 4
    
    Size = 0
    If Length <> 0
      
      *Result = AllocateMemory(Length)
      
      While Size < Length
        If CurSize > 0
          Size + CurSize
          If *Callback
            CallFunctionFast(*Callback, Size, Length)
          EndIf
        EndIf
        If Size > (Length-PacketSize)
          PacketSize = Length-Size
        EndIf
        If PacketSize > 0
        CurSize = ReceiveNetworkData(ConnectionID, *Result+Size, PacketSize)
        EndIf
      Wend
      
    Else
      
      *Buffer = AllocateMemory(PacketSize)
      *Result = AllocateMemory(1)
      t = ElapsedMilliseconds()
      While ElapsedMilliseconds()-t <= #TIMEOUT
        If NetworkClientEvent(ConnectionID) = 2
          CurSize = ReceiveNetworkData(ConnectionID, *Buffer, PacketSize)
          If CurSize > 0
            oSize = Size
            Size + CurSize
            *Result = ReAllocateMemory(*Result, Size)
            CopyMemory(*Buffer, *Result+oSize, CurSize)
            If *Callback
              CallFunctionFast(*Callback, Size, 0)
            EndIf
          EndIf
          t = ElapsedMilliseconds()
        EndIf
      Wend
      Length = Size
      
    EndIf
    
    *EndSize\l = Length
    If *Callback
      CallFunctionFast(*Callback, Size, Length)
    EndIf
    
    CloseNetworkConnection(ConnectionID)
    
    ProcedureReturn *Result
  EndIf
EndProcedure

; Example:

*Buffer = HTTPRequest("http://www.bradan.eu/", @Size, 16, 0)
If *Buffer
  Debug Size
  Debug PeekS(*Buffer, Size)
  FreeMemory(*Buffer)
Else
  Debug "Website not available!"
EndIf
Damit geht ein POST Request.

Aber wenn das deine Methode zum verstecken des FTP Accounts ist muss ich dich enttäuschen: Einmal mit dem Netzwerksniffer hingegangen wird jeder FTP Uploads tätigen können. Am besten ist es wenn du die Daten direkt per PHP Skript kapselst.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
Frogger
Beiträge: 425
Registriert: 14.03.2006 19:27
Kontaktdaten:

Beitrag von Frogger »

Danke für den Code. Ich werde ihn mir mal genauer anschauen.

Und nein es soll kein Versuch sein die FTP-Zugansdaten zu "schützen".

Das Tool an dem ich gerade arbeite soll in regelmäßigen Abständen Bilder von einer Webcam hochladen.

Das Problem bei mir mit FTP ist, das die Verbindung zum Server nach einer Weile getrennt wird und eine automatische Neuanmeldung immer fehlschlägt.
Dann hilft nur noch die Anwendung neustarten und connecten.
Das senden von NOOP, PWD, TYPE A und TYPE I bringt auch nichts. Irgendwann wird die Verbindung trotzdem beendet.

Und ich habe immer noch nicht herausgefunden wie ich den PHP-Code umschreiben muss damit man die Dateien auch aus dem Browser heraus senden kann.
Ich dachte mir das in der form:

http://www.domain.de/upload.php?file=C:/xxx.jpg
Anschließend soll die Datei hochgeladen werden.

So oder so ähnlich soll es irgendwann mal funktionieren /:->
[PB4.20]
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Mir wurde mal gesagt, dass man mit php nur Sachen hochladen kann, die mit dem html-File-"gadget" übergeben worden sind. Damit soll anscheinden verhindert werden, dass Dateien ohne das wissen der User hochgeladen werden, wenn er eine Webseite besucht.

Wo ist das Problem mit der Verbindung? Wenn du alle 30sekunden z.B ein Bild hochladen willst, isses doch egal, wenn der Client jedes mal neu connected.

@DD: Jap. Danke für den Code. :allright:
Benutzeravatar
Frogger
Beiträge: 425
Registriert: 14.03.2006 19:27
Kontaktdaten:

Beitrag von Frogger »

TomS hat geschrieben:Wo ist das Problem mit der Verbindung? Wenn du alle 30sekunden z.B ein Bild hochladen willst, isses doch egal, wenn der Client jedes mal neu connected.
Naja genau das funktioniert nicht auf Dauer.
Nach einer Zeit wird die Verbindung getrennt.


Und es muss nicht zwingend sein, das man die Datei auch per Browser hochladen kann. (würde mich aber interessieren ob das geht)
Die Hauptsache wäre, das man sie aus dem Programm heraus Senden kann.

Das es geht besteht kein Zweifel. Es gibt einige Uploadtools, die auf die gleiche Weise funktionieren.
[PB4.20]
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Ich meinte: Verbinden, hochladen, trennen delay(30000) verbinden, hochladen, trennen.

Was sind denn das für tools? Woher weißt du, dass sie mit php arbeiten?
Benutzeravatar
Frogger
Beiträge: 425
Registriert: 14.03.2006 19:27
Kontaktdaten:

Beitrag von Frogger »

Ich meinte: Verbinden, hochladen, trennen delay(30000) verbinden, hochladen, trennen.
Das funktioniert auch so nicht.
Ein paar mal verbinden und trennen (10-20 mal) und die nächste Verbindung scheitert.

z.B. diese Tools :)
http://www.imageuploader.de/
http://zer0s.codepark.de.vu/
[PB4.20]
Benutzeravatar
Frogger
Beiträge: 425
Registriert: 14.03.2006 19:27
Kontaktdaten:

Beitrag von Frogger »

Hab es immer noch nicht hinbekommen :(

ich weis einfach nicht welche daten und in welcher reihenfolge ich dem php-script schicken muss
[PB4.20]
Benutzeravatar
Delle
Beiträge: 1130
Registriert: 10.05.2005 22:48

Beitrag von Delle »

Du mußt VOR dem Versenden rückwärts die genaue Contentlänge berechnen... das Bild war im Test 20.524 Bytes groß, im Header steht aber dann 20.973 Bytes:

Head:

POST /upload.php HTTP/1.0
Content-Type: multipart/form-data; boundary=---------------------------fz62l38eY6GI9Yhw
Host: www.imageuploader.de
Content-Length: 20973

Daten:

-----------------------------fz62l38eY6GI9Yhw
Content-Disposition: form-data; name="datei"; filename="bild.jpg"
Content-Type: image/pjpeg

Rest:

-----------------------------fz62l38eY6GI9Yhw
(binäre Bilddaten)
-----------------------------fz62l38eY6GI9Yhw--

Entweder mal beim ImageUploader mitsniffen oder HTTP-Protokoll auseinander nehmen...
PB 6.21 | Win 11
Antworten