Autor Thema: Verständnisfrage zu HttpUtils_NonblockingGet  (Gelesen 1746 mal)

Offline xasher

  • Developer
  • Full Member
  • ****
  • Beiträge: 127
Verständnisfrage zu HttpUtils_NonblockingGet
« am: 06 Mai 2022, 16:37:42 »
Hallo zusammen,

ich komme gerade an meinem Modul nicht weiter. Ich brauche für eine Abfrage ein erzeugtes Antiforgerycookie
Ich komme mit der Reihenfolge der Verarbeitung aber nicht klar. Was ich bisher habe - hier zum Debuggen:

...
}elsif( $cmd eq "TEST" ) {
   
print "1\n";

    my $saunaid  = AttrVal($name, "saunaid", "");
    my $aspxauth = $hash->{KLAFS}->{cookie};

   
         my $header = "Cookie: $aspxauth";
         my $datauser = "s=$saunaid";
         HttpUtils_NonblockingGet({
             url        => ENTERPIN,
             timeout    => 5,
             hash        => $hash,
             method      => "GET",
             header      => $header, 
             data => $datauser,
             callback    => \&Klafs_GETantiforgery1,
         }); 
         
         # RequestVerificationToken  aus dem Header auslesen fuer das Cookie
         sub Klafs_GETantiforgery1($) {
           my ($param, $err, $data) = @_;
           my $hash = $param->{hash};
           my $name = $hash->{NAME};
           my $header = $param->{httpheader};
           Log3 $name, 5, "header: $header";
           Log3 $name, 5, "Data: $data";
           Log3 $name, 5, "Error: $err";
print "AntiForgery GET\n";
           foreach my $cookie ($header =~ m/set-cookie: ?(.*)/gi) {
               $cookie =~ /([^,; ]+)=([^,;\s\v]+)[;,\s\v]*([^\v]*)/;
               my $antiforgery  = $1 . "=" .$2 .";";
               Log3 $name, 4, "AntiforgeryGet: $antiforgery";
               Log3 $name, 5, "$name: Antiforgery found: $antiforgery";
               $hash->{KLAFS}->{antiforgery}    = $antiforgery;
           }
         }
   

   
    print "2\n";
}

Als Ausgabe im Log kommt die Reihenfolge:

1
2
AntiForgery GET
2022.05.06 16:28:07 4: AntiforgeryGet: __RequestVerificationToken=uXch_rxxxxxxxxxxxxxxxx......

An Position 2 muss ich das neue Cookie ($hash->{KLAFS}->{antiforgery) verwenden. Es ist dort aber noch nicht vorhanden. Kommt laut Log erst später.

Was muss ich denn hier beachten?

Grüße
Alex

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 25853
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #1 am: 06 Mai 2022, 17:21:12 »
Klassisches Callback-Muster:
Code ab Position 2 in die interne Funktion (Klafs_GETantiforgery1) verlagern.

Alternative, falls man hintereinander mehrere nonblocking Aufrufe hat:
- jeden Aufruf in einem separaten if, der prueft, ob dieser Aufruf an der Reihe ist
- direkt nach dem nonblocking Aufruf ein return (noch im if)
- Im Callback eine Variable setzen, damit der gleiche Aufruf nicht wieder erfolgt, und die urspruengliche Funktion wieder aufrufen
=> Statt eine tiefe Schachtelung der Funktionen hat man damit nur eine Funktion mit mehreren If-Bloecken.

Generell muss man sich davon verabschieden, dass die urspruengliche Funktion das Ergebnis zurueckliefert.
Im FHEMWEB Kontext ist deswegen asyncOutput interessant.

Offline xasher

  • Developer
  • Full Member
  • ****
  • Beiträge: 127
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #2 am: 06 Mai 2022, 17:35:53 »
Hallo Rudolf,

ja das mit dem Async erklärt es. Ich habe 3 Anrfagen, die genau getaktet werden müssen.
Deine Alternative finde ich daher besser. Leider hab ichs noch nicht ganz verstanden.
Wie kann ich das zeitlich prüfen, wann welche Abfrage an der Reihe ist, wenn sie untereinander stehen klappt ja nicht.

Hast du mir da im Ansatz ein Beispiel? Hoffentlich verlang ich da nicht zu viel.

Auf jeden Fall schon mal Danke!

Grüße
Alex

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 19409
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #3 am: 06 Mai 2022, 17:38:02 »
Wenn ich das richtig erinnere, macht der TvHeadend-code so was. Habe aber grade keinen link parat.
Server: HP-T620@Debian 11, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 25853
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #4 am: 06 Mai 2022, 21:12:30 »
Zitat
Hast du mir da im Ansatz ein Beispiel?

Variante 1, Aufruf aus telnet oder Browser mit { nb_1($cl) }
sub
nb_1($)
{
  my ($cl) = @_;

  HttpUtils_NonblockingGet({
    url=>"http://fhem.de/MAINTAINER.txt",
    callback=>sub($$$){
      Log 1,"MAINTAINER.txt LEN:".length($_[2]);
      my $len = length($_[2]);

      HttpUtils_NonblockingGet({
        url=>"http://fhem.de/CHANGED",
        callback=>sub($$$){
          Log 1,"CHANGED LEN:".length($_[2]);
          $len += length($_[2]);
          asyncOutput($cl, "TOTAL LEN IS: $len");
        }
      });
    }
  });
}

Variante 2, Aufruf mit { nb_2({cl=>$cl}) }
sub
nb_2($;$$)
{
  my ($hash,$err,$data) = @_;

  if(!$hash->{gotMaintainer}) {
    $hash->{gotMaintainer} = 1;
    $hash->{callback} = \&nb_2;
    $hash->{url} = "http://fhem.de/MAINTAINER.txt";
    HttpUtils_NonblockingGet($hash);
    return;
  }

  if(!$hash->{gotChanged}) {
    $hash->{gotChanged} = 1;
    Log 1,"MAINTAINER.txt LEN:".length($data);
    $hash->{len} = length($data);
    $hash->{url} = "http://fhem.de/CHANGED";
    HttpUtils_NonblockingGet($hash);
    return;
  }

  Log 1,"CHANGED LEN:".length($data);
  $hash->{len} += length($data);
  asyncOutput($hash->{cl}, "TOTAL LEN IS: ".$hash->{len});
}

Offline xasher

  • Developer
  • Full Member
  • ****
  • Beiträge: 127
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #5 am: 09 Mai 2022, 10:18:26 »
Hallo zusammen,

vielen Dank, ich bin begeistert. Ich habe deine Variante 1 gewählt Rudolf.
@BetaUser. Danke für den Hinweis. Ich glaube das Modul gibt es nicht mehr.

Viele Grüße,
Alex

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 25853
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #6 am: 09 Mai 2022, 10:24:15 »
Zitat
Ich habe deine Variante 1 gewählt Rudolf.
Ich habe auch so angefangen :)
Gefällt mir Gefällt mir x 1 Liste anzeigen

Offline justme1968

  • Developer
  • Hero Member
  • ****
  • Beiträge: 21328
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #7 am: 09 Mai 2022, 10:32:31 »
nur der vollständigkeit halber noch ein dritter vorschlag da ich meine das die beiden ansätze von oben bei längeren ketten von anfragen an ihre grenzen kommen bzw. der code recht unübersichtlich wird:

- im $hash des HttpUtils_NonblockingGet aufrufs kann man auch zusätzliche wertepaare mitgeben. z.b. key => xxx die für jeden aufruf unterschiedlich sein können.

- in der callback routine kann man so ganz einfach die antworten den anfragen zuordnen und in der behandlung der jeweiligen antwort die nächste nötige anfrage absetzen.

- das lässt sich auch weiter ausbauen z.b. durch eine queue in die die anfragen eingereiht werden und jeweils bei einer antwort die nächste abgeschickt wird

- es gibt fehler bei denen es sinnvoll sein kann eine anfrage zu wiederholen. das lässt sich mit den oberen drei punkten recht einfach machen in dem man am anfang des callbacks die fehlerhafte anfrage einfach erneut sendet und mit zählt wie oft das passiert ist so das man dann bei n >2 oder >3 abbrechen kann.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, …

https://github.com/sponsors/justme-1968
Gefällt mir Gefällt mir x 1 Liste anzeigen

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 19409
Antw:Verständnisfrage zu HttpUtils_NonblockingGet
« Antwort #8 am: 09 Mai 2022, 10:49:37 »
nur der vollständigkeit halber noch ein dritter vorschlag da ich meine das die beiden ansätze von oben bei längeren ketten von anfragen an ihre grenzen kommen bzw. der code recht unübersichtlich wird:

- im $hash des HttpUtils_NonblockingGet aufrufs kann man auch zusätzliche wertepaare mitgeben. z.b. key => xxx die für jeden aufruf unterschiedlich sein können.

- in der callback routine kann man so ganz einfach die antworten den anfragen zuordnen und in der behandlung der jeweiligen antwort die nächste nötige anfrage absetzen.

- das lässt sich auch weiter ausbauen z.b. durch eine queue in die die anfragen eingereiht werden und jeweils bei einer antwort die nächste abgeschickt wird

- es gibt fehler bei denen es sinnvoll sein kann eine anfrage zu wiederholen. das lässt sich mit den oberen drei punkten recht einfach machen in dem man am anfang des callbacks die fehlerhafte anfrage einfach erneut sendet und mit zählt wie oft das passiert ist so das man dann bei n >2 oder >3 abbrechen kann.
Klingt interessant, muss ich mir ggf. für TvHeadend auch mal anschauen, da wird das über einen Zähler im Devicehash gemacht...

@BetaUser. Danke für den Hinweis. Ich glaube das Modul gibt es nicht mehr.
Das war noch nie offiziell, hatte das mal als "Fingerübung" aktualisiert/modernisiert, weil im Ursprungscode manches "gefährlich" war. (package)-Code ist z.B. hier zu finden: https://forum.fhem.de/index.php/topic,123117.msg1176443.html#msg1176443
Server: HP-T620@Debian 11, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files