Debugging AWS CloudFront Origin Requests
When I was working on improving the performance of one of our web projects, we noticed that browsers had to make an additional call before invoking the actual request due to CORS.
What is CORS — Cross-Origin Resource Shariing
CORS is a mechanism that allows a server to indicate any other origins than its own from which a browser should permit the loading of resources.
A web content origin is defined by the scheme (protocol), host (domain), and port of the URL used to access it.
http://m.domainname.com:80Scheme: http
Host: a.domainame.com
Port: 80http://api.domainname.com:80Scheme: http
Host: b.domainame.com
Port: 80So, http://m.domainname.com & http://api.domainname.com are different origin and CORS comes into play
CORS is primarily a security mechanism enforced by the server at the browser level. This allows you to make requests on your behalf and also blocks some requests made by potentially malicious JavaScripts.
In our project, we were using two different subdomains, so the browser was making prelight requests before initiating the actual request. The browser uses the OPTIONS method of HTTP preflight requests to determine if the request can be sent before sending the actual request. In other words, this prelights request determines whether or not the main request will be approved.
Preflight calls were causing performance issues in our project, so we altered the configurations on AWS CloudFront, which is in front of the base URL http://m.domainname.com so that all requests for the subdomain must go through there, and to configure CloudFront behavior to route to http://api.domainname.com on the basis of some rules defined in CloudFront behavior.
For example, to route to different kinds of origins based on the content type, based on path patterns:
- /images/s*
- /api/*
- /*
Then, after adding all these rules in CloudFront and updating the code to send all requests to http://m.domainname.com, we found that while routing requests based on behavior rules in CloudFront behavior to http://api.domainname.com, these requests kept getting declined by the origin of http://api.domainname.com, which might be due to some headers not passed or CloudFront adding some headers that we were having difficulty debugging.
CloudFront acts as an intermediary between the users and the backend servers. According to the behavior rules defined, it forwards the request to one of the origins, which then responds to the user. CloudFront transforms the request by replacing the path, changing headers, cookies, and query parameters, which makes debugging very difficult. CloudFront does not have any built-in tools to inspect and see what changes CloudFront made that resulted in requests being sent to the origin.
We could only see 400 bad requests in the origin server logs, and no helpful trace was available to debug further. In order to determine what actual requests CloudFront was receiving from the origin server, we needed any service that could provide a public endpoint with request details to monitor for that hour.
With Webhook.site, you can easily inspect, test, and automate any incoming HTTP request or email, since we were only interested in inspecting the incoming HTTP request, so this suited our purposes.
Webhook.site provides a unique public URL, which we would use to send CloudFront requests to inspect the requests.
To send all requests to webhook.site, we need to change the origin setting on CloudFront. The origin domain and path need to be changed, and since webhook.site is HTTPS, the protocol needs to be HTTPS only. After changes are done, wait for distribution deployment to complete.
Once the deployment is complete, send requests to the CloudFront domain to inspect requests which will start showing in the side panel of webhook.site which will refresh automatically to display all incoming requests.
Now we can easily debug to see the request header, query params & payload of requests to debug and fix issues, sometimes the host header is a problem where an origin hostname is passed instead of the actual hosting website as shown in the below GET request.
Let’s see an example of POST request and see all the headers & payload.
Debugging is fun when you have the right tools to work with.