Changeset 3361

Show
Ignore:
Timestamp:
12/15/2007 01:44:50 AM (9 months ago)
Author:
mayoojin
Message:

Support for broken downloads resuming via parsing 'Range' header value. This addition will ONLY work if PHP is run as Apache module and PHP >= 4.3.0. This condition is checked automatically I added some comments, so you, devs, please, review this.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • sandbox/modules/file/file.controller.php

    r3344 r3361  
    9191            $fp = fopen($uploaded_filename, 'rb'); 
    9292            if(!$fp) return $this->stop('msg_not_permitted_download'); 
    93  
    94             header("Cache-Control: "); 
    95             header("Pragma: "); 
    96             header("Content-Type: application/octet-stream"); 
    97             header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
    98  
    99             header("Content-Length: " .(string)($file_obj->file_size)); 
    100             header('Content-Disposition: attachment; filename="'.$filename.'"'); 
    101             header("Content-Transfer-Encoding: binary\n"); 
    102  
    103             fpassthru($fp); 
     93                         
     94                        // Support for broken downloads resuming via parsing 'Range' header value. Made by X-[Vr]bL1s5. 
     95                        // This addition will ONLY work if PHP is run as Apache module and PHP >= 4.3.0 
     96                        if (function_exists('apache_request_headers')) { // check if we run as Apache module. 
     97                                $fr_buffer_size = 8192; 
     98                                 
     99                                $fr_headers = apache_request_headers(); 
     100                                if (isset($fr_headers['Range'])) { 
     101                                        $fr_range_header = trim($fr_headers['Range']); 
     102                                        $fr_range_header = str_replace('bytes=', '', $fr_range_header); 
     103                                        $fr_range = explode ('-', $fr_range_header); 
     104                                        if (isset($fr_range[0]) && ($fr_range[0] != NULL)) { 
     105                                                if (!is_numeric($fr_range[0])) return $this->stop('msg_not_permitted_download'); // invalid header values 
     106                                                $fr_range_begin = $fr_range[0]; 
     107                                                if ((int) ($fr_range_begin) < 0) $fr_range_begin = 0; 
     108                                        } else { 
     109                                                $fr_range_begin = 0; 
     110                                        } 
     111                                        if (isset($fr_range[1]) && ($fr_range[1] != NULL)) { 
     112                                                if (!is_numeric($fr_range[1])) return $this->stop('msg_not_permitted_download'); // invalid header values 
     113                                                $fr_range_end = $fr_range[1]; 
     114                                                if ((int) ($fr_range_end) > ($file_obj->file_size - 1)) $fr_range_end = $file_obj->file_size - 1; 
     115                                        } else { 
     116                                                $fr_range_end = $file_obj->file_size - 1; 
     117                                        } 
     118                                         
     119                                        $fr_content_length = $fr_range_end - $fr_range_begin + 1; 
     120                                         
     121                                        header("HTTP/1.1 206 Partial Content"); // oh... maybe HTTP proto version will change... ^^; 
     122                                        header("Cache-Control: no-cache"); 
     123                                        header("Pragma: no-cache"); 
     124                                         
     125                                        header("Accept-Ranges: bytes"); 
     126                                        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
     127                                        header("Content-Type: application/octet-stream"); 
     128                                        header('Content-Disposition: attachment; filename="'.$filename.'"'); 
     129                                         
     130                                        header("Content-Length: $fr_content_length"); 
     131                                        header("Content-Range: bytes $fr_range_begin-$fr_range_end/" .(string)($file_obj->file_size)); 
     132                                        header("Content-Transfer-Encoding: binary"); 
     133                                         
     134                                        $fr_bytes_read = 0; 
     135 
     136                                        if (fseek($fp, $fr_range_begin) != 0) return $this->stop('msg_not_permitted_download'); // unable to seek file. 
     137 
     138                                        while (!feof($fp)) { 
     139                                                $fr_buffer = fread($fp, $fr_buffer_size); 
     140                                                $fr_bytes_read += strlen($fr_buffer); 
     141                                                if ($fr_content_length > $fr_bytes_read) { 
     142                                                        echo $fr_buffer; 
     143                                                } else { 
     144                                                        $fr_buffer = substr($fr_buffer, 0, strlen($fr_buffer) - ($fr_bytes_read - $fr_content_length)); 
     145                                                        echo $fr_buffer; 
     146                                                        break; 
     147                                                } 
     148                                        } 
     149                                } else { 
     150                                        header("HTTP/1.1 200 OK"); // oh... maybe HTTP proto version will change... ^^; 
     151                                        header("Cache-Control: no-cache"); 
     152                                        header("Pragma: no-cache"); 
     153                                        header("Accept-Ranges: bytes"); // we should claim that we accept ranges! 
     154                                        header("Content-Type: application/octet-stream"); 
     155                                        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
     156 
     157                                        header("Content-Length: " .(string)($file_obj->file_size)); 
     158                                        header('Content-Disposition: attachment; filename="'.$filename.'"'); 
     159                                        header("Content-Transfer-Encoding: binary"); 
     160 
     161                                        fpassthru($fp);                          
     162                                } 
     163                        } else { // end of the support... 
     164                         
     165                                header("Cache-Control: no-cache"); // originally here it these lines were empty headers like "Cache-Control: ". I don't know why... but it might break the standards. // X-[Vr]bL1s5 
     166                                header("Pragma: no-cache"); // here too 
     167                                header("Content-Type: application/octet-stream"); 
     168                                header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
     169 
     170                                header("Content-Length: " .(string)($file_obj->file_size)); 
     171                                header('Content-Disposition: attachment; filename="'.$filename.'"'); 
     172                                header("Content-Transfer-Encoding: binary"); 
     173 
     174                                fpassthru($fp); 
     175                        } 
    104176 
    105177            // 이상이 없으면 download_count 증가 
     
    311383            $output->add('source_filename', $args->source_filename); 
    312384            $output->add('upload_target_srl', $upload_target_srl); 
    313             $output->add('sid', $args->sid); 
    314             $output->add('direct_download', $args->direct_download); 
    315385            return $output; 
    316386        }