[Gelöst] "Download" via FHEMWEB?

Begonnen von Thorsten Pferdekaemper, 06 Juni 2018, 21:42:00

Vorheriges Thema - Nächstes Thema

Thorsten Pferdekaemper

Hi,
das Modul FUIP verwendet den $data{FWEXT} Mechanismus, um seine Seiten via FHEMWEB bereit zu stellen. Jetzt hätte ich gerne eine Möglichkeit, Daten auf das Frontend herunterzuladen. Normalerweise schreibt man dazu in den HTTP-Header "Content-Disposition: attachment". Allerdings gelingt mir das nicht, da FHEMWEB den Header kontrolliert und ich habe bisher keine Möglichkeit gefunden, etwas eigenes in den Header zu schreiben.
Hat dazu jemand eine Idee?
Gruß,
    Thorsten
FUIP

betateilchen

Zitat von: Thorsten Pferdekaemper am 06 Juni 2018, 21:42:00
da FHEMWEB den Header kontrolliert und ich habe bisher keine Möglichkeit gefunden, etwas eigenes in den Header zu schreiben.

und das ist auch gut so.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Thorsten Pferdekaemper

Hi,
das klingt so ein bisschen danach:
https://de.wikipedia.org/wiki/Der_Fuchs_und_die_Trauben
Hat jemand noch eine hilfreiche Idee?
Gruß,
   Thorsten
FUIP

rudolfkoenig

- Hack, ungetestet: FWEXT/CONTENTFUNC liefert ($FW_RETTYPE, $FW_RET)  zurueck. FW_RETTYPE auf "text/html; charset=UTF8\r\nContent-Disposition: attachment" setzen.

- Alternative: als FW_RETTYPE undef zurueckliefern, und die komplette Antwort samt HTTP-Header selbst versenden, mit FW_addToWritebuffer($hash, ...). FHEMWEB schliesst danach die Verbindung.

Thorsten Pferdekaemper

Hi,
dankeschön. Ich werde mal den Hack ausprobieren, um das ganze überhaupt zum Lafen zu bekommen und das dann ggf. später mit der zweiten Lösung "sauber" implementieren.
Gruß,
   Thorsten
FUIP

mumpitzstuff

Kann man in diesem Zusammenhang auch irgendwie sehen, um was für ein Request es sich handelt? Genauer interessiert mich, ob ich an dieser Stelle einen HEAD request vor mir habe oder ein normales GET.

Thorsten Pferdekaemper

Hi Rudi,
wie von Dir vorgeschlagen habe ich inzwischen die "saubere" Lösung eingebaut. D.h. ich baue die Header selbst zusammen und schicke das ganze dann mittels FW_addToWritebuffer ab. Das sieht jetzt in etwa so aus:

main::FW_addToWritebuffer($main::defs{$main::FW_cname},
           "HTTP/1.1 200 OK\r\n" .
           "Content-Length: $length\r\n" .
           $expires . $compressed . # $main::FW_headerlines .
           "Content-Type: $rettype\r\n\r\n" .
           $data, undef, 1);

Das funktioniert auch, außer wenn closeConn im FHEMWEB-Device gesetzt ist. Dann kommt nämlich am Client gar nichts an (ERR_EMPTY_RESPONSE).
(Siehe auch https://forum.fhem.de/index.php?topic=100122.)
Ich vermute mal, dass das daran liegt, dass in diesem Fall in FW_closeConn auch die TCP-Verbindung geschlossen wird. Sollte das nicht erst dann passieren, wenn auch der Schreibpuffer leer ist?
Ich habe mich da noch nicht ganz durchgewurschtelt, also kann es sein, dass ich das ganze nicht komplett erfasst habe (das ist jetzt ein Euphemismus...). Vielleicht kannst Du mir dazu ja einen Tipp geben. (Oder auch jemand anders.)
Danke&Gruß,
   Thorsten
FUIP

Thorsten Pferdekaemper

Hi,
in Ermangelung einer besseren Lösung habe ich das bei mir jetzt so gemacht:

my $client = $main::defs{$main::FW_cname};
$client->{inform}{devices => {}} unless $client->{inform};  # hack to keep connection open
main::FW_addToWritebuffer($client,
[...]
        $data, sub ($) {my $hash = shift; delete $hash->{inform}; main::FW_closeConn($hash);} , 1);
}

Das ist natürlich eher ein ziemlicher Hack, aber ich habe noch Hoffnung, dass jemand mir einen Tipp gibt, das besser zu machen oder eine Änderung in FHEMWEB einbaut.
Gruß,
   Thorsten
FUIP

rudolfkoenig

Ich habe gerade folgende Aenderung eingecheckt:Index: FHEM/01_FHEMWEB.pm
===================================================================
--- FHEM/01_FHEMWEB.pm    (revision 19231)
+++ FHEM/01_FHEMWEB.pm    (working copy)
@@ -737,7 +737,8 @@
FW_closeConn($)
{
   my ($hash) = @_;
-  if(!$hash->{inform} && !$hash->{BUF}) { # Forum #41125
+  # Forum #41125, 88470
+  if(!$hash->{inform} && !$hash->{BUF} && !defined($hash->{".WRITEBUFFER"})) {
     my $cc = AttrVal($hash->{SNAME}, "closeConn",
                      $FW_userAgent =~ m/(iPhone|iPad|iPod)/);
     if(!$FW_httpheader{Connection} || $cc) {
und es kurz mit bzw. ohne gesetzten closeConn getestet.
Natuerlich nicht dein Problem, dafuer habe ich keine Anleitung :)

P.S.: Sorry fuer die spaete Antwort, habe Zeit und Moeglichkeit gebraucht, um dein Fall naeher anzuschauen.

Thorsten Pferdekaemper

Hi,
vielen Dank, das müsste so funktionieren. Allerdings ist es mit dem heutigen Update anscheinend noch nicht mitgekommen. Dann warte ich mal, bis das für die Allgemeinheit zur Verfügung steht und nehme meine Änderungen zurück.
Gruß,
   Thorsten
FUIP

rudolfkoenig

Sorry, hab das Einchecken jetzt nachgeholt.

Thorsten Pferdekaemper

Hi,
vielen Dank. Ich habe gerade meinen "Hack" wieder ausgebaut und es funktioniert immer noch.
Gruß,
   Thorsten
FUIP