AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TIdHttpServer JPG-Upload von HTML

Ein Thema von Hobbycoder · begonnen am 15. Jul 2019 · letzter Beitrag vom 17. Jul 2019
Antwort Antwort
Seite 1 von 2  1 2      
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#1

TIdHttpServer JPG-Upload von HTML

  Alt 15. Jul 2019, 13:14
Hi,

ich möchte gerne in meinem TIdHTTPServer über ein HTML-Formular Bilder/Dateien hochladen, die dieser dann speichert.
Um die Dateien aus dem Stream zu extrahieren habe ich mir (zugegeben im Inet geklaut, woher weiß ich nicht mehr) folgende Methode:
Delphi-Quellcode:
procedure TfrmWSMain.ExtractFiles(var ARequestInfo: TIdHTTPRequestInfo;
  Files: TStringList);
var
  ms : TMemoryStream;
  newdecoder, Decoder: TIdMessageDecoder;
  boundary, startboundary : String;
  msgEnd : Boolean;
  tmp : String;
  I : Integer;
  fname : String;
  tsValues : TStringList;
begin
  if Pos('krank', LowerCase(ARequestInfo.Document)) > 0 then
  begin
    if ARequestInfo.PostStream<>nil then
    begin
      ARequestInfo.PostStream.Position:=0;
      msgEnd:=False;
      boundary:=ExtractHeaderSubItem(ARequestInfo.ContentType, 'boundary', QuoteHTTP);
      startboundary := '--' + boundary;
      repeat
        tmp:=ReadLnFromStream(ARequestInfo.PostStream, -1, True);
      until tmp=startboundary;
      Decoder:=TIdMessageDecoderMIME.Create(nil);
      TIdMessageDecoderMIME(Decoder).MIMEBoundary:=boundary;
      tsValues:=TStringList.Create;
      try
        repeat
          Decoder.SourceStream:=ARequestInfo.PostStream;
          Decoder.FreeSourceStream:=False;
          Decoder.ReadHeader;
          Inc(i);
          case Decoder.PartType of
            mcptText, mcptAttachment:
              begin
                ms:=TMemoryStream.Create;
                ms.Position:=0;
                newdecoder:=Decoder.ReadBody(ms, msgEnd);
                tmp:=Decoder.Headers.Text;
                fname:=Decoder.Filename;
                if Decoder<>nil then
                  TIdMessageDecoderMIME(Decoder).MIMEBoundary:=boundary;
                Sleep(100);
                if fname<>'then
                begin
                  ms.SaveToFile(fname);
                  //msgEnd:=True;
                end else begin
                  ms.SaveToFile(IntToStr(i)+'.txt');
                end;
                ms.Free;
              end;
            mcptIgnore:
              begin
                try
                  FreeAndNil(Decoder);
                  Decoder:=TIdMessageDecoderMIME.Create(nil);
                  TIdMessageDecoderMIME(Decoder).MIMEBoundary:=boundary;
                finally
                  ms.Free;
                end;
              end;
            mcptEOF:
              begin
                FreeAndNil(Decoder);
                msgEnd:=True;
              end;
          end;
        until (Decoder = nil) or (msgEnd);
      finally
        if Decoder<>nil then
          Decoder.Free;
      end;
    end;
  end;
end;
die grundsätzlich erst mal funktioniert.

HTML sieht so aus:
Code:
            <tr><form data-ajax="false" id="krank" method="post" action="krank.php" enctype="multipart/form-data">
                      <td><label>Krank von</label></td>
                 <td><input type="text" name="krankvon" id="krankvon" style="width:100%;" focus></td>            
            </tr><tr>
                      <td><label>Krank bis</label></td>
                 <td><input type="text" name="krankbis" id="krankbis" style="width:100%;" focus></td>            
            </tr><tr>
                      <td><label>Bild 1</label></td>
                  <td><input type="file" name="datei1" id="datei1" accept="text/*"></td>
            </tr><tr>
                      <td><label>Bild 2</label></td>
                  <td><input type="file" name="datei1" id="datei2" accept="text/*"></td>
            </tr><tr>
                      <td><label>Bild 3</label></td>
                  <td><input type="file" name="datei1" id="datei3" accept="text/*"></td>
            </tr><tr>
            <td colspan="2">
                 <input type="submit" value="Absenden" style="width:100%;">
            </td>
            </tr></form>
ich bekomme für jedes Input die Daten in eine Datei.

2 Probleme habe ich noch, welches ich selbst nicht lösen kann:

1. Dateiname der Dateien wird nicht erkannt und
2. die hochgeladenen JPG's sind fehlerhaft.

Die Dateigröße ist geringfügig größer. Soweit ich das mit einem Hexeditor erkannt habe, wird wohl aus einem LF ein CRLF. Damit verändert sich der Inhalt und das Bild wird nicht mehr korrekt dargestellt.

Wer kann mir bei der Lösung helfen?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: TIdHttpServer JPG-Upload von HTML

  Alt 15. Jul 2019, 13:44
Wieso wählst du im HTML Teil das Schema text/*: accept="text/*, wenn du Bilder hochladen willst?

https://wiki.selfhtml.org/wiki/HTML/...t/Datei-Upload

https://wiki.selfhtml.org/wiki/MIME-Type
Michael Gasser
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#3

AW: TIdHttpServer JPG-Upload von HTML

  Alt 15. Jul 2019, 13:55
Wieso wählst du im HTML Teil das Schema text/*: accept="text/*, wenn du Bilder hochladen willst?

https://wiki.selfhtml.org/wiki/HTML/...t/Datei-Upload

https://wiki.selfhtml.org/wiki/MIME-Type
Da hast du Recht. Aber das Problem besteht weiterhin.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#4

AW: TIdHttpServer JPG-Upload von HTML

  Alt 15. Jul 2019, 14:43
Unter https://mikejustin.wordpress.com/201...-with-indy-10/ habe ich u.a. einen Link zu einem Stackoverflow Artikel der ebenfalls einen CR/LF Bug beschreibt gepostet.

Kann es sein, dass die Indy-Version veraltet ist?
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#5

AW: TIdHttpServer JPG-Upload von HTML

  Alt 15. Jul 2019, 16:44
Danke für den Link.
Das würde gerne mal ausprobieren. Ich verwendet die in 10.3 Rio mitgelieferte Indy-Version.
Wenn ich die im Link aufgeführten Änderungen an der IdMessageCoderMIME.pas ausprobieren will, muss ich diese ja neu compilieren. Ich muss zugeben, dass ich nicht weiß, wie ich das hinbekomme, das das keine von mir nachinstallierte Komponente ist. Anhand des Haltepunkts kann ich erkennen, dass er diese nicht automatisch neukompiliert, auch wenn ich mein Projekt bereinige. Wie geht das?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#6

AW: TIdHttpServer JPG-Upload von HTML

  Alt 15. Jul 2019, 18:07
Okay, ich bin ein Schritt weiter. Ich habe mir einfach erst einmal die IdMessageCoderMIME.pas ins Projekt kopiert, dann wird diese verwendet. Dort habe ich dann den Fix angewendet. Jetzt werden meine Bilder korrekt und in richtiger Größe geschrieben.
Nun habe ich aber ein neues Problem:

Nachdem alle Attachments gelesen wurden, erfolgt ein erneuter Durchlauf der Repeat-Schleife, da msgEnd nicht auf True gesetzt wurde, also der Case auf Decoder.PartType nicht mcptEOF liefert. So meine Vermutung. Er läuft dann in die Zeile newdecoder:=Decoder.ReadBody(ms, msgEnd); und kehrt nicht mehr zurück.
Müsste ReadBody nicht dann msgEnd auf True setzen? Bzw. Decoder.PartType nicht mcptEOF liefern?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#7

AW: TIdHttpServer JPG-Upload von HTML

  Alt 15. Jul 2019, 18:45
Okay, ich bin ein Schritt weiter. Ich habe mir einfach erst einmal die IdMessageCoderMIME.pas ins Projekt kopiert
Das sollte eigentlich nicht notwendig sein, denn laut Kommentar unter https://stackoverflow.com/a/27259795/80901 von Remy LeBeau ist der dort beschriebene Fix in Indy bereits enthalten.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#8

AW: TIdHttpServer JPG-Upload von HTML

  Alt 16. Jul 2019, 13:31
Okay, ich bin ein Schritt weiter. Ich habe mir einfach erst einmal die IdMessageCoderMIME.pas ins Projekt kopiert
Das sollte eigentlich nicht notwendig sein, denn laut Kommentar unter https://stackoverflow.com/a/27259795/80901 von Remy LeBeau ist der dort beschriebene Fix in Indy bereits enthalten.
Also in meiner Installation war der Code, welcher im Fix beschrieben ist, nicht drin.
Jetzt mit dem Fix werden die hochgeladenen Bilder auch korrekt aus dem Stream extrahiert.

Nur erkennt ReadBody das Ende nicht wirklich, und kehrt nach dem letzten Attachment nicht mehr zurück. Wenn jemand dazu noch einen Tipp hätte.....
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#9

AW: TIdHttpServer JPG-Upload von HTML

  Alt 16. Jul 2019, 13:59
Einen ersten Workaround habe ich gefunden. In der Unit IdMessageCoder Methode TIdMessageDecoder.ReadHeader Zeile 307
Alt:
Delphi-Quellcode:
  if LStrmPos >= LStrmSize then begin
    Result := '';
    Exit;
  end;
Geänder in:
Delphi-Quellcode:
  if LStrmPos >= LStrmSize then begin
    Result := '.'; //<-- in der IdMessageCoderMIME wird auf . getestet und VMsgEnd gesetzt
    Exit;
  end;
Auszug aus der IdMessageCoderMIME, Methode TIdMessageDecoderMIME.ReadBody (Ein paar Zeilen unter dem FIX):
Delphi-Quellcode:
        if LLine = '.then begin {Do not Localize}
          VMsgEnd := True;
          Break;
        end;
So scheint es bei mir zu funktionieren. Jetzt muss ich nur noch ergründen, warum der Filename nicht ausgewertet wird. Erste Vermutung: Implementierung fehlt wohl noch. (FFilename wird in IdMessageCoder/IdMessageCoderMIME nie beschrieben).
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#10

AW: TIdHttpServer JPG-Upload von HTML

  Alt 16. Jul 2019, 15:07
'ne Mail endet mit 'ner Zeile, die nur einen Punkt enthält.

Von daher erscheint mir Deine Änderung korrekt und sinnvoll.

Je nach Software folgt der Zeile mit dem Punkt auch noch 'ne Leerzeile weshalb die ursprüngliche Variante wohl (meist) funktioniert.

Man kann sich leider nicht sicher darauf verlassen, dass die letzte Zeile einen Punkt enthält.

Eventuell solltest Du in Deiner Variante prüfen, ob die letzte Zeile einen Punkt enthält oder eine Leerzeile ist.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz