Serve html file without extension from CloudFront and S3 - amazon-s3

I read many answers to this question but for some reason neither of them works for me. I have static website served by S3 with static website feature enabled and index document set to index.html. And there is CloudFront distribution pointing to that static S3 website. In my bucket I have following files, each of them with public access:
file1.html
file2 (with Content-Type: text/html metadata)
file3/index.html
I tried visiting following pages:
https://example.com/file1.html => works
https://example.com/file2 => 404
https://example.com/file3 => 404
https://example.com/file3/index.html => works
404 response returns this:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Key>index.html</Key>
<RequestId>02KPT6454CMB1D5M0</RequestId>
<HostId>pxZgtslx4ddbSh645ZiYxlLWEg6xxGLjxlwZNO+JzjFb4eu1/kp4SYZoMFXZO7muXtZ/iJZ9g=</HostId>
</Error>
I am struggling with this for several hours and can't make it work. From what I read I should either upload (or rename through S3 console) file without extension and add Content-Type: text/html metadata to it or I should create folder named like a file without extension and put file named index.html inside. Neither of those options works.

Related

Apache - set application MIME type based on URL or directory

I have some images in my content whose url look like
http://www.example.com/sites/default/files/cdn/2014/10/08/w3V7WGRjaj5FUXx6wM5LIA4eyfmmB0grX0cIvPw2qf-O1mhQ2qwYPEHddAeVer62LLkZFrEV7fSQCxSR-J_CjPxncwLfbmjkdKNE_Gt1eENqMD5ikc9Bwl-NhSdePmjn2g
These are image files, with no extension.
They render as images on my webhost.
I moved to a different server, and currently when the same url is opened, the browser offers the image as text file for download.
I believe the application/mime type is not being set to image by the new apache server.
i tried adding a htaccess snippet as
<Directory "sites/default/cdn/*">
Header append Vary: Accept-Encoding
AddType image/png .png
</Directory>
And also tried several other combinations like giving a specific directory instead of a *, etc. But no luck so far.
Any pointers?

s3 presinged url nginx reverse proxy error - SignatureDoesNotMatch

I want to display pdf from s3 in the browser by using pdfjs - https://mozilla.github.io/pdf.js/
In place using of s3 URL, I have reverse proxy it like this
URL www.my-site-url.com/public/s3-presinged-url-bucket-part-with-sign-info
NGINX Block
location /public {
proxy_pass https://XXXX.s3.us-west-2.amazonaws.com/;
}
But S3 throws error
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
How to reverse proxy it correctly?
I ran into a similar situation when proxying to presigned S3 urls. Everything worked on development machines, but failed in production because CloudFront added additional headers which changed the signature. In my case because I already had valid presigned URLs provided headers were unmolested, I added proxy_pass_request_headers off; to make the proxy request roughly equivalent to a direct GET request.

Subfolder redirect issue with static website hosting using S3, CloudFront and Origin Path

I'm having some difficulties setting up static website hosting using Amazon S3 and Cloudfront.
We have many websites that we would like to serve as static websites using Amazon S3 + Cloudfront and we would prefer to host them all in a single S3 bucket.
Initial setup is pretty straight forward but we are having issues with sub-folder redirects if omitting trailing slash in the URL.
example, setting up a single website from the bucket:
bucket contents for website1:
s3://bucket-name/websites/website1/index.html
s3://bucket-name/websites/website1/about/index.html
I have enabled static website hosting for this bucket with default document set to 'index.html'
I have created a Cloudfront web distribution to serve this single website, default root object is set to 'index.html'.
The distribution has a custom origin pointing to the static website url 'bucket-name.s3-website-us-east-1.amazonaws.com' with Origin Path set to '/websites/website1'
When navigating to the distribution url 'http://example.cloudfront.net' it correctly serves the 'index.html' document from 's3://bucket-name/websites/website1/index.html'
When navigating to 'http://example.cloudfront.net/about/' it also correctly serves the 'index.html' document from 's3://bucket-name/websites/website1/about/index.html'
But, if I omit the trailing slash like 'http://example.cloudfront.net/about' S3 redirects me to 'http://example.cloudfront.net/websites/website1/about/', since I have Origin Path set to '/websites/website1' Cloudfront will request index.html from 's3://bucket-name/websites/website1/about/websites/website1/about/index.html' which does not exist.
Am I missing something here? Is this an impossible setup using only Cloudfront and S3?
I ended up solving it by using routing rules for the S3 bucket
https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html
the problem is the redirect caused by omitting a trailing slash results in the Orgigin Path being appended to the full S3 bucket path ("example.cloudfront.net/about" redirects to "example.cloudfront.net/websites/website1/websites/website1/about/" that fails because the path is invalid)
The below routing rule solves this by triggering on the faulty path pattern prefix and redirecting back to the Cloudfront distribution with the prefix stripped from the request, i.e ("example.cloudfront.net/about" redirects to "example.cloudfront.net/websites/website1/websites/website1/about/" that redirects to "example.cloudfront.net/about/")
The downside is that you need to remember to modify the routing rules when adding new distributions
<RoutingRules>
<RoutingRule>
<Condition>
<KeyPrefixEquals>websites/website1/websites/website1/</KeyPrefixEquals>
</Condition>
<Redirect>
<HostName>example.cloudfront.net</HostName>
<ReplaceKeyPrefixWith></ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>

S3 multiple index files

I'm using s3 with cloudfront. I have an application that has two index files.
/index
/admin/index
The /index works fine the /admin/index requires me to put /admin/index.html without including index.html it throws
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>D989FEFADF688159</RequestId>
<HostId>
GvoytrXvDOLPu26AiYYaq6Zi4ck42xyZy3mdxlSF8q5AZc4WEphayr5o6WVDxNM7+qutIAfn53k=
</HostId>
</Error>
I checked the permissions on the file they are correctly set. Additionally I can view the file when using the full url /admin/index.html.
Is this expected behavior or something wrong with my configuration of s3 / cloudfront.
I think cloudfront is the issue. It appears you can't have multiple index files when using cloud front. http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html
I ended up adding the index.html to the route to make it work.

Serving gzip content from on Amazon S3 - doesn't work with my application

I've gziped my JavaScript file using gzip and uploaded it to Amazon S3. I've set the following:
content-type: application/x-javascript
content-encoding: gzip
The file was given public permissions.
The problem that when I refer the script to the location (correct one, I've checked) of the gzipped file (with js.gzip at the end), the application doesn't run it. When I tried to view the file in Chrome browser, it tried to download the file instead of showing it.
What I'm doing wrong?
According to one answer of a similar question, there's a bug in Safari (probably Webkit) which stops proper gzip acceptance with the "wrong" file extension.
File extension shouldn't matter, but apparently Webkit screws it up. try either .jgz or .gz.js.
Try to remove:
content-type: application/x-javascript
and only use:
content-encoding: gzip
in your S3 bucket file.js file (gziped, replace .js.gz for .js only).
Now the browser request should work without any problem.