'accessing images from s3 in case insensitive way

I was using express in node.js where it was serving static images in a case-insensitive way, but when I moved to s3, I found that the images are case sensitive.

Is there any way in amazon s3, to serve the static files (images) in a case insensitive way ? any configuration ? otherwise, my best bet would be to convert the images to lowercase before PUT-ing them to s3.

UPDATE

Another problem, c++.jpg is not rendered by s3, it need to be converted into c%2B%2B.jpg. Whereas, c++.jpg is rendered like a charm by express. Any workaround here ?



Solution 1:[1]

It should also be noted that S3 is meant to be accessed by HTTP(S). URLs in HTTP are case-sensitive. Servers which allow accessing URLs in a case-insensitive manner are broken because they possibly pollute caches. The files image.jpg, Image.jpg, IMAGE.JPG might all point to the same file, but a cache wouldn't know and load the same file multiple times. Same for a web browser. If you refer to the same image twice on the page, once as image.jpg and once as Image.jpg, the browser would load the image twice. It therefore does not make any sense to demand that S3 should be case-insensitive. Instead stick to what the RFCs about URLs and HTTP say and fix your website.

BTW whether the underlying object store is implemented on POSIX (Unix, Linux) or Windows does not matter for this topic, it's about the HTTP and URL specs (RFCs).

Solution 2:[2]

AWS has introduced lambda edge Now.You can point the domain(hostname of s3 which you are using) to cloudfront, configure your s3 bucket as the backend and attach a lambda edge function to the cloudfront.

Select viewer request event to trigger to the lambda function.The below nodejs code in lambda will convert all the requests received by cloudfront to lowercase and pass it to the backend s3 bucket.The below code worked for me.

exports.handler = (event, context, callback) => {
    // TODO implement

   const request = event.Records[0].cf.request;
   console.log (request)
   request.uri = request.uri.toLowerCase()
   console.log (request.uri)
   callback(null, request)

};

The workflow is like below.

Request(mixedcase uri) --> cloudfront --> (Lambda function which will change uri to lower case) --> s3(the uri will be lowercase once request is received )

Solution 3:[3]

Whenever you upload a file to S3, you are creating a URL. To ensure that you are safe, you may want to evaluate the file names that you are using. RFC-Something spec for HTTP URLs only allow for the following characters to be within URLs.

RegEx

[a-zA-Z0-9_-]+

Any file name that doesn't match that pattern you may want to change in an effort to be URL compliant. AWS is CasE-SensITive primarily because it is meant as an Object Store. When persisting objects. Many times objects that are written are persisted with a base64 URL Safe encoded hash in order to create a more reliable search time for objects during retrieval.

Solution 4:[4]

Another approach is a custom error/404 html page on S3 with something like the following redirect script.

<script>
    var url = $(location).attr('href');
    url = url.toLowerCase();
    $.ajax({
        url: url,
        method: "HEAD"
    })
    .done (function() {
        window.location = url;
    })
    .fail (function() {
        window.location = '/';
    });
</script>

References:

http://aaronkenny.com/blog/case-insensitive-urls-s3-hosted-site/index.htm

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Christian Hujer
Solution 2 Haneef Mohammed
Solution 3 Matthew Hager
Solution 4 Simon Hutchison