Jo: Umleitung

Hallo,

ich habe mit einer .htaccess eine rewrite Regel geschrieben, die alle Aufrufe von .zip Dateien in einem bestimmten Verzeichnis erst an ein Prüfscript weiterleitet:

RewriteRule (.*).zip$ checkdownload.php?file=$1

Das funktioniert soweit auch gut. Jetzt soll aber eine weitere Regel den Aufruf einer .zip Datei über alle PHP-Scripte auf dem Server z.B. via header('Location: '.$file); selbst erlauben.

Wie bekomm ich das hin?

Danke
Jo

  1. Tach!

    RewriteRule (.*).zip$ checkdownload.php?file=$1
    Jetzt soll aber eine weitere Regel den Aufruf einer .zip Datei über alle PHP-Scripte auf dem Server z.B. via header('Location: '.$file); selbst erlauben.

    Du schickst also den Client per Redirect wieder zum Server und diesmal sollen aber Zip-Dateien ausgeliefert werden? Dann muss also irgendein Unterscheidungskriterium in den Client-Request rein. Cookie wäre eine Möglichkeit. Ich würde das aber gar nicht so machen, sondern die Datei mit readfile() direkt durchreichen. Weniger Requests, weniger Fehlermöglichkeiten.

    dedlfix.

    1. Ich würde das aber gar nicht so machen, sondern die Datei mit readfile() direkt durchreichen. Weniger Requests, weniger Fehlermöglichkeiten.

      Danke, da haste natürlich recht ;-)
      ich machs jetzt so:

        
      $filename = htmlspecialchars($_GET['file']);  
      $filename = realpath($filename);  
      $file_extension = strtolower(substr(strrchr($filename,"."),1));  
        
      switch ($file_extension) {  
      	case "pdf": $ctype="application/pdf"; break;  
      	case "exe": $ctype="application/octet-stream"; break;  
      	case "zip": $ctype="application/zip"; break;  
      	case "doc": $ctype="application/msword"; break;  
      	case "xls": $ctype="application/vnd.ms-excel"; break;  
      	case "ppt": $ctype="application/vnd.ms-powerpoint"; break;  
      	case "gif": $ctype="image/gif"; break;  
      	case "png": $ctype="image/png"; break;  
      	case "jpe": case "jpeg":  
      	case "jpg": $ctype="image/jpg"; break;  
      	default: $ctype="application/force-download";  
      }  
        
      if (!file_exists($filename)) {  
      	die("File nicht gefunden!");  
      }  
        
      header("Pragma: public");  
      header("Expires: 0");  
      header("Cache-Control: must-revalidate, post-check=0, pre-check=0");  
      header("Cache-Control: private",false);  
      header("Content-Type: $ctype");  
      header("Content-Disposition: attachment; filename=\"".basename($filename)."\";");  
      header("Content-Transfer-Encoding: binary");  
      header("Content-Length: ".@filesize($filename));  
      set_time_limit(0);  
      @readfile("$filename") or die("File kann nicht gelesen werden.");  
        
      
      

      Es werden teilweise recht große .zip Files (um 500 MB) durchgereicht.
      Ist das ok oder muss ich noch was beachten?

      Jo

      1. Moin Jo,

        Danke, da haste natürlich recht ;-)
        ich machs jetzt so:
        […]
        Ist das ok oder muss ich noch was beachten?

        Was passiert, wenn ich als file-Parameter /etc/passwd angebe? Achte darauf, dass nur Dateien ausgeliefert werden, die du auch wirklich ausliefern willst. Beachte auch, dass relative Pfadangaben möglich sind.

        LG,
         CK

      2. Tach!

        $filename = htmlspecialchars($_GET['file']);
        $filename = realpath($filename);

        Das Dateisystem basiert nicht auf HTML, htmlspecialchars() hat da normalerweise nichts verloren. Dateinamen unterliegen anderen Beschränkungen. Nach dem realpath() fehlt eine Prüfung, ob der Dateiname mit dem Pfad-Teil anfängt, in dem die Dateien zu finden sind.

        @readfile("$filename") [...]
        Es werden teilweise recht große .zip Files (um 500 MB) durchgereicht. Ist das ok oder muss ich noch was beachten?

        Mit readfile() ist das ok, das reicht die Datei stückweise durch, ohne großartig Speicher zu verwenden.

        dedlfix.

      3. Hi,

        @readfile("$filename") or die("File kann nicht gelesen werden.");

          
        
        > Es werden teilweise recht große .zip Files (um 500 MB) durchgereicht.  
        > Ist das ok oder muss ich noch was beachten?  
          
        Hab zufällig grade eine Datei mit knapp über 500 MB runtergeladen. Hat ca. 5 Minuten 40 Sekunden gedauert.  
        Bei Dateien dieser Größenordnung könnte demnach die maximale Script-Laufzeit überschritten werden (das sind ggf. "nur" 30s), also die Server-Konfiguration daraufhin überprüfen ...  
        set\_time\_limit in der php.ini, wenn ich mich richtig erinnere - php.net kann ich derzeit nicht erreichen.  
          
        cu,  
        Andreas
        
        -- 
        [Warum nennt sich Andreas hier MudGuard?](http://MudGuard.de/)  
        [O o ostern ...](http://ostereier.andreas-waechter.de/)  
          
        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.  
        
        
        1. Tach!

          Hab zufällig grade eine Datei mit knapp über 500 MB runtergeladen. Hat ca. 5 Minuten 40 Sekunden gedauert.
          Bei Dateien dieser Größenordnung könnte demnach die maximale Script-Laufzeit überschritten werden (das sind ggf. "nur" 30s), also die Server-Konfiguration daraufhin überprüfen ...

          Zu beachten ist allerdings, dass diese Zeit (außer unter Windows) die reine Prozessorzeit des Scripts umfasst. Wartezeiten beim Dateilesen und dass der Datenübertragungspuffer wieder leer wird, zählen nicht darunter.

          set_time_limit in der php.ini, wenn ich mich richtig erinnere - php.net kann ich derzeit nicht erreichen.

          set_time_limit() ist eine Funktion, die Einstellung in der php.ini heißt max_execution_time.

          dedlfix.