TylerBTybee
TylerBTybee

Reputation: 1

PHP: How to do partial content downloads from data that is not a file. E.G. data stored inside of a variable pulled from AWS S3 Bucket

In the code below: In safari where it does partial downloading. I keep getting the error:

Failed to load resource: Plug-in handled load

I get inside of the if (isset($_SERVER['HTTP_RANGE'])) branch. Error_Log Verifies this. I checked in google chrome to make sure the resource was actually being grabbed and it indeed is being grabbed and google chrome downloads the whole file inside of the else statement of the previously mentioned if statement.

What do I need to do to correct the headers? The stream is always grabbed in 1024 bytes or less due to the "->read(1024)".

$s3 = S3Client::factory([
        'version' => 'latest',
        'region' => 'A Region',
        'credentials' => [
            'key' => "A KEY",
            'secret' => "A SECRET",
        ]
    ]);

//echo "Step 4\n\n";
    
    $bucket = "bucket";
 
    $image_path = $_GET['video_path'];
    
    try {
        
        $result = $s3->getObject([
            'Bucket' => $bucket,
            'Key' => $image_path
        ]);
       

        header("Content-Type: {$result['ContentType']}");
        $fileSize = $result['ContentLength'];
       

        if (isset($_SERVER['HTTP_RANGE'])){ // do it for any device that supports byte-ranges not only iPhone
           // echo "partial";
            error_log("Error message We are good on safari in HTTP_RANGE\n", 3, "error_log");
            // Read the body off of the underlying stream in chunks
           

            header('HTTP/1.1 206 Partial Content');
            header('Accept-Ranges: bytes');
            $start = 0;
            //$theLengthOfTheNextData = mb_strlen($data, '8bit');
            header("Content-Range: bytes 0-1023/$fileSize");
            header("Content-Length: 1024");
            while ($data = $result['Body']->read(1024))
            {

                //$theLengthOfTheNextData = mb_strlen($data, '8bit');
                //it starts at zero

                //$end = $start + $theLengthOfTheNextData - 1;


                //$theLengthOfTheNextData = mb_strlen(data);
                //echo "Length: $theLengthOfTheNextData\n\n";

                //header("Content-Range: bytes $start-$end/$fileSize");
                //header("Content-Length: $theLengthOfTheNextData");
                //$start = $start + $theLengthOfTheNextData;

                // header("Content-Range: bytes $start-$end/$size");

                set_time_limit(0);
                echo $data;


                // Flush the buffer immediately
                //@ob_flush();

                flush();

            }
            //header("Content-Length: $fileSize");

             //rangeDownload($result['Body'],$fileSize);
        }
        else {
           // echo "Just entire thing";
            error_log("Error message ---- NOT good on safari in HTTP_RANGE\n", 4, "error_log");
            header("Content-Length: ".$fileSize);
            echo $result['Body'];

        }
        //echo "Step 7\n\n";
        //no need to cast as string
        // Cast as a string
        // $body = (string)$result->get('Body');
        //below should actually work too
        // $bodyAsString = (string) $result['Body'];
    } catch (S3Exception $e) {
        echo $e;
        //echo "Step 6B\n\n";
        //grabbing the file was unsuccessful
        $successfulMove = 0;
    }

Upvotes: 0

Views: 552

Answers (1)

TylerBTybee
TylerBTybee

Reputation: 1

If anyone is looking for the answer to this. You will need to utilize "registerStreamWrapper" in the S3 functions.

Reference Link

You will need to scroll down too " tedchou12 " comment. It works!!!

Upvotes: 0

Related Questions