cdn
cdn copied to clipboard
Add key prefix as a configuation option
It's not uncommon to have single s3 bucket for multiple applications, connected to a single cloudfront domain, separated just by a key prefix, example:
static.example.com/app1/assets...
static.example.com/app2/assets...
ATM there's no easy way to implement this with this very nice package thanks!
@bubenkoff thanks for raising that point. Can you please suggest a suitable solution? I haven't faced that issue before so any details you can share are much appreciated!
I'm actually facing the same sort of problem on an S3/CloudFront environment as described by @bubenkoff , where I have just one bucket, hosting multiple apps' assets. At the moment I use just one app on the CDN, so I'm good having a public folder on the bucket's root directory, but this could potentially display the package issue if I decide to use the package on the other apps since, in a Laravel environment, you most likely always push content from the public directory, potentially overwriting every apps assets.
A possible solution could be having a config variable in config/cdn.php
containing the additional folder/path (defaulting to an empty string) e.g. 'app-folder' => '',
, which will then get pushed to the AwsS3Provider
'sdefault
array.
Then, considering the way you upload the assets (get all local's, compare with server's, remove the not modified from the array), and you are using the AWS PHP SDK putObject
method, where the "destination" path is held in the Key
key, we will need to prefix the Key
key wth app-folder
if the string is not empty and the file is brand new (not available on server).
Considering this there will most likely be a bit of refactoring in the AwsS3Provider
's upload
and getFilesAlreadyOnBucket
methods as follows:
- In the
getFilesAlreadyOnBucket
method add a line after 401:$item->IsModified = true;
this way we know if the file has actually been modified instead of just created locally; - In the
upload
method change line 207 to:'Key' => ($this->default['providers']['aws']['s3']['app-folder'] !== '' && $file->IsModified !== null ? str_replace('\\', '/', $this->default['providers']['aws']['s3']['app-folder'].'/'.$file->getPathName()), : str_replace('\\', '/', $file->getPathName())
. This way we'll addapp-folder
as a prefix to the the actual local app path, so the file gets uploaded where we want. You might not want to expose the variable itself though, and access it from a getter e.g.getAppFolder
, so you could apply string transformation on it, as necessary (trim('/')
off the top of my head).
I fear though that these edits could "break stuff" (very technical term), as you are most likely not allowed to add a custom key to $item
at point 1, but is roughly my idea.
Apolgies if I've written something outrageous or haven't formatted the answer properly, but I'm very inexperienced with GitHub's issue tracker. What do you think?
@thtg88 Thanks for the details. I'm just afraid that would require too much config in the simple case where you only have one bucket per app. I always lean towards simplicity when it comes to config.
I was thinking whether Bucket
in config can be bucket-name/app1
, that should work IMO. Can you please give it a try?
@Mulkave Forgot to mention I tried that, unfortunately it throws an exception as the forward-slash '/' character gets urlencoded. I'm not at my PC right now but I can provide the Exception details if needed. thanks for your reply anyway
@thtg88 sure some more details on the exception would help. I'm also not able to try that atm.
Hi @Mulkave , apologies for the delay. You can find the exception message below:
[2016-11-19 14:38:49] local.ERROR: exception 'Aws\S3\Exception\S3Exception' with message 'Error executing "ListObjects" on "https://s3.amazonaws.com/the-s3-bucket-name%2Fthe-application-assets-subfolder-name?encoding-type=url"; AWS HTTP error: Client error: `GET https://s3.amazonaws.com/the-s3-bucket-name%2Fthe-application-assets-subfolder-name?encoding-type=url` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calcul (truncated...)
SignatureDoesNotMatch (client): The request signature we calculated does not match the signature you provided. Check your key and signing method. - <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKIAIY7T2HVCCV34ZZVA</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA256
20161119T143848Z
20161119/us-east-1/s3/aws4_request
thestringtosign-omitted</StringToSign><SignatureProvided>thsignatureprovided-omitted</SignatureProvided><StringToSignBytes>thestringtosignbytes-omitted</StringToSignBytes><CanonicalRequest>GET
/the-s3-bucket-name/the-application-assets-subfolder-name
encoding-type=url
aws-sdk-invocation-id:60f4df8826b54f3ef8e7a99eb6361085
aws-sdk-retry:0/0
host:s3.amazonaws.com
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20161119T143848Z
aws-sdk-invocation-id;aws-sdk-retry;host;x-amz-content-sha256;x-amz-date
thecanonicalrequest-omitted</CanonicalRequest><CanonicalRequestBytes>thecanonicalrequestbytes-omitted</CanonicalRequestBytes><RequestId>032C69243B67DFE1</RequestId><HostId>thehostid-omitted</HostId></Error>'
exception 'GuzzleHttp\Exception\ClientException' with message 'Client error: `GET https://s3.amazonaws.com/the-s3-bucket-name%2Fthe-application-assets-subfolder-name?encoding-type=url` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calcul (truncated...)
' in C:\Application\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php:111
Should you need any other details, please let me know. Thanks!
@Mulkave, Very actual problem! Maybe I propose PR for this?
I'm currently running into this issue. It would be good to have this feature available. The main reason is we have different branches being staged that need different CDN assets.