1
\$\begingroup\$

I have my images stored in an S3 bucket and I am serving them from AWS CloudFront. I have created 2 CNAME records for the CloudFront: mywebsite.com and www.mywebsite.com

So the image path being served from AWS CloudFront could be either of the following urls:

www.mywebsite.con/s3-folder/img-1.jpg

mywebsite.com/s3-folder/img-1.jpg

The relative image path is stored in DB, and to display the image I would add www.mywebsite.com before the path...

But then I started getting CORS (Cross Origin Request Sharing). This was when user was vising the page using: mywebsite.com url and I was building the path to the image like: www.mywebsite.com/s3-folder/img-1.jpg

To prevent this error, I built the following PhotoPathMapper, which checks the current request to see if it contains www or not and build the image url accordingly:

public static class PhotoPathMapper
{
    private static readonly string _wwwSubDomain = "www.";
    private static readonly string _fileUploadRootWithWWW;
    private static readonly string _fileUploadRootWithoutWWW;

    static PhotoPathMapper()
    {
        if (EnvironmentConfig.IsDevEnvironment)
        {
            // ignore CORS violation for DEV Environment as it runs under localhost   
            _fileUploadRootWithWWW = _fileUploadRootWithoutWWW = GlobalConfig.FileUploadRoot;
        }
        else
        {
            int indexOfWWW = GlobalConfig.FileUploadRoot.IndexOf(_wwwSubDomain, StringComparison.InvariantCultureIgnoreCase);
            if (indexOfWWW >= 0)
            {
                // build 2 website roots: https://www.mywebsite.com and https://mywebstite.com
                _fileUploadRootWithWWW = GlobalConfig.FileUploadRoot;
                _fileUploadRootWithoutWWW = GlobalConfig.FileUploadRoot.Remove(indexOfWWW, _wwwSubDomain.Length);
            }
            else
            {
                throw new Exception($"FileUploadRoot '{GlobalConfig.FileUploadRoot}' Config value should include www subdomain, e.g. use https://www.mywebsite.com instead of https://mywebsite.com");
            }
        }
    }

    public static string AddAbsoluteRootOfPhotos(string relativePath)
    {
        // check to see if current request includes www subdomain or not (i.e is it mywebsite.com or www.mywebsite.com)
        // and build the absolute path accordingly. This would prevent any CORS access violation
        if (IncludeWWWSubdomain())
        {
            return _fileUploadRootWithWWW + relativePath;
        }

        return _fileUploadRootWithoutWWW + relativePath;
    }

    public static string RemoveAbsoluteRootOfPhotos(string absolutePath)
    {
        if (!string.IsNullOrEmpty(absolutePath))
        {
            int indexOfDomainWithWWW = absolutePath.IndexOf(_fileUploadRootWithWWW);
            if (indexOfDomainWithWWW >= 0)
            {
                return absolutePath.Remove(indexOfDomainWithWWW, _fileUploadRootWithWWW.Length);
            }

            int indexOfDomainWithoutWWW = absolutePath.IndexOf(_fileUploadRootWithoutWWW);
            if (indexOfDomainWithoutWWW >= 0)
            {
                return absolutePath.Remove(indexOfDomainWithoutWWW, _fileUploadRootWithoutWWW.Length);
            }
        }

        return string.Empty;
    }

    private static bool IncludeWWWSubdomain()
    {
        if (!string.IsNullOrEmpty(HttpContext.Current.Request.Url.Host))
        {
            if (HttpContext.Current.Request.Url.Host.StartsWith(_wwwSubDomain, StringComparison.InvariantCultureIgnoreCase))
            {
                return true;
            }

            return false;
        }

        throw new Exception($"Host name is empty string.");
    }
}

This has resolved the CORS issue.

I have seen this article where they change the XMLHttpRequest and change certain permissions on S3 bucket to get around the CORS error. I am wondering if my solution is good or would it be better to follow the above article.

Appreciate any feedback about this solution.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ The real solution is to use relative addresses: /s3-folder/img-1.jpg \$\endgroup\$ – Peter Taylor Sep 25 '19 at 5:19
  • \$\begingroup\$ @PeterTaylor: thanks a lot. I have changed the FileUploadRoot to / char and everything works fine. The CORS error does not appear whether I include www in the url or not. \$\endgroup\$ – Hooman Bahreini Sep 25 '19 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.