No Content-Length field in the HTTP response header (google app engine) - google-app-engine

Content-Length header is missing when I try to download rar, exe, msi static files, though response for images contains Content-Length, but if I change rar extension to jpg it doesn't.
How do I solve this?

What headers do you see? It's possible it's being served using Transfer-Encoding: Chunked, which is a perfectly legitimate way of transferring responses over HTTP.
Also, how are you serving the file - using static files, your code, or the blobstore?

I tried serving a copy of http://googleappengine.googlecode.com/files/GoogleAppEngine_1.3.4.msi as a static fileand experienced the same issue - GAE's response did not include a Content-Length header.
Workaround: If the Content-Length header is critical, then consider hosting your static msi (etc.) file types on a file hosting site (e.g., Dropbox for now.
Edit: This is the intended behavior after all - Nick points out that the files are being transferred with the Transfer-Encoding: Chunked header.

Related

Understanding formation of Request Headers

I am running a NextJS application, and I observed that JavaScript resources are not getting gzipped on mobile (on desktop it works fine). On further debugging, I found that this is because the Request Headers in mobile are not sending the Accept-Encoding header. These JS files are basically chunks (bundles of JS code) downloaded using a <script> tag. Now I understand that there is no way to add Request Headers to a <script> tag, but I can see that the Accept-Encoding headers are present when running the app in desktop resolution.
So I want to understand where are these Request Headers (specifically Accept-Encoding) added to outgoing JavaScript file requests? Is it automatically added by the browser when making a request, or added by NextJS, or WebPack (embedding it when sending the html page for the first time to client)? And how can I fix this issue? Note that I observe this behaviour even on my local machine running on localhost:3000.
That header is set by the client and it is used to tell the server what kind of content encoding ( compressions algorithm ) it can understand, so basically the client will get the gzipped files if it declares that it can accept them, and the server is able to serve them (nextjs has gzip compression on by default).
Mdn Docs Accept-Encoding
Next.js Docs gzip

Should I enable Gzip on Nginx server with SSL for a react app?

I have a react app with a pretty large build size, it is deployed on an Nginx server with SSL. I learned a bit about GZip and how it can improve the site's performance. But I also came to know that it is not to safe to use GZip with SSL.
GZip is enabled for HTML files by default in Nginx. Should I enable it for other files like Javascript and CSS as well to improve performance ?
When you say
it is not to safe to use GZip with SSL
i assume that you are talking about Breach Attack. Well for breach attack to be successful for the compressed response, two conditions need to be satisfied:
Reflect user-input in HTTP response bodies
Reflect a secret (such as a CSRF token) in HTTP response bodies
When you send compressed js/css files in response, you usually do not reflect user-input in the response. That means calling the js/css file url will only return that file.
Also you usually do not return any sensitive data in the response along with compressed js/css files.
So yeah it is completely safe to use Gzip compression for js/css assets. Static responses are not vulnerable to this attack.

Access-Control-Allow-Origin Issue with API

I have written a pretty simple API in PHP and am running it as a service (https://protoapi-dot-rehash-148415.appspot.com/events/).
When I try to load a data grid with the JSON from the API, I am getting the dreaded "No 'Access-Control-Allow-Origin' header is present on the requested resource." error on the page on which I want to consume the JSON. (http://proto-angular-dot-rehash-148415.appspot.com/events.php)
I've tried a couple of different methods to add Access-Control-Allow-Origin: "*" to the app.yaml file and to the header in the PHP file that produces the API. I think it doesn't work in the yaml because you cannot apply http_headers to dynamic files, and it doesn't work in the file because of the compression.
Is there any other way to make this work, short of putting the API and the app in the same service? I'd hate to do that because I am using mod_rewrite for the API and it will probably cause chaos on my app.
Any insights would be greatly appreciated!
-Mike
The header won't do any good unless you add it server-side, on the events API. The server is what dictates CORS permissions. You could send it messages or files all day with the right headers at the top and it will just ignore them. The allow-origin header has to come from the server to allow the cross-origin resource sharing (CORS) to take place.
I would recommend prepending the header in the function that offers up the API or handles the requests. Your events API spits out a lot of JSON. Right before that JSON, have your API spit out the header Access-Control-Allow-Origin: * and you should be all set.
As a sanity check you can also try adding Access-Control-Allow-Headers: Content-Type and see if that helps. Based on your comment about the Content-Type header, this may be part of the problem. It should be added the same way as the other one; have your API send it prior to your events JSON on its own line (put a \n to make a new line inside the string literal).

Returning Gzip-ed response bodies on App Engine

When caching item in App Engine's memcache I used gzip compression to save space and get below the 1MB limit for some files.
Since I also put rendered pages into the memcache, I though it would be nice and much quicker to directly return the gzipped body to the client, if it accepts gzip encdoing.
Unfortunately the request's Accept-Encoding only has the value identity (using the AE dev server with Go), which to me means I have to return the body as-is (i.e. plain html).
Is one not supposed to gzip contents themselves? Or could I always return gzipped content with the appropriate headers, and the AE infrastructure would decompress this when the client does not support compression?
After all I hope to get even better response times by caching the response in its output state.
For caching the response, if your response is public (same copy for all users), you can make use of Google's edge cache by setting the proper HTTP headers, for example:
Cache-Control: public,max-age=86400
Expires: Sat, 16 May 2015 07:23:15 +0000
About compression, as far as I know, Google automatically compress the content in HTTP response whenever possible. There is no need to handle this manually.

App Engine Accept-Encoding

In the APP Engine API, it is mentioned that, if the request comes with "Accept-Encoding" set, then it will automatically compress the response.
But when I look at the request, the header is not there. but at the browser, it is set. when I try to explicitly set the header(with JQuery ajax function), there is a message:
Refused to set unsafe header "Accept-Encoding"
But this situation is not occurring when working in local host - request has the "Accept-Encoding" header. this happens only after publishing. but not allowing to set the "Accept-Encoding" explicitly happens always.
I searched everywhere, but couldn't find a explanation to the problem. It would be really helpful if someone can explain...
You have two different problems:
App Engine does not compress reply. GAE uses a number of factors to determine if response needs to be compressed. It takes content type and user agent into account when deciding. See the answer by Nick Johnson (from GAE team).
jQuery refuses to set "Accept-Encoding" header. Note that this is a jQuery issue and has nothing to do with GAE. See this: Is it possible to force jQuery to make AJAX calls for URLs with gzip/deflate enabled?
I have a similar problem as in the HTTPRequest header, "Accept-Encoding" is null. As GAE has explained it looks for Accept-Encoding and User-Agent headers, if it wants to compress. but in my case there is no way the GAE can recognize whether to compress.
From the browser, then header is set, but in the request header, it is not.

Resources