Bernd Steffen: htm-Datei von externen Server lesen?

Hallo,

bin noch recht neu im Bereich php und so, aber vielleicht hilft mir da trotzdem eine(r) weiter?

Ich möchte von einem externen Server eine htm-Datei einlesen und auf bestimmte Bereiche hin überprüfen und ausgeben.

Leider scheitere ich bereits am Einlesen der Datei.
Ich habs bisher erstmal so probieren wollen:

$fp = fopen ("http://un:pw@10.10.22.63/upsstat.htm", "r");
fpassthru($fp);

Bei dem Server handelt es sich um eine USV mit Web-Interface, aber das sollte nicht so schlimm sein oder?

Naja, jedenfalls erhalte ich immer die folgende Fehlermeldung angezeigt:

Warning: fopen("http://...@10.10.22.63","r") - No such file or directory in c:\web\apc.php on line 14

Warning: Supplied argument is not a valid File-Handle resource in c:\web\apc.php on line 15
(wobei das wohl ein Folgefehler ist, stimmts?)

Kann mir da vielleicht jemand helfen, der sich a bissl besser auskennt?

  1. Hi,

    Leider scheitere ich bereits am Einlesen der Datei.

    das liegt daran, dass es sich nicht um eine Datei handelt, sondern um eine Ressource.

    $fp = fopen ("http://un:pw@10.10.22.63/upsstat.htm", "r");

    Das ist keine gültige URL. RFC 1738 (http://www.ietf.org/rfc/rfc1738.txt) sagt in Absatz 3.3 sehr deutlich:

    """
    3.3. HTTP
    [...]
    No user name or password is allowed. [...]
    """

    Wenn Du eine Ressource anfordern willst, die eine Authentifizierung erfordert, so baue mit Sockets eine HTTP-Verbindung mit den in RFC 2617 (URL analog zu RFC 1738) definierten Headern auf.

    Warning: Supplied argument is not a valid File-Handle resource in c:\web\apc.php on line 15
    (wobei das wohl ein Folgefehler ist, stimmts?)

    Korrekt.

    Cheatah

    --
    X-Will-Answer-Email: No
    1. Hallo Cheatah,

      erstmal danke für die Antowrt.

      Das ist keine gültige URL. RFC 1738 (http://www.ietf.org/rfc/rfc1738.txt) sagt in Absatz 3.3 sehr deutlich:

      """
      3.3. HTTP
      [...]
      No user name or password is allowed. [...]
      """

      hmm, davon stand in meiner php-Anleitung leider nichts. (unter function.fopen.html)
      :(

      Wenn Du eine Ressource anfordern willst, die eine Authentifizierung erfordert, so baue mit Sockets eine HTTP-Verbindung mit den in RFC 2617 (URL analog zu RFC 1738) definierten Headern auf.

      Puh, das klingt jetzt so richtig kompliziert.
      Die PHP-Anleitung liefert mir da leider keine brauchbaren Beispiele.

      Hast Du vielleicht ein Beispiel parat? Wäre echt toll!

      Und nochmals danke für die bisherige Hilfe ;)

      Liebe Grüße!

      1. Hi,

        3.3. HTTP
        No user name or password is allowed. [...]

        hmm, davon stand in meiner php-Anleitung leider nichts. (unter function.fopen.html)
        :(

        das hat ja auch mit PHP nichts zu tun. Zudem solltest Du von der Doku einer Sprache, welche HTTP-Requests in einer Funktion für _Datei_operationen unterbringt, in dieser Richtung nicht allzu viel erwarten.

        Wenn Du eine Ressource anfordern willst, die eine Authentifizierung erfordert, so baue mit Sockets eine HTTP-Verbindung mit den in RFC 2617 (URL analog zu RFC 1738) definierten Headern auf.
        Puh, das klingt jetzt so richtig kompliziert.

        Nein, das komplizierte ist höchstens der Request an sich.

        Die PHP-Anleitung liefert mir da leider keine brauchbaren Beispiele.

        S.o.

        Hast Du vielleicht ein Beispiel parat? Wäre echt toll!

        Da ein Beispiel einer fertigen Lösung entspricht: nein, selbstverständlich nicht. Andreas hat Dir aber eine "etwas einfachere" Alternative aufgetan.

        Cheatah

        --
        X-Will-Answer-Email: No
  2. Hallo!

    $fp = fopen ("http://un:pw@10.10.22.63/upsstat.htm", "r");
    fpassthru($fp);

    Das problem ist "un:pw@", das ist _kein_ HTTP! Browser setzen diese manchmal um in Basic-Authentification Header, aber direkt funktioniert das nicht.

    Außerdem kann man die Möglichkeit ein URL über fopen() zu verwenden abschalten, siehe dazu http://www.php3.de/manual/de/function.fopen.php

    Wenn Du die Basic-Authentification mit implementieren willst, kannst Du entweder CURL verwwenden, das müßte in PHP eigentlich mit http://www.php3.de/manual/de/ref.curl.php funktionieren(ist nicht überall installiert), oder den kompletten HEADER selbst zusammenbauen mit http://www.php3.de/manual/de/function.fsockopen.php(sollte immer gehen, dazu mußt Du aber wissen wie der Header genau auszusehen hat).

    Viele Grüße
    Andreas

    1. Hallo!

      $fp = fopen ("http://un:pw@10.10.22.63/upsstat.htm", "r");
      fpassthru($fp);

      Das problem ist "un:pw@", das ist _kein_ HTTP! Browser setzen diese manchmal um in Basic-Authentification Header, aber direkt funktioniert das nicht.

      Ja, das hat mir Cheatah auch schon gesagt *snief*.

      Wenn Du die Basic-Authentification mit implementieren willst, kannst Du entweder CURL verwwenden, das müßte in PHP eigentlich mit http://www.php3.de/manual/de/ref.curl.php funktionieren(ist nicht überall installiert), oder den kompletten HEADER selbst zusammenbauen mit http://www.php3.de/manual/de/function.fsockopen.php(sollte immer gehen, dazu mußt Du aber wissen wie der Header genau auszusehen hat).

      Hab ich das soweit verstanden, dass CURL ein Zusatzmodul ist, dass auf meinem Webserver aktiviert/installiert sein muss?

      Den Tipp mit dem fsockopen hat mir Cheatah auch genannt, aber das klingt alles wie böhmische Dörfer, da ich mit Headern uns sowas noch nichts zu tun hatte.

      Gibts da nicht irgendwo ein ganz einfaches Beispiel, wie ich eine Html-Datei mit Authentication lesen und Zeile für Zeile ausgeben kann?

      Danke für Deine Mühe,

      viele Grüße!

      1. Hi!

        Hab ich das soweit verstanden, dass CURL ein Zusatzmodul ist, dass auf meinem Webserver aktiviert/installiert sein muss?

        Du hast das selbst auf Windows installiert, korrekt? Dann lass es ;-) Das auf Windows ans laufen zu bekommen ist nicht ganz so einfach wie es sein sollte.

        Den Tipp mit dem fsockopen hat mir Cheatah auch genannt, aber das klingt alles wie böhmische Dörfer, da ich mit Headern uns sowas noch nichts zu tun hatte.

        Dann lies mal den Link, da _stehen_ Beispiele, und nicht nur oben, in den Kommentaren darunter steht noch _erheblich_ mehr, interessant sein dprfte für dich vor allem der Kommentar vom 26-Jun-2002: http://www.php3.de/manual/de/function.fsockopen.php
        Bedenke nur das Du so wie Du es bisher GET anstatt POST verwendet hast.

        Gibts da nicht irgendwo ein ganz einfaches Beispiel, wie ich eine Html-Datei mit Authentication lesen und Zeile für Zeile ausgeben kann?

        s.o.

        Grüße
        Andreas

        @Cheatah: Wie interpretierst Du 3.2.2.4 von ftp://ftp.isi.edu/in-notes/rfc2617.txt?

        1. Hi,

          @Cheatah: Wie interpretierst Du 3.2.2.4 von ftp://ftp.isi.edu/in-notes/rfc2617.txt?

          mit den Digest-Angaben ist es wie mit HTML-Attributen: Anführungszeichen sind nicht immer nötig, manchmal jedoch schon (hier: wenn Whitespaces im Wert vorkommen), und sie gehören in keinem Fall zum Wert des Attributs. Oder meintest Du etwas anderes?

          Cheatah

          --
          X-Will-Answer-Email: No
          1. Hi!

            @Cheatah: Wie interpretierst Du 3.2.2.4 von ftp://ftp.isi.edu/in-notes/rfc2617.txt?

            mit den Digest-Angaben ist es wie mit HTML-Attributen: Anführungszeichen sind nicht immer nötig, manchmal jedoch schon (hier: wenn Whitespaces im Wert vorkommen), und sie gehören in keinem Fall zum Wert des Attributs. Oder meintest Du etwas anderes?

            ;-) ICh meinte natürlich die Syntax von Mufasa:myhost@testrealm.com:Circle Of Life

            Grüße
            Andreas

            1. Hi,

              ;-) ICh meinte natürlich die Syntax von Mufasa:myhost@testrealm.com:Circle Of Life

              hm, das sehe ich eigentlich in 3.2.2.2 definiert. Oder übersehe ich da ein wesentliches Problem?

              Cheatah

              --
              X-Will-Answer-Email: No
              1. Hi!

                ;-) ICh meinte natürlich die Syntax von Mufasa:myhost@testrealm.com:Circle Of Life

                hm, das sehe ich eigentlich in 3.2.2.2 definiert. Oder übersehe ich da ein wesentliches Problem?

                Ich dachte ja nur da das auf den ersten Blick der syntax die manche Browser nutzen sehr ähnelt, ist aber wohl doch nicht dasselbe...

                Grüße
                Andreas

                1. Hi,

                  Ich dachte ja nur da das auf den ersten Blick der syntax die manche Browser nutzen sehr ähnelt, ist aber wohl doch nicht dasselbe...

                  nein, ist es in der Tat nicht. Die Syntax in den URLs entstammt RFC 1738; sie ist im allgemeinen Aufbau eines URL-Schemas beschrieben (Absatz 3.1, darauf bezieht sich Puretec zur Rechtfertigung der illegalen "@-Domains") und in bestimmten Schemata wie z.B. dem von FTP durchaus gültig. Allerdings enthält die Syntax nur einen Doppelpunkt, nämlich den zur Trennung von Username und Passwort - kein Wunder, da FTP keine Basic/Digest Authentication und damit auch keine Realms kennt ;-)

                  Cheatah

                  --
                  X-Will-Answer-Email: No
        2. Hi!

          Dann lies mal den Link, da _stehen_ Beispiele, und nicht nur oben, in den Kommentaren darunter steht noch _erheblich_ mehr, interessant sein dprfte für dich vor allem der Kommentar vom 26-Jun-2002: http://www.php3.de/manual/de/function.fsockopen.php
          Bedenke nur das Du so wie Du es bisher GET anstatt POST verwendet hast.

          Jo, ich hab die Offline-Doku und da stehen keine Kommentare.

          Jetzt hab ich mich in die Kommentare eingelesen, besonders den von Dir empfohlenden Beitrag, weil da eben sowas wie eine Passwort-Authentifizierung drinsteht.

          Ich hab nur nicht so recht verstanden, inwiefern ich den $header einbauen kann. :(

          Ob Ihr vielleicht nochmal so nett wäred (schreibt man das so?), mir diesbezüglich nochmal einen Tip zu geben?

          Viele liebe Grüße!

          1. Hallo!

            Jo, ich hab die Offline-Doku und da stehen keine Kommentare.

            Jetzt hab ich mich in die Kommentare eingelesen, besonders den von Dir empfohlenden Beitrag, weil da eben sowas wie eine Passwort-Authentifizierung drinsteht.

            Ich hab nur nicht so recht verstanden, inwiefern ich den $header einbauen kann. :(

            dann lies nochmal die "offiziellen" Beispiele. Da steht auch ein Header drin, der nunmal erheblich kürzer ist.

            Dann guckst Du bei welcher Funktion Du Dir nicht sicher bist  udn guckst bei der nach, also hier z.B. http://www.php3.de/manual/de/function.fputs.php oder besser direkt http://www.php3.de/manual/de/function.fwrite.php. Das ganze funktioniert hier wie das Schreiben eines Strings in eine Datei, nur schreibst Du hier an Stelle des Strings einen Header der an den mit fsockopen genannten Server geschickt wird.
            Wenn Du mal ein bisschen mehr über Header rausfinden willst guck Dir mal http://forum.de.selfhtml.org/cgi-bin/http_trace.pl an! Da kannst Du sehr schön sehen was da für header bin und her geschickt werden.

            Grüße
            Andreas

            1. Hallo,

              also, so siehts bisher bei mir aus:

              $header = "GET / HTTP/1.0\r\n";
              $header .= "Authorization: Basic ";
              $header .= base64_encode("$username:$password") . "\r\n";
              $fp = fsockopen ("10.10.17.63", 80, &$errno, &$errstr, 30);
              if (!$fp) {
                  echo "$errstr ($errno)<br />\n";
              } else {
                  echo "ok, let's go<hr>";
                  fputs ($fp, $header);
                  while (!feof($fp)) {
                      echo fgets($fp,4096);
                  }
                  fclose($fp);
              }

              Mit nem reinen Get ohne dem Authorization-Gedöns bekam ich die vom Server produzierte Mitteilung, dass ohne Anmeldung nichts geht. Soweit so gut, heisst doch schonmal soviel, ich bin auf dem richtigen Weg.

              Dann hab ich die Geschichte mit dem Usernamen und Passwort etc. eingefügt und die Fehlermeldung bleib aus, allerdings wurd auch nichts zurückgegeben. (Zumindest nichts ausser mein 'ok, let's go').

              Auch wenn ich jetzt irgendeine htm-Datei angebe. Geht genauso wenig.

              Ich dürfte doch nun schon ganz schön nah dran sein, oder etwa noch nicht?

              Viele lieben Grüße!

              1. Hallo,

                $header = "GET / HTTP/1.0\r\n";
                $header .= "Authorization: Basic ";
                $header .= base64_encode("$username:$password") . "\r\n";
                $fp = fsockopen ("10.10.17.63", 80, &$errno, &$errstr, 30);
                if (!$fp) {
                    echo "$errstr ($errno)<br />\n";
                } else {
                    echo "ok, let's go<hr>";
                    fputs ($fp, $header);
                    while (!feof($fp)) {
                        echo fgets($fp,4096);
                    }
                    fclose($fp);
                }

                Ich dürfte doch nun schon ganz schön nah dran sein, oder etwa noch nicht?

                bist Du! Es fehlt ein Zeilenumbruch am Ende, so wie es in den Beispielen gemacht wird!

                Grüße
                Andreas

                1. Hallo,

                  bist Du! Es fehlt ein Zeilenumbruch am Ende, so wie es in den Beispielen gemacht wird!

                  Jupp, et lööft, jetzt bekomm ich endlich die Seite angezeigt.

                  Natürlich hab ich noch ein paar Fragen, die ich mal wieder selber nicht gelöst bekomme. Ob Du mir dabei nochmal helfen könntest?

                  Dass die Bilder nicht angezeigt werden ist noch klar, da das Image relativ adressiert wurde und auf meinem Server dieses Bild dann nicht existiert. Klaro.

                  Wenn ich das richtig verstanden habe, lese ich immer 4096 Zeichen ein (es sei denn das Zeilenende wurde vorher erreicht)?
                  Wenn ich nur die ersten 4096 Zeichen ausgebe kommt als Text:
                  HTTP/1.1 200 OK

                  Das sind doch deutlich weniger Zeichen (auch im Quelltext).

                  Naja, egal dachte ich.

                  Jetzt hab ich versucht den String zu untersuchen, aber mein strpos schmeisst mir regelmäßig eine Fehlermeldung aus:
                  Warning: Empty delimiter in ...
                  was wohl heisst, das bei $pos = strpos("Temperature", $zeile);
                  die $zeile leer war.?
                  Außerdem hat er bis jetzt noch kein einziges Mal meinen Text gefunden, welchen ich auch immer gesucht habe. :(

                  Und dann stellt sich noch die Frage, wie ich denn vermeiden kann, dass die 4096 Zeichen nun gerade mein 'Temperature' in der Mitte durchschneiden und ich dadurch den blöden Text nicht finde.

                  Bei der fgets()-Beschreibung gabs so ein Beitrag, hab aber nicht verstanden wie ich das jetzt umsetzen muss.

                  Schön wäre, wenn ich einfach alles mit einem Rutsch eingelesen bekäme.

                  1. Hallo!

                    Jupp, et lööft, jetzt bekomm ich endlich die Seite angezeigt.

                    sehr schön!

                    Wenn ich das richtig verstanden habe, lese ich immer 4096 Zeichen ein (es sei denn das Zeilenende wurde vorher erreicht)?

                    ja, kannst Du aber auch weglassen, einfach fgets($fp)

                    Wenn ich nur die ersten 4096 Zeichen ausgebe kommt als Text:
                    HTTP/1.1 200 OK

                    Das sind doch deutlich weniger Zeichen (auch im Quelltext).

                    Ja, aber danach kommt der erste Zeilenumbruch! also ist das alles was Du an dieser Stelle hast!

                    Naja, egal dachte ich.

                    Kommt drauf an. Wenn Du genau in diese Strung was suchst findest Du auch nur HTTP/1.1 200 OK!

                    Jetzt hab ich versucht den String zu untersuchen, aber mein strpos schmeisst mir regelmäßig eine Fehlermeldung aus:
                    Warning: Empty delimiter in ...
                    was wohl heisst, das bei $pos = strpos("Temperature", $zeile);
                    die $zeile leer war.?

                    Was willst Du genau machen? Willst Du ermitteln ob der Begriff vokommt, oder in welcher Zeile er vorkommt? Wenn letzteres Egal ist, dann würde ich die gesamte ausgabe in einen String schreiben und danach den String untersuchen! an $header hast Du gesehen wie man einen String an einen String hängt. Dasselbe machst Du jetzt einfach mit fgets in der Schleife. Das was bisher mit echo ausgegeben wurde, oder was Du zeilenweise durchsucht hast, hängst Du an einen string, und hast am Ende einen Sting der die komplette Seite enthält und indem Du alles findest.

                    Außerdem hat er bis jetzt noch kein einziges Mal meinen Text gefunden, welchen ich auch immer gesucht habe. :(

                    Das ist komisch, vermutlich durchsuchst Du immer die erste Zeile oder sowas. Versuch es mal so wie ich geschrieben habe!

                    Und dann stellt sich noch die Frage, wie ich denn vermeiden kann, dass die 4096 Zeichen nun gerade mein 'Temperature' in der Mitte durchschneiden und ich dadurch den blöden Text nicht finde.

                    s.o., wobei man das schon da stehen lassen sollte, ist einfach schneller. Und Zeilen länger als 4KB hat man normalerweise eh nicht.

                    Bei der fgets()-Beschreibung gabs so ein Beitrag, hab aber nicht verstanden wie ich das jetzt umsetzen muss.

                    Schön wäre, wenn ich einfach alles mit einem Rutsch eingelesen bekäme.

                    Das Problem bei Dir ist die HTTP-Authentifizierung, das schränkt Dich leider etwas ein!

                    Grüße
                    Andreas