@@ -2367,22 +2367,38 @@ function output_file($path, $chunkSize=1024) {
23672367 header ("Content-Disposition: $ contentDisposition;filename= \"$ file \"" );
23682368
23692369 header ('Accept-Ranges: bytes ' );
2370- $ range = 0 ;
23712370 $ size = filesize ($ path );
2371+ $ start = 0 ;
2372+ $ end = $ size - 1 ;
23722373
23732374 if (isset ($ _SERVER ['HTTP_RANGE ' ])) {
2374- list ($ a , $ range ) = explode ('= ' , $ _SERVER ['HTTP_RANGE ' ]);
2375- str_replace ($ range , '- ' , $ range );
2376- $ range = (int )$ range ; #fseek etc require integers not strings
2377- $ size2 = $ size - 1 ;
2378- $ new_length = $ size - $ range ;
2375+ # RFC 7233: bytes=start-end | bytes=start- | bytes=-suffix
2376+ if (preg_match ('/^bytes=(\d*)-(\d*)$/ ' , trim ($ _SERVER ['HTTP_RANGE ' ]), $ m )
2377+ and ($ m [1 ] !== '' or $ m [2 ] !== '' )) {
2378+ if ($ m [1 ] === '' ) {
2379+ # Suffix range: last N bytes
2380+ $ suffix = (int )$ m [2 ];
2381+ if ($ suffix > $ size ) $ suffix = $ size ;
2382+ $ start = $ size - $ suffix ;
2383+ } else {
2384+ $ start = (int )$ m [1 ];
2385+ if ($ m [2 ] !== '' ) $ end = (int )$ m [2 ];
2386+ }
2387+ if ($ end > $ size - 1 ) $ end = $ size - 1 ;
2388+ }
2389+ if ($ start > $ end or $ start >= $ size ) {
2390+ header ('HTTP/1.1 416 Range Not Satisfiable ' );
2391+ header ("Content-Range: bytes */ $ size " );
2392+ return false ;
2393+ }
2394+ $ length = $ end - $ start + 1 ;
23792395 header ('HTTP/1.1 206 Partial Content ' );
2380- header ("Content-Length: $ new_length " );
2381- header ("Content-Range: bytes $ range - $ size2 / $ size " );
2396+ header ("Content-Length: $ length " );
2397+ header ("Content-Range: bytes $ start - $ end / $ size " );
23822398 } else {
2383- $ size2 = $ size - 1 ;
2384- header ("Content-Range: bytes 0- $ size2 / $ size " );
2385- header (' Content-Length: ' . $ size );
2399+ $ length = $ size ;
2400+ header ("Content-Range: bytes 0- $ end / $ size " );
2401+ header (" Content-Length: $ size" );
23862402 }
23872403
23882404 if ($ size == 0 ) {
@@ -2391,13 +2407,18 @@ function output_file($path, $chunkSize=1024) {
23912407 @ini_set ('magic_quotes_runtime ' , 0 );
23922408 $ fp = fopen ($ path , 'rb ' );
23932409
2394- fseek ($ fp , $ range );
2410+ fseek ($ fp , $ start );
23952411
2396- while (!feof ($ fp ) and (connection_status () == 0 )) {
2412+ $ remaining = $ length ;
2413+ $ buffer = 1024 * $ chunkSize ;
2414+ while ($ remaining > 0 and !feof ($ fp ) and (connection_status () == 0 )) {
23972415 set_time_limit (0 );
2398- print (@fread ($ fp , 1024 *$ chunkSize ));
2416+ $ data = @fread ($ fp , min ($ buffer , $ remaining ));
2417+ if ($ data === false or $ data === '' ) break ;
2418+ print ($ data );
23992419 flush ();
2400- ob_flush ();
2420+ if (ob_get_level () > 0 ) ob_flush ();
2421+ $ remaining -= strlen ($ data );
24012422 }
24022423 fclose ($ fp );
24032424
0 commit comments