Changeset 124345 in spip-zone


Ignore:
Timestamp:
Apr 27, 2020, 12:43:53 PM (6 weeks ago)
Author:
Cerdic
Message:

Prise en charge des requetes avec un entete Range et ajout de Accept-Ranges: bytes : fort utile pour la lecture de documents audio/video

Location:
_plugins_/acces_restreint/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/acces_restreint/trunk

    • Property subgit:lock:28a0722ab0b2e7f9878636c4f6f18aba3076d8ff deleted
    • Property subgit:lock:39ac37480194f01b3e215eee8b91fba7e28465d1 set to 2020-04-27T14:44:02.418
  • _plugins_/acces_restreint/trunk/action/api_docrestreint.php

    r102789 r124345  
    224224
    225225        // toujours envoyer un content type, meme vide !
     226        header('Accept-Ranges: bytes');
    226227        header('Content-Type: ' . $Document->get_mime_type());
    227228
     
    256257        }
    257258
    258         if ($size = filesize($chemin_fichier)) {
    259                 header('Content-Length: '. $size);
    260         }
    261 
    262         readfile($chemin_fichier);
     259        if (isset($_SERVER['HTTP_RANGE'])) {
     260                accesrestreint_envoyer_partie($chemin_fichier, $Document->get_mime_type());
     261        }
     262        else {
     263                if ($size = filesize($chemin_fichier)) {
     264                        header('Content-Length: '. $size);
     265                }
     266
     267                readfile($chemin_fichier);
     268        }
     269}
     270
     271/**
     272 * Prendre en charge l'entete Range:bytes=0-456 utilise par les player medias
     273 * source : https://github.com/pomle/php-serveFilePartial/blob/master/ServeFilePartial.inc.php
     274 *
     275 * @param string $fileName
     276 * @param string $contentType
     277 * @throws Exception
     278 */
     279function accesrestreint_envoyer_partie($fileName, $contentType = 'application/octet-stream'){
     280        if (!file_exists($fileName)){
     281                throw new \Exception(sprintf('File not found: %s', $fileName));
     282        }
     283
     284        if (!is_readable($fileName)){
     285                throw new \Exception(sprintf('File not readable: %s', $fileName));
     286        }
     287
     288
     289        ### Remove headers that might unnecessarily clutter up the output
     290        header_remove('Cache-Control');
     291        header_remove('Pragma');
     292
     293
     294        ### Default to send entire file
     295        $byteOffset = 0;
     296        $byteLength = $fileSize = filesize($fileName);
     297
     298        //header('Accept-Ranges: bytes', true);
     299        //header(sprintf('Content-Type: %s', $contentType), true);
     300
     301        ### Parse Content-Range header for byte offsets, looks like "bytes=11525-" OR "bytes=11525-12451"
     302        if (isset($_SERVER['HTTP_RANGE']) && preg_match('%bytes=(\d+)-(\d+)?%i', $_SERVER['HTTP_RANGE'], $match)){
     303                ### Offset signifies where we should begin to read the file
     304                $byteOffset = (int)$match[1];
     305
     306
     307                ### Length is for how long we should read the file according to the browser, and can never go beyond the file size
     308                if (isset($match[2])){
     309                        $finishBytes = (int)$match[2];
     310                        $byteLength = $finishBytes+1;
     311                } else {
     312                        $finishBytes = $fileSize-1;
     313                }
     314
     315                $cr_header = sprintf('Content-Range: bytes %d-%d/%d', $byteOffset, $finishBytes, $fileSize);
     316
     317                header("HTTP/1.1 206 Partial content");
     318                header($cr_header);  ### Decrease by 1 on byte-length since this definition is zero-based index of bytes being sent
     319        }
     320
     321        $byteRange = $byteLength-$byteOffset;
     322
     323        header(sprintf('Content-Length: %d', $byteRange));
     324
     325        header(sprintf('Expires: %s', date('D, d M Y H:i:s', time()+60*60*24*90) . ' GMT'));
     326
     327
     328        $buffer = '';  ### Variable containing the buffer
     329        $bufferSize = 512*16; ### Just a reasonable buffer size
     330        $bytePool = $byteRange; ### Contains how much is left to read of the byteRange
     331
     332        if (!$handle = fopen($fileName, 'r')){
     333                throw new \Exception(sprintf("Could not get handle for file %s", $fileName));
     334        }
     335
     336        if (fseek($handle, $byteOffset, SEEK_SET)==-1){
     337                throw new \Exception(sprintf("Could not seek to byte offset %d", $byteOffset));
     338        }
     339
     340
     341        while ($bytePool>0){
     342                $chunkSizeRequested = min($bufferSize, $bytePool); ### How many bytes we request on this iteration
     343
     344                ### Try readin $chunkSizeRequested bytes from $handle and put data in $buffer
     345                $buffer = fread($handle, $chunkSizeRequested);
     346
     347                ### Store how many bytes were actually read
     348                $chunkSizeActual = strlen($buffer);
     349
     350                ### If we didn't get any bytes that means something unexpected has happened since $bytePool should be zero already
     351                if ($chunkSizeActual==0){
     352                        ### For production servers this should go in your php error log, since it will break the output
     353                        trigger_error('Chunksize became 0', E_USER_WARNING);
     354                        break;
     355                }
     356
     357                ### Decrease byte pool with amount of bytes that were read during this iteration
     358                $bytePool -= $chunkSizeActual;
     359
     360                ### Write the buffer to output
     361                print $buffer;
     362
     363                ### Try to output the data to the client immediately
     364                flush();
     365        }
     366
     367        exit();
    263368}
    264369
  • _plugins_/acces_restreint/trunk/paquet.xml

    r118968 r124345  
    22        prefix="accesrestreint"
    33        categorie="auteur"
    4         version="4.0.0"
     4        version="4.1.0"
    55        etat="test"
    66        compatibilite="[3.1.0;3.3.*]"
Note: See TracChangeset for help on using the changeset viewer.