aws / aws-sdk-php

Official repository of the AWS SDK for PHP (@awsforphp)
http://aws.amazon.com/sdkforphp
Apache License 2.0
6.03k stars 1.22k forks source link

Allow start time to be specified for pre-signed URLs #1208

Closed rairlie closed 7 years ago

rairlie commented 7 years ago

Aws\Signature\SignatureV4 allows creation of a pre-signed URL that expires up to 7 days from now. It would be useful if rather than assuming the validity starts now, I could specify a specific time, for example so I could create a URL that's only valid from tomorrow, or valid for 24 hours from 00:00 hrs today. This would mean the returned URL would be constant for the period specified, rather than generating an entirely unique URL every time, which would allow upstream caching.

Would there be interest in this change?

imshashank commented 7 years ago

@rairlie Please clarify is you are talking about S3 objects presigned URL.

If yes then that is the limitation of AWS S3 and the SDK just uses their API to create the presign URL. You can submit this as a feature request with the S3 team.

Please let me know if you need help with anything.

rairlie commented 7 years ago

@imshashank

I'm talking about aws-sdk-php/src/Signature/SignatureV4.php:

    public function presign(
        RequestInterface $request,
        CredentialsInterface $credentials,
        $expires
    ) {
    ...
        $httpDate = gmdate(self::ISO8601_BASIC, time());
    ...
        $parsed['query']['X-Amz-Date'] = gmdate('Ymd\THis\Z', time());

And also the method:

    private function convertExpires($expires)
    {
    ...
        $duration = $expires - time();

Notice they both use time(). This means the URL can only be generated with a start time of 'now'. I can't create one valid from yesterday or tomorrow. This seems a restriction imposed by the SDK. There's no reason to have this limitation?

What I'm proposing is changing it so time can be passed as a parameter to presign(). I've tried this locally and it works expected - would you consider a PR?

imshashank commented 7 years ago

@rairlie Sorry for the misunderstanding. Yes please send us a PR.

Thanks

imshashank commented 7 years ago

@rairlie Also I would suggest having a look at what values the AWS S3 takes.

For presign we can only provide a value of "expires-in" and that is what the PHP SDK provides.

I dont see value in providing a value which says expire 24 hours from sometime on yesterday. Also with the S3 API, there is no way to create a URL with expiration starting from tomorrow or some time in future.

http://docs.aws.amazon.com/cli/latest/reference/s3/presign.html

I hope I understood you correctly.

rairlie commented 7 years ago

@imshashank

I dont see value in providing a value which says expire 24 hours from sometime on yesterday.

My use case is: I have a web service that returns a pre-signed URL for an S3 object. I want this URL to be valid for 7 days, starting every Monday at 00:00 hrs. By being able to control the start time, the web service will return the same URL any time I call it during that week. So if I call it on Friday I'll get the same URL as when I call it on Monday. This is important because if the URL is constant it can be cached. If I can only generate URLs valid from 'now', I'll return a different URL every time, which will be a cache miss.

I can think of other use cases, but this is the one I have. So with the change in the PR, I'm able to generate constant URLs.

You're right, the s3 presign() method doesn't allow a start time to be specified, but as I don't use this method I didn't change it (I'm using S3SignatureV4 directly).

imshashank commented 7 years ago

@rairlie Thanks for the response. Please reply to the questions asked in the PR and we can then work to merge the code to the main repo.

imshashank commented 7 years ago

PR merged.