php_neuling: download einer Datei von einem Server

Hallo,

ich möchte von dieser Seite http://browsers.garykeith.com/downloads die Datei php_browscap.ini per php-script downloaden. Wenn ich das mit meinem Browser mache, also http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI in die Adresszeile eingebe, dann bekomme ich die Datei. Wenn ich das aber mit folgendem script mache:

$bc_url = "browsers.garykeith.com";  
function get_remote_file($url, $method = "GET", $data = "", $redirect = 10) {  
    $fp = fsockopen ($url, 80, $errno, $errstr, 30);  
    if ($fp) {  
        $path = $url."/stream.asp?PHP_BrowsCapINI";  
        $header = "\r\nHost: ".$url."\r\n";  
        $header .= "Connection: Close\r\n\r\n";  
        fputs ($fp, $method." ".$path." HTTP/1.0".$header);  
        $body = "";  
        while ( !feof($fp) ) $body .= fgets($fp);  
        fclose($fp);  
    }  
    else return ("Fehler");  
    return $body;  
}  
$erg = get_remote_file($bc_url);  
if($erg!="Fehler") {  
  $handle = fopen('php_browscap.ini','w');  
  fwrite($handle,$erg);  
  fclose($handle);  
  chmod('php_browscap.ini',0755);  
  $out = "Fertig";  
} else { $out = $erg; }  
echo $out;  

dann bekomme ich folgende Antwort:

HTTP/1.1 400 Bad Request
Content-Type: text/html
Date: Thu, 15 Mar 2012 16:09:06 GMT
Connection: close
Content-Length: 34

<h1>Bad Request (Invalid URL)</h1>

Offenbar klappt zwar die Verbindung, doch irgendwie ist doch was falsch, aber ich weiß nicht was :-(

Wäre schön, wenn mir jemand helfen könnte, vielen Dank schonmal

php_neuling

  1. Hallo,

    $bc_url = "http://browsers.garykeith.com";

    ???  
      
    Bei http://browsers.garykeith.com/ kommt aber sowieso keine antwort ...;  
      
    Gruß  
      
    jobo
    
    1. Hallo,

      $bc_url = "http://browsers.garykeith.com";

      
      > ???  
      >   
      > Bei http://browsers.garykeith.com/ kommt aber sowieso keine antwort ...;  
      >   
      > Gruß  
      >   
      > jobo  
        
      Hallo, ich weiß nicht, warum du das "http://" in meine $bc\_url Variable reingemacht hast, das bringt, wie du richtig sagst gar nichts...  
        
      trotzdem vielen Dank für die Mühe  
        
      php\_neuling
      
      1. Hallo,

        Hallo,

        $bc_url = "http://browsers.garykeith.com";

        
        > > ???  
        > >   
        > > Bei http://browsers.garykeith.com/ kommt aber sowieso keine antwort ...;  
        > >   
        > > Gruß  
        > >   
        > > jobo  
        >   
        > Hallo, ich weiß nicht, warum du das "http://" in meine $bc\_url Variable reingemacht hast, das bringt, wie du richtig sagst gar nichts...  
        >   
        > trotzdem vielen Dank für die Mühe  
        >   
        > php\_neuling  
          
        Weil die Eingabe der URL in meinem Browser auch nix gebracht hat, also Server-nix-erreichbar ...;  
          
        Gruß  
          
        jobo
        
  2. Hallo,

    ich möchte von dieser Seite http://browsers.garykeith.com/downloads die Datei php_browscap.ini per php-script downloaden. Wenn ich das mit meinem Browser mache, also http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI in die Adresszeile eingebe, dann bekomme ich die Datei.

    und zwar mit Hilfe von HTTP/1.1

    Wenn ich das aber mit folgendem script mache:

    warum willst Du sowas von Hand zu Fuß machen?

    [code lang=php]$bc_url = "browsers.garykeith.com";
    function get_remote_file($url, $method = "GET", $data = "", $redirect = 10) {
        $fp = fsockopen ($url, 80, $errno, $errstr, 30);
        if ($fp) {
            $path = $url."/stream.asp?PHP_BrowsCapINI";
            $header = "\r\nHost: ".$url."\r\n";
            $header .= "Connection: Close\r\n\r\n";
            fputs ($fp, $method." ".$path." HTTP/1.0".$header);

    und warum wunderst Du Dich, wenn Du HTTP/1.0 sprechen willst, dass

    dann bekomme ich folgende Antwort:

    HTTP/1.1 400 Bad Request

    sich die Gegenstelle beklagt.
    Abgesehen davon ist es absolut keine gute Idee, so etwas von Hand zu Fuß machen zu wollen. Falls die fopen-Wrapper freigeschaltet sind, nutze einfach file_get_contents(). Falls nicht, wäre die curl-Erweiterung die nächste Idee.

    Freundliche Grüße

    Vinzenz

    1. Hallo,

      vielen Dank auch dir

      und zwar mit Hilfe von HTTP/1.1

      das habe ich geändert, aber es ändert sich nichts am Ergebnis, die Gegenstelle beklagt sich immer noch...

      Abgesehen davon ist es absolut keine gute Idee, so etwas von Hand zu Fuß machen zu wollen. Falls die fopen-Wrapper freigeschaltet sind, nutze einfach file_get_contents(). Falls nicht, wäre die curl-Erweiterung die nächste Idee.

      sowohl bei file-get-contents als auch bei curl_init bekomme ich die Fehlermeldung: Fatal error: Call to undefined function curl_init()...
      (bzw. file_get_contents() ), ansonsten wären das sicher gute Möglichkeiten.

      freundliche Grüße zurück

      php_neuling

      1. sorry, hab noch mal nachgesehen, die Fehlermeldung war wie folgt:

        Warning: file_get_contents(http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 403 in...

        viele Grüße

        php_neuling

        1. Hallo,

          sorry, hab noch mal nachgesehen, die Fehlermeldung war wie folgt:

          Warning: file_get_contents(http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 403 in...

          http://de.selfhtml.org/servercgi/server/httpstatuscodes.htm@title=Statuscode 403 bedeutet "verboten" :-) Die Gegenstelle rückt mit den Angaben, die PHP macht, die Datei nicht einfach heraus.

          wget wäre ein gutes Werkzeug, um herauszufinden, was die Gegenstelle alles so will.

          Die Live HTTP Headers erzählen mir übrigens folgendes:

          http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI

          GET /stream.asp?PHP_BrowsCapINI HTTP/1.1
          Host: browsers.garykeith.com
          User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2

          (oh, ich muss meinen Firefox noch updaten :-))

          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
          Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
          Accept-Encoding: gzip, deflate
          Connection: keep-alive
          Referer: http://forum.de.selfhtml.org/my/?t=209515&m=1426038
          Cookie: ASPSESSIONIDQCDRRBBC=NLONBHHAECBBEPMBCPCKCONL

          HTTP/1.1 200 OK
          Cache-Control: private
          Connection: close
          Date: Thu, 15 Mar 2012 16:22:18 GMT
          Content-Type: application/octet-stream; Charset=UTF-8
          Server: Microsoft-IIS/6.0
          X-Powered-By: ASP.NET
          Content-Disposition: attachment; filename=php_browscap.ini
          Content-Encoding: gzip
          Vary: Accept-Encoding
          Transfer-Encoding: chunked

          Freundliche Grüße

          Vinzenz

          1. Hallo Ingrid,

            User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2

            (oh, ich muss meinen Firefox noch updaten :-))

            done!

            Freundliche Grüße

            Vinzenz

            1. Hallo,

              ich habe jetzt den pfad geändert, indem ich $url weggelassen habe, dadurch kommt nun vom Server eine andere Fehlermeldung:

              HTTP/1.1 302 Object moved
              Connection: close
              Date: Thu, 15 Mar 2012 17:05:36 GMT
              Server: Microsoft-IIS/6.0
              X-Powered-By: ASP.NET
              Location: /error/invalid-ua
              Content-Length: 138
              Content-Type: text/html
              Set-Cookie: ASPSESSIONIDQCDRRBBC=GFIBCHHAKGIBNHLEEOIKGDHA; path=/
              Cache-control: private

              <head><title>Object moved</title></head>
              <body><h1>Object Moved</h1>This object may be found <a HREF="/error/invalid-ua">here</a>.</body>

              und diese Seite sagt mir, dass ich mit einem blanken useragent nicht an die Datei komme. D.h. doch, dass ich im header meinen useragent angeben muss oder? obwohl ich ehrlich gesagt nicht verstehe, warum der nicht automatisch mitgeschickt wird.

              viele Grüße

              php_neuling (der übrigens nicht Ingrid ist)

              1. Hi,

                ich habe jetzt den pfad geändert, indem ich $url weggelassen habe, dadurch kommt nun vom Server eine andere Fehlermeldung:

                <body><h1>Object Moved</h1>This object may be found
                <a HREF="/error/invalid-ua">here</a>.</body>

                ^^^^^^^^^^
                Die Adresse, auf die da umgeleitet wird, klingt ziemlich deutlich danach, dass der Gegenseite dein User-Agent-String, der beim Request mitgesendet wird, nicht passt (ggf. auch weil einfach nicht vorhanden).

                Schicke mal noch einen User-Agent-Header mit, wie bspw. den aus Vinzenz' Beispiel.

                MfG ChrisB

                --
                RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                1. Hi Chris,

                  Schicke mal noch einen User-Agent-Header mit, wie bspw. den aus Vinzenz' Beispiel.

                  das habe ich jetzt gemacht und es funktioniert :-) freu, freu :-)

                  also vielen Dank an euch, habt mir sehr geholfen :-)

                  php_neuling

              2. Hallo,

                und diese Seite sagt mir, dass ich mit einem blanken useragent nicht an die Datei komme. D.h. doch, dass ich im header meinen useragent angeben muss oder? obwohl ich ehrlich gesagt nicht verstehe, warum der nicht automatisch mitgeschickt wird.

                Ändern kannst Du den user-agent zum Beispiel mit ini_set(). Die zu ändernde Einstellung heißt user_agent.

                php_neuling (der übrigens nicht Ingrid ist)

                Oh, das war auch nicht an Dich gerichtet. Ich hab' nur gerade das (TM) nicht gefunden. Hier wird ein Ingrid-Posting als Gunnar™-Beitrag bezeichnet, siehe z.B. </archiv/2010/4/t196934/#m1320173> :-)

                Freundliche Grüße

                Vinzenz

      2. Hallo,

        und zwar mit Hilfe von HTTP/1.1

        das habe ich geändert, aber es ändert sich nichts am Ergebnis, die Gegenstelle beklagt sich immer noch...

        HTTP/1.1 ist deutlich komplizierter als HTTP/1.0. Der Datentransfer kann häppchenweise erfolgen und erfolgt hier häppchenweise (chunked). Du musst darauf gefasst sein, diese Häppchen richtig verarbeiten und immer hübsch richtig antworten, d.h. Du darfst Dich in die Einzelheiten des Protokolls einlesen und musst diese umsetzen.

        Schau Dir bitte in phpinfo() an, was die von Dir genutze PHP-Installation Dir bietet und wie sie konfiguriert ist.

        Ich glaube nicht, dass es eine gute Idee ist, mit fsockopen zu arbeiten.

        Freundliche Grüße

        Vinzenz

  3. Moin!

    ich möchte von dieser Seite http://browsers.garykeith.com/downloads die Datei php_browscap.ini per php-script downloaden. Wenn ich das mit meinem Browser mache, also http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI in die Adresszeile eingebe, dann bekomme ich die Datei.

    Ich halte die Nutzung solcher statischen Browserinfos für sehr fragwürdig. Wie dir in der PHP-Doku zum Befehl get_browser() ja für Cookies illustriert wird, enthält diese Datei eben gerade nur Infos über die GRUNDSÄTZLICHEN technischen Möglichkeiten des erkannten Browsers. Es wird hingegen keinerlei Rücksicht genommen auf die eventuellen Einstellungen, die der User gemacht hat. get_browser() wird also immer "Javascript = true" für einen Firefox ausgeben, auch wenn der User Javascript abgeschaltet hat oder mit NoScript o.ä. selektiv Javascript deaktiviert hat.

    Weiterhin ist diese gesamte Erkennung von Fähigkeiten ausschließlich basiert auf:
    1. Dem vom Browser mitgeschickten User-Agent, den man als User sehr leicht verändern kann, insbesondere auf falsche Werte bzw. Werte anderer existierender Browser verstellen kann.
    2. Der Existenz einer passenden browscap.ini-Datei, die zu pflegen ziemlich aufwendig ist.

    Obendrein sehe ich in der Ausgabe des Funktionsaufrufs von get_browser() eigentlich auch keine wertvolle Information, die ich als Programmierer einer Webseite oder Webapplikation nutzen wollen würde.

    Naja, zugegeben: Die Browserfamilie oder ggf. auch die Browserversion wäre dann interessant, wenn ich in einer erklärenden Support-Seite Screenshots von Browser-Dialogen anzeigen will, und dabei dynamisch dem User immer die Screenshots seines eigenen Browsers (oder zumindest einer nicht sehr veralteten Version) zeigen will. Sowas macht allerdings immer noch hohen Pflegeaufwand für etwas, was vom User mutmaßlich kaum wertgeschätzt werden würde.

    Summa summarum: Lohnt sich nicht in meinen Augen, damit überhaupt zu experimentieren. Für was hättest du das einsetzen wollen?

    Wenn ich das aber mit folgendem script mache:

    $bc_url = "browsers.garykeith.com";

    function get_remote_file($url, $method = "GET", $data = "", $redirect = 10) {
        $fp = fsockopen ($url, 80, $errno, $errstr, 30);
        if ($fp) {
            $path = $url."/stream.asp?PHP_BrowsCapINI";
            $header = "\r\nHost: ".$url."\r\n";
            $header .= "Connection: Close\r\n\r\n";
            fputs ($fp, $method." ".$path." HTTP/1.0".$header);
            $body = "";
            while ( !feof($fp) ) $body .= fgets($fp);
            fclose($fp);
        }
        else return ("Fehler");
        return $body;
    }
    $erg = get_remote_file($bc_url);
    if($erg!="Fehler") {
      $handle = fopen('php_browscap.ini','w');
      fwrite($handle,$erg);
      fclose($handle);
      chmod('php_browscap.ini',0755);
      $out = "Fertig";
    } else { $out = $erg; }
    echo $out;

    
    >   
    > dann bekomme ich folgende Antwort:  
    >   
    > HTTP/1.1 400 Bad Request  
    > Content-Type: text/html  
    > Date: Thu, 15 Mar 2012 16:09:06 GMT  
    > Connection: close  
    > Content-Length: 34  
    >   
    > <h1>Bad Request (Invalid URL)</h1>  
      
    Du hast die [FAQ](http://browsers.garykeith.com/faq) nicht gelesen. Dort wird ausführlich erklärt, dass du gefälligst die "Terms of Service" berücksichtigen sollst, insbesondere keinen Abuse des Downloads betreiben darfst (mehr als 100 Requests pro Tag sind Abuse, Requests ganz ohne oder mit User-Agents kürzer als 10 Zeichen sind Abuse).  
      
    Da ich in deinem Skript keinerlei Mechanismus zum Zwischenspeichern oder Abfragen auf Aktualisierung der Datei gefunden habe, und du in diese Sicherungsmaßnahmen gegen Serverüberlast blind reingetappt bist, ist davon auszugehen, dass deine Requests künftig ohnehin wegen Überlastung des Servers gesperrt werden.  
      
    Wie man an dem zwischenzeitlich aufgetretenen 403-Status gesehen hat, dürfte das tatsächlich streng kontrolliert werden.  
      
    Angesichts der Überflüssigkeit der Funktion get\_browser() (wäre nur sinnvoll nutzbar für PHP-Versionen mit topaktueller browscap.ini - das ist aber nicht garantierbar der Fall) würde ich mir den Aufwand einfach sparen. Alle Browserfähigkeiten ermittelt man schlauerweise IM BROWSER SELBST.  
      
     - Sven Rautenberg