Entwickler-Ecke

Internet / Netzwerk - IdHttpServer, Datei runterladen -> Name?


Gausi - Mo 22.09.08 21:26
Titel: IdHttpServer, Datei runterladen -> Name?
Ich versuche gerade, meinen Player um einen kleinen Webserver zu erweitern. D.h. der Player liefert über einen IDhttpserver eine HTML-Seite, die ein Browser dann anzeigen kann. Ich möchte darüber auch eine Download-Funktion bereitstellen. Da die Dateien irgendwo auf dem Server-System liegen können, und eigentlich der lokale Speicherort der Datei keinen was angeht, mach ich das ungefähr so:

Auf der Downloadseite findet sich z.B. sowas:

Quelltext
1:
<a href="download_pl?id=44">Allison Crowe - Lisa's Song</a>                    

Klickt man dann auf den Link, wird also das Dokument "download_pl" mit dem Parameter "id=44" angefordert.

Im OnCommandGet-Event passiert dann das:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
if aRequestInfo.Document = '\download_pl' then
begin
    queriedID := StrToIntDef(aRequestInfo.Params.Values['ID'], 0);
    localFilename := GetFilenameByID(queriedID);
    AResponseInfo.ContentType := 'audio/mp3';
    AResponseInfo.ContentStream := TTntFileStream.Create(localFilename, fmOpenRead or fmShareDenyWrite)
end;

Das funktioniert auch, allerdings will der Browser das dann als "download_pl.mp3" abspeichern. Gibts eine Möglichkeit, diesen Namen zu ändern? Ich hab da bisher nichts zu gefunden...


jakobwenzel - Mo 22.09.08 21:58

Man muss ganz normal die HTTP-Header setzen, IIRC den Wert "Content-Disposition" auf "attachment; filename=bliblablubb.mp3".
Und damit man bei längeren Downloads noch nen Fortschrittsbalken hat und nicht "Dateigröße unbekannt" sollte "Content-Length" auf die Dateigröße in Bytes gesetzt werden.


Gausi - Mo 22.09.08 22:57

Ahja. Das war das richtige Stichwort. Hat zwar etwas gedauert, aber so klappt das dann bei Indy10 scheinbar auch mit Unicode-Namen:


Delphi-Quelltext
1:
AResponseInfo.CustomHeaders.Add('Content-Disposition: attachment; filename="' + UTF8Encode(WideExtractFileName(localFilename)) + '"'  );                    


Danke! :D


Gausi - Sa 18.04.09 22:51

Ich mach hier mal weiter, da sich mit Delphi 2009 da ein neues Problem auftut. :?

Jetzt ist ein String ja ein UnicodeString, und das ist auch bei den Indys so. D.h. das UTF-kodierte wird automatisch zurück nach UTF-16 kodiert, da CustomHeaders jetzt UnicodeStrings auflistet. Das aber versteht unter Umständen (d.h. so alles jenseits des ASCII-Zeichensatzes) der Browser nicht mehr, und je nach Browser (IE, Opera, ..) werden unterschiedliche Ausweichnamen genommen, was ich aber vermeiden möchte.

Das UTF8 weglassen habe ich natürlich als erstes probiert, ändert aber nichts.

Ich muss also entweder Indy dazu bringen einen UTF8-String zu senden, oder den Brwoser dazu bringen, die UTF16-Kodierung zu verstehen. Jemand ne Idee wie man eines davon anstellen kann?

Edit: Wireshark zeigt als Dateinamen im Header lauter "?" an (als Bytes $3f, ist also kein Anzeigeproblem der Wireshark-GUI, sondern im Header stehen wirklich '?'). Das bedeutet: zwischen Reinpacken in die Liste und Lossenden per http wird der UnicodeString zu Ansi. :?!?:

Edit2: Sieht so aus [http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http], als wären da auch nur ASCII-Zeichen erlaubt. Und dass das vorher ging, war dann wohl ein netter Zufall, weil die gängigen Browser die UTF8-Kodierung anhand von Heuristiken(?) erkennen und dann den "richtigen" Dateinamen vorschlagen.

Für Vorschläge zum Umgehen dieser Problematik bin ich aber weiter offen. ;-)


Gausi - So 19.04.09 12:16

Ich rede mal weiter mit mir selbst...

Problem bin ich jetzt anders angegangen. Als href gebe ich in dem Html-Dokument jetzt nicht das Pseudo-Download-Skript mit Datei-ID als Parameter an, sondern den Dateinamen. Damit mein kleiner Http-Server weiß, dass die Anforderung keine "normale" Datei ist, sondern eine Audio-Datei aus der Medienbib/Playlist, die irgendwo im Dateisystem des Users schlummert, hänge ich die Parameter Action=download&id=<ID der Datei> an den Link an, die dann benutzt werden, um den richtigen Download anzustoßen. Ein Beispiel-Link sieht dann so aus:

Quelltext
1:
2:
3:
<a href="01-อัสนี-วสันต์
 - เด็กเลี้ยงแ
กะ.mp3?id=42&Action=download_pl">

Den CustomHeader-Filename lasse ich dann weg - die Browser nehmen dann als Dateinamen den verlinkten Namen. Damit machen jetzt Opera, Firefox, und der Browser auf meinem Nokia 5800 das, was ich will. Der IE spackt wieder was rum, aber das ist ja normal. :lol: