Force-Download with php on Amazon S3

后端 未结 12 1881
予麋鹿
予麋鹿 2020-12-13 07:40

I am trying to use http://code.google.com/p/amazon-s3-php-class/ to force-dowload files from AWS S3. I have an mp3 that I want people to \"play\" or \"download.\" By default

相关标签:
12条回答
  • 2020-12-13 08:05

    If you are using a library like Tarzan AWS, you can add meta headers, that amazon will include when the file is retrieved. Check out the meta parameter in the update_object function here, for example: http://tarzan-aws.com/docs/2.0/files/s3-class-php.html#AmazonS3.update_object

    0 讨论(0)
  • 2020-12-13 08:09
    <?php
        require_once __DIR__.'/vendor/autoload.php';
        use Aws\Common\Aws;
    
        function gen_url($bucket,$key,$force_download=false){
            // OR AWS Service Builder (personal method to do this)
    
    
            $config = array(
                    'key'    => '',
                    'secret' => '',
            );
    
            // Create a service builder using a configuration file
            $aws = Aws::factory($config);
    
            // Get the client from the builder by namespace
            $s3 = $aws->get('S3');
            $params = array(
                'Bucket'                        => $bucket,
                'Key'                           => $key,
                'ResponseContentType'           => 'application/octet-stream',
                'ResponseContentDisposition'    => 'attachment; filename="'.$key,
            );
    
            if($force_download){
                $params['ResponseContentType'] = 'application/octet-stream';
                $params['ResponseContentDisposition'] = 'attachment; filename="'.basename($key).'"';
            }
    
            $command = $s3->getCommand('GetObject',$params);
            return $command->createPresignedUrl('+1 days');
        }
    
        $bucket = '';
        $filename = '';
    
    
        $url = gen_url($bucket,$filename,true);
    
        echo "\n".$url."\n\n";
    

    The code above works, you just need to install the S3 composer dependency and link in the autoload file, put your key/secret into config and then supply the bucket/filename.

    0 讨论(0)
  • 2020-12-13 08:10

    Also worth mentioning is you are able to hard-set the headers for files in S3. For example, if you need to force-download a certain file you can set the appropriate headers for that file. Such as defaulting to stream, and either having a secondary file set to force-download or spend the bandwidth to use php/fputs and force-download via PHP.

    0 讨论(0)
  • 2020-12-13 08:12

    This is now possible by overwriting the S3 headers using signed requests.

    Request Parameters

    There are times when you want to override certain response header values in a GET response. For example, you might override the Content-Disposition response header value in your GET request.

    You can override values for a set of response headers using the query parameters listed in the following table.

    response-content-type - Sets the Content-Type header of the response response-content-disposition - Sets the Content-Disposition header of the response.

    Note

    You must sign the request, either using an Authorization header or a pre-signed URL, when using these parameters. They cannot be used with an unsigned (anonymous) request.

    So, you would set those headers to:

    response-content-disposition: attachment; filename=FILENAME.EXT
    response-content-type: application/octet-stream
    

    Found answer here: https://stackoverflow.com/a/5903710/922522

    0 讨论(0)
  • 2020-12-13 08:15

    Just wanting to post a contribution to this, Alex Neth is correct on this reference, but i do not feel a link is sufficient information, using amazon's own AWS PHP SDK2. Below I've outlined a basic (untested) method for calling data this way, you can use either S3 Factory Method or AWS Service Builder to make the S3 Client.

    <?php
    // S3 Factory Method
    /*use Aws\S3\S3Client;
    
    $s3= S3Client::factory(array(
        'key'    => '<aws access key>',
        'secret' => '<aws secret key>'
    ));*/
    
    // OR AWS Service Builder
    use Aws\Common\Aws;
    
    // Create a service builder using a configuration file
    $aws = Aws::factory('/path/to/my_config.json');
    
    // Get the client from the builder by namespace
    $s3 = $aws->get('S3');
    
    // Now lets create our request object.
    $command = $s3->getCommand('GetObject',array(
        'Bucket'                        => 'your-bucket-name',
        'Key'                           => 'keyname',
        'ResponseContentType'           => 'application/octet-stream',
        'ResponseContentDisposition'    => 'attachment; filename="filename.mp3',
    ));
    $url = $command->createPresignedUrl('+1 days');
    ?>
    

    You can then use PHP's header("Location: $url"); in order to redirect the visitor to the MP3 file with a force download, this should prevent it from playing in the browser, Please note, i use ResponseContentType quite frequently but I've never used ResponseContentDisposition with AWS (it should work according to the docs).

    Converting this sample into a function should be easy, you could even pass in $bucket, $key, $force_download as such

    <?php
    use Aws\Common\Aws;
    
    function gen_url($bucket,$key,$force_download=false){
        // OR AWS Service Builder (personal method to do this)
    
        // Create a service builder using a configuration file
        $aws = Aws::factory('/path/to/my_config.json');
    
        // Get the client from the builder by namespace
        $s3 = $aws->get('S3');
        $params = array(
            'Bucket'                        => $bucket,
            'Key'                           => 'keyname',
            'ResponseContentType'           => 'application/octet-stream',
            'ResponseContentDisposition'    => 'attachment; filename="filename.mp3',
        );
    
        if($force_download){
            $params['ResponseContentType'] = 'application/octet-stream';
            $params['ResponseContentDisposition'] = 'attachment; filename="'.basename($key).'"';
        }
    
        $command = $s3->getCommand('GetObject',$params);
        return $command->createPresignedUrl('+1 days');
    }
    
    // Location redirection to an MP3 force downlaod
    header("Location: ".gen_url("recordings","my-file.mp3",true));
    // Location redirection to a MP3 that lets the browser decide what to do.
    header("Location: ".gen_url("recordings","my-file.mp3"));
    
    ?>
    

    WARNING, if you haven't figured it out, this requires the AWS PHP SDK 2 currently (April 7th 2014) found here http://aws.amazon.com/sdkforphp/ This code is mostly pseudo code and may require some additional tweaking to actually make work as i'm referencing this from memory.

    0 讨论(0)
  • 2020-12-13 08:16

    Just add this to your file's metadata on s3:

    Content-Disposition: attachment; filename=FILENAME.EXT
    Content-Type: application/octet-stream
    
    0 讨论(0)
提交回复
热议问题