We've just discovered that one of Cloudfront's edge locations is returning a zero-byte file for one of our javascript assets. The invalidation is running right now, but I'm beginning to think this phenomenon may be the source of widespread but strangely un-reproducible bugs that our customers have been reporting for months now.
We're using Cloudfront with a Custom Origin (Nginx serving static files from an EC2 server). It would appear that with every deploy to our application that introduces new asset names (e.g. changed file version), we have a non-zero chance of one or more Cloudfront edge locations getting a 0-byte file.
Is there any way to avoid this?
Is there any way to detect this?
[sentiment redacted]
There is a very similar problem which has been discussed on the AWS forum. It seems to boil down to your server not sending a Content Length header with your custom origin.
Note the excerpt from the forum, which may be related:
Unfortunately your origin doesn't appear to provide a Content-Length
header. Without a Content-Length header CloudFront can't determine
that a truncated object was received and will cache it. If your origin
can send a Content-Length header any truncated objects will not be
cached. See the Developer Guide for more details.
Try adding the ContentLength header, that should do the trick.
Related
Is it possible to serve always stale/cached data from CDN edge servers like Akamai. ?
Reason is if there is some problem in origin server and It might need 2-3 days to solve it.My origin server responds properly but I don’t want it to get overloaded and want CDN to keep serving the cached data instead for sometime.
Best Regards,
Saurav
Yes, Akamai can serve stale content if the request to the origin times out or produces an error code. Here's a screen shot of the "Caching" and "Cache HTTP Error Responses" behaviors.
Note, however, that your content will need to be fairly popular to remain in cache. If it's not popular, then it may be evicted before you're able to repair your origin.
A better alternative is to implement a Site Failover ruleset which allows you to serve your page with alternate content from a separate origin, or static assets from Akamai's NetStorage. Here's a screenshot of a typical Match of a failed origin and the standard Fail Over behavior.
The "Action" field provides the following options, which can each be configured to your needs:
Serve stale content
Redirect to a different location
Use alternate hostname in this property
Use alternate hostname on provider network
Serve alternate content from NetStorage
I'm attempting to resolve an error that is preventing me from showing google-adsense ads on an amp-html site that I built and am hosting on an nginx server. I have searched and read through quite a few similar questions on Stack Overflow, Google Adsense and Amp By Example documentations.
I placed an amp-ad, per Google's instructions. The page itself loads properly, but with for whitespace where the ad should be. In the console, I get this error (twice):
Blocked a frame with origin "https://d-1234567890.ampproject.net" from accessing a frame with origin "https://example.com". Protocols, domains, and ports must match.
I recently moved the Nameservers to a new server, which now supports https instead of http. The site appears to still be verified in Adsense, but is it trying to send the ads via the wrong protocol?
Protocols must match -- seems to be the case, as both sites are https.
Domains and ports must match -- ok, but how to verify these?
Beyond this, I'm not quite sure how to troubleshoot the issue, other than blindly turning off security measures. Should I be looking at my headers (X-Frame-Options, X-Content-Type-Options, etc.)? Or my Content-Security-Policy header? Or is Google Adsense still using the old http protocol?
FWIW, I am also getting these (related) warnings in the console:
[Warning] The resource https://3p.ampproject.net/234567890/f.js was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
[Warning] The resource https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it wasn't preloaded for nothing.
Thank you in advance for your help.
I currently use Akamai as a CDN for my app, which is served over multiple subdomains.
I recently realized that Akamai is caching CORS requests the same, regardless of the origin from which they were requested.
This of course causes clients that make requests with a different Origin than the cached response to fail (since they have a different response header for Access-Control-Allow-Origin than they should)
Many suggest supplying the Vary: Origin request header to avoid this issue, but according to Akamai's docs and this Akamai community post, this isn't supported by Akamai.
How can I force Akamai to cache things uniquely by Origin if an Origin header is present in the request?
I did some research, and it appears this can be done by adding a new Rule in your Akamai config, like so:
Note that if you do this - REMEMBER - this changes your cache key at Akamai, so anything that was cached before is essentially NOT CACHED anymore! Also, as noted in the yellow warning labels, this can make it harder to force reset your cache using Akamai's url purging tools. You could remove the If block, and just include Origin header as a similar Cache ID Modification rule too, if you were ok with changing the cache key for all your content that this rule would apply to.
So in short, try this out on a small section of your site first!
More details can be found in this related post on Stack Overflow
We have hosted an API on Akamai. I had similar requirement, but we wanted to use the cached response on Akamai for all the touchpoints. But without CORS settings, it used to cache the response from first origin, and then keep it in cache, and the following requests from other touch points use to fail due to cached origin header.
We solved the problem with using API Gateway feature provided by Akamai. You can find it under API Definition. Custom cache parameters can also be defined here. Please see the screen shot for the CORS settings. Now it cached the response from backend and serve to the requester as per the allowed origin list.
CORS Setting in API Definition
I'm trying to implement content negotiation based on client Accept headers so that clients that accept image/webp get webp images while clients that don't get plain old jpeg. webp and jpeg image are served from the same url, i.e. /images/foo-image/ and the content returned varies on the Accept header presented by the client. This now works great on my site.
Next challenge is to get this working AWS CloudFront sitting in front of my site. I'm setting the Vary header to Vary: Accept to let CloudFront know that it has to cache and serve different content based on the client Accept headers.
This doesn't seem to work unfortunately, i.e. CloudFront just serves up whatever it first gets it's hands on, Vary and Accept notwithstanding. Interestingly, CloudFront does seem to be able to vary content based on Accept-Encoding (i.e. gzip).
Does anyone know what gives?
It turns out this is documented as not supposed to work:
The only acceptable value for the Vary header is Accept-Encoding. CloudFront ignores other values.
UPDATE: AWS now has support for more sophisticated content negotiation. I wrote a blog post on how to take advantage of this.
Just to update this question, CloudFront now supports caching by different headers, so you can now do this
Having recently discovered problems relating to the HTTP ETag and our CDN I've tried to capture some in Fiddler for well known sites. However it appears that whatever combination of browser / website I use I'm not seeing any pass by.
Is there any reason for this? Can you suggest a combination in which I can see them? Perhaps they're not widely used anymore?
They are definitely widely used, I've used it myself often. The most common usecase is conditional requests (always check if there's new content, but only send the content back from the server if it has changed).
However, Last-Modified can also do this instead and it's not needed if you don't force the browser to always check for new content (no must-revalidate).
The reason your CDN isn't using them is one of the following:
They are using Last-Modified instead
They don't force a revalidation and set an expiry time well in the future
They couldn't determine a ETag for a particular piece of content
Misconfiguration