localhorst: Bild runterladen und ausgeben (fsockopen)

Hallo zusammen,

ich lade mir Bilder von einem Content Service runter und möchte diese dann natürlich auch ausgeben. Da dies einbezahlter Service ist liegen die Bilder in einem htaccess geschützem Bereich.

Dafür habe ich mir folgendes Script gebastelt.

<?
$bin_bild=get_secret_file ("contentservice.....", "/WUBPICS/big/21544.jpg", "user", "password");

function get_secret_file ($host, $path, $user, $password) {
###############################################################################################################
###############################################################################################################
  $fp = fsockopen($host, 80);
  fputs($fp, "GET ".$path." HTTP/1.1\n");
  fputs($fp, "Host: ".$host."\n");
  fputs($fp, "Authorization: Basic ".base64_encode($user.":".$password)."\n");
  fputs($fp, "Connection: close\n\n");

$content = "";
  while(!feof($fp)) {
      $content .= fgets($fp, 1024);
  }

fclose($fp);

$handle = fopen ("../../bilder_content/big/21544.jpg", "wb");
  fwrite($handle, $content);
  fclose ($handle);

return $content;
}

?>

Es wird auch ein Bild runtergeladen das von der Größe, dem auf dem Server entspricht. Beim Anzeigen in Firefox kommt dann aber folgender Fehler.

The image “http://.../bilder_content/big/21544.jpg” cannot be displayed, because it contains errors.

Runterladen und öffnen geht auch nicht.

Wo liegt mein Fehler? Textdateien kann ich so runterladen, aber keine Binären Dateien. Denke das da irgentwo der Fehler liegt, ich weiß es aber leider nicht.

Gruß
Localhorst

  1. Tag localhorst.

    ich lade mir Bilder von einem Content Service runter und möchte diese dann natürlich auch ausgeben. [...] Dafür habe ich mir folgendes Script gebastelt.
          $content .= fgets($fp, 1024);

    M.E. solltest du hier besser fread verwenden, schließlich geht es um Binärdaten.

    Es wird auch ein Bild runtergeladen das von der Größe, dem auf dem Server entspricht. Beim Anzeigen in Firefox kommt dann aber folgender Fehler.

    Wie machst du denn die Ausgabe? Das Prinzip für Grafikdateien habe ich mal hier beschrieben:
    http://forum.de.selfhtml.org/archiv/2005/8/t113707/#m722322

    Siechfred

    1. Hi,

      und danke das du dich meines Problemes angenommen hast.

      M.E. solltest du hier besser fread verwenden, schließlich geht es um Binärdaten.

      So weit ich weiß sind beide Binär safe, habs aber auch mit fread getestet und bin zu dem selben Ergebnis gekommen.

      Wie machst du denn die Ausgabe?

      In der Funktion wird die Bilddatei ja wieder in eine neue Datei geschrieben. Hab das auch auf meinem normalen Rechner getestet und wollte die dann normal mit einem Doppleklick öffnen und da kommt nur ein schwarzer Bildschirm. Gimp sagt auch das die Datei einen Fehler enthält.

      Muß ich beim Schreiben der Datei, dieser evtl einen wieder einen Header verpaßen?

      Gruß
      Localhorst

      1. Muß ich beim Schreiben der Datei, dieser evtl einen wieder einen Header verpaßen?

        Ja, sonst gibt's Probleme. Deswegen hatte ich auf mein kleines Beispiel verlinkt, was (abgesehen von dem ganzen fsockopen-Gedöns) genau das leistet, was du willst.

        Siechfred

    2. hi,

      M.E. solltest du hier besser fread verwenden, schließlich geht es um Binärdaten.

      file_get_contents() ist ebenfalls binary safe.

      Und ich sehe eigentlich keinen Grund, mit fsockopen() etc. zu hantieren - mit dem HTTP Wrapper kann man auch das Format
      http://user:password@example.com/...
      benutzen (PHP nutzt dann natürlich nicht diesen bekanntermaßen ungültigen URL, sondern setzt das intern in eine standardkonforme Basic Authentification um.)

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. Ja so geht es auch, aber leider nicht auf dem Webspace auf dem ich damit Arbeite.

        Denn dort kommt dann mal wieder, wie auch bei fopen folgende Fehlermeldung.

        Warning: file_get_contents(): URL file-access is disabled in the server configuration

        Was ich soweit ich weiß auch nicht umgehen kann, bin aber trotzdem für hilfe dankbar. Auf die Server Konfiguration habe ich leider keinen Einfluß.

        Gruß
        Localhorst

        1. Hi,

          Was ich soweit ich weiß auch nicht umgehen kann, bin aber trotzdem für hilfe dankbar. Auf die Server Konfiguration habe ich leider keinen Einfluß.

          Alternativ get es auch noch über cURL - das ist etwas einfacher zu haandhaben als Socket.

          get_contents() versucht ggf. alle 3 Möglichkeiten.

          Gruß, Cybaer

          --
          Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
  2. Hallo Freunde des gehobenen Forumsgenusses,

    $content = "";
      while(!feof($fp)) {
          $content .= fgets($fp, 1024);
      }

    fclose($fp);

    $handle = fopen ("../../bilder_content/big/21544.jpg", "wb");
      fwrite($handle, $content);
      fclose ($handle);

    Du lädst hier die HTTP-Response-Header und das Bild herunter und gibst beides aus.
    Du solltest die Header abschneiden: (ungetestet)
    [code lang=php]$bild = substr($content, strpos($content, "\r\n\r\n")+3);

    Wenn das nicht funktioniert könntest du die 3 zwischen 0 und 8 variieren,
    ich weis nicht, ob "\r\n" ein oder zwei Zeichen sind.

    Gruß
    Alexander Brock

    --
    Ceterum censeo Carthaginem esse delendam
    1. Hab deine Variante auch noch mal getestet, mit allen Zahlen von 0-8 ging auch nicht.

      Bleibt bei der Fehlermeldung.

      function get_secret_file ($host, $path, $user, $password) {
      ###############################################################################################################
      ###############################################################################################################
        $fp = fsockopen($host, 80);
        fputs($fp, "GET ".$path." HTTP/1.1\n");
        fputs($fp, "Host: ".$host."\n");
        fputs($fp, "Authorization: Basic ".base64_encode($user.":".$password)."\n");
        fputs($fp, "Connection: close\n\n");

      $content = "";
        while(!feof($fp)) {
            $content .= fgets($fp, 1024);
        }

      fclose($fp);

      $bild = substr($content, strpos($content, "\r\n\r\n")+8);

      $handle = fopen ("../../bilder_content/big/21544.jpg", "wb");
        fwrite($handle, $bild);
        fclose ($handle);

      return $content;
      }

      1. Hab deine Variante auch noch mal getestet, mit allen Zahlen von 0-8 ging auch nicht.

        4 müsste korrekt sein, wenn ich das richtig überflogen hab.
        Was du aber noch machen solltest, setz ein HTTP/1.0 Request ab, kein HTTP/1.1.

        Auf jeden Fall würd ich mir einmal $content komplett, und einmal das vermeindlich ohne $header als Text ausgeben lassen, dann kannst ja erkennen ob das Header-Abschneiden richtig geht.

        1. Juhu,

          beides sehr gute Ideen.

          Mit der Ausgabe konnte ich es überprüfen und nach dem ich ein HTTP/1.0 Request abgesetzt habe ging es auch. 4 war auch die Richtige Variante!!

          Vielen Dank, ich war schon am verzweifeln.

          Gruß
          Localhorst

          1. Hallo Freunde des gehobenen Forumsgenusses,

            Mit der Ausgabe konnte ich es überprüfen und nach dem ich ein HTTP/1.0 Request abgesetzt habe ging es auch. 4 war auch die Richtige Variante!!

            Könntest du noch die fertige Funktion posten, damit auch Archivsucher etwas davon haben?

            Gruß
            Alexander Brock

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
            1. Könntest du noch die fertige Funktion posten, damit auch Archivsucher etwas davon haben?

              Na aber sicher doch!!!

              Und noch mals vielen Dank für Hilfe, da wäre ich alleine nie drauf gekommen!

              Folgende Funktion lädt eine binäre Datei aus einem mit .htaccess geschützen Ordner und speichert die binäre Datei (Bild) in einem Ordner auf dem localen System.

              ###############################################################################################################
              function get_secret_image($host,$path,$user,$password,$speicher_bild_pfad,$speicher_bild_name) {
              ###############################################################################################################

              $fp = fsockopen($host, 80);
                fputs($fp, "GET ".$path." HTTP/1.0\n");
                fputs($fp, "Host: ".$host."\n");
                fputs($fp, "Authorization: Basic ".base64_encode($user.":".$password)."\n");
                fputs($fp, "Connection: close\n\n");

              $content = "";
                while(!feof($fp)) {
                    $content .= fgets($fp, 1024);
                }

              fclose($fp);
                $bild = substr($content, strpos($content, "\r\n\r\n")+4);
                $handle = fopen ($speicher_bild_pfad.$speicher_bild_name, "wb");
                fwrite($handle, $bild);
                fclose ($handle);
              }

              Für normale nicht binäre Dateien benutze ich folgende Funktion.

              ###############################################################################################################
              ###############################################################################################################
              function get_secret_file ($host, $path, $user, $password) {
              ###############################################################################################################
              ###############################################################################################################
                $fp = fsockopen($host, 80);
                fputs($fp, "GET ".$path." HTTP/1.1\n");
                fputs($fp, "Host: ".$host."\n");
                fputs($fp, "Authorization: Basic ".base64_encode($user.":".$password)."\n");
                fputs($fp, "Connection: close\n\n");

              $content = "";
                while(!feof($fp)) {
                    $content .= fgets($fp, 1024);
                }

              fclose($fp);

              return $content;
              }

              1. Hallo Localhorst,

                Für normale nicht binäre Dateien benutze ich folgende Funktion.
                function get_secret_file ($host, $path, $user, $password) ...

                Das heißt aber, dass du bei denen auch das ganze Gedöns mit den HTTP Response Headers mit als Dateiinhalt ausgibst. Besser wäre es, die obige Funktion, die bei Bildern und sonstige Binärdateien funktioniert, auch für alle anderen Dateien zu verwenden.

                Denn das hier

                while(!feof($fp)) {
                      $content .= fgets($fp, 1024);
                  }

                sammelt ja wirklich *alles*, was der Server antwortet, als $content auf, und das ist eigentlich falsch.

                Schönen Sonntag noch,

                Martin