5

I own a domain name my-portal.com. I want to serve a static website from my-portal.com/site/a/. I want to serve another static website from my-portal.com/site/b/.

How can I do that with resources that AWS provides?

I was trying to setup two websites as two separate S3 buckets with static website hosting enabled and then created an API Gateway with resources /site/a and /site/b configured as HTTP proxy to S3 websites.

This setup worked correctly for most of the cases. But when a browser tries to load a binary file (font, image, etc.) from my static website, the API Gateway does not properly handle that file and responds with the corrupted one (because it behaves strangely with binary files).

What other ways to achieve the same result do I have?

Girafa
  • 3,370
  • 3
  • 18
  • 33

3 Answers3

1

You can easily achieve this using AWS CloudFront. Use behaviors to select the origin based on the path. CloudFront has a built in integration to S3.

cementblocks
  • 4,326
  • 18
  • 24
  • Having a behavior pointing /site/a/* to the bucket "A", it will forward all requests to "A/site/a", so I would need to have a folder "/site/a" in my bucket "A" and "/site/b" in the bucket "B". Is there a way to point "/site/a/*" to the root of the bucket "A"? I don't want my buckets to contain that subpaths. – Girafa Jan 17 '19 at 10:30
  • @Girafa to do that path rewrite, you can use a Lambda@Edge Origin Request trigger to rewrite the paths on the back-side of CloudFront before they are sent to the buckets. Using CloudFront and one Lambda@Edge trigger together is still a lower-cost solution than API Gateway. – Michael - sqlbot Jan 17 '19 at 13:51
  • That sounds interesting. I will try. Thank you – Girafa Jan 18 '19 at 08:39
0

You can create subdomain(a and b) and use in your website

  1. my-portal.com
  2. a.my-portal.com
  3. b.my-portal.com

If you hosted your domain outside of Amazon you can either use route 53 or fwd address in CNAME.

Please read following links for detail

vaquar khan
  • 10,864
  • 5
  • 72
  • 96
  • Thanks. Basically, the reason for why I want two websites to be under the same domain is that I want to share the WebStorage among them. Having them under subdomains would break this requirement. But thanks nevertheless for your answer. – Girafa Jan 16 '19 at 17:03
  • You don't want to use nginx ? – vaquar khan Jan 16 '19 at 17:27
  • *"share the webstorage"* ... what does that mean? – Michael - sqlbot Jan 16 '19 at 22:54
  • @vaquarkhan do you mean running nginx in a Fargate container instead of using higer-level API Gateway or other resources? – Girafa Jan 17 '19 at 09:19
  • @Michael-sqlbot localStorage and sessionStorage – Girafa Jan 17 '19 at 09:19
  • Ok, I think I have found a workaround. It's possible to configure binary files mime types in API Gateway. By using \*/\* APIG treats every response as binary file. It works fine for html/js/css/images/fonts etc. But it breaks the JSON API if any. So, the only limitation in this case is to not mix JSON API with statics. – Girafa Jan 17 '19 at 09:24
  • @Girafa oh, yes, of course. I was thinking about AWS and server-side components and could not imagine what you were referring to, in that context. My mistake. Both of those are constrained to a single origin, which does indeed rule out subdomains. – Michael - sqlbot Jan 17 '19 at 13:45
  • Glad you fixed issue however if you add your question with binary compression error on API getaway or your condition why you want to use Http Proxy you will get correct answer . Best practice you can add your Answered here and mark as correct to help other who will face same issue in future. – vaquar khan Jan 17 '19 at 15:36
0

Solution #1: Use CloudFront + Lambda@Edge

CloudFront allows to configure multiple cache behaviors, routing different path patterns to a respective origins:

  • https://my-portal.com/site/a => https://bucket-a.s3-website.amazonaws.com/site/a
  • https://my-portal.com/site/b => https://bucket-b.s3-website.amazonaws.com/site/b

The only limitation is that each S3 bucket should be aware of the path and provide the same file structure within it. The bucket for the website A should contain the folder /site/a, the B bucket should contain the folder /site/b.

It's possible to overcome this limitation by using Lambda@Edge.

Solution #2: Configure Binary File Mimetypes in API Gateway

API Gateway allows to configure binary file mime types. But it requires requests to have the Accept header compatible with the mime types configured.

So, for example, if you configure a image/* as a binary mimetype in APIG, your requests for images should have Accept header with the value of image/png, image/jpg or just image/*. If the header is missing or it has some other value, APIG won't treat the response as a binary file.

The problem here is that browsers usually send Accept: */* when they try to load resources imported from CSS.

So, the only solution to this would be to configure */* as a binary mimetype. This will break all non-binary responses served by this API Gateway, like JSON ones.

Solution #3: Host binary files separately

This is a combination of the previous two approaches. You can just create a separate static website hosting and put your binary files there.

Girafa
  • 3,370
  • 3
  • 18
  • 33