| 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"); |
| 166 | | header("Pragma: no-cache"); |
| 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 | | } |
| | 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); |