1

I'm trying to send JSON HTTP request from Google App Engine application and retrieve response, and while this works great locally, it suddenly breaks when I deploy it to GAE.

To be more precise, the HTTP response body that is returned to my application ends up looking like this instead of being simple JSON:

�\bD�[��8��ʖϣ�M�M$ �\\�bA` @!r���~pvk�cR]�_7E�

I did find one set of circumstances where I get correct response on GAE which might give some insight at this behavior - if the response doesn't have content-type header it goes through fine, but as soon as there is content-encoding header set to "gzip" present I get the incorrect garbage above as a response body.

Unfortunately I don't have control over the service I'm calling. So the only choice I have is to fix this somehow on my side, but to fix it I'm trying to understand the difference between what Google does to response. Does anyone know?

I understand that Google does some things to HTTP traffic. Is it forcing gzip on my responses as well?

I've also tried playing with encodings, trying to read response as utf-8, and setting utf-8 as default encoding for my GAE application as recommended here, but with no effect. I've ruled out incorrect processing of response in my code or anything I'm using, at least I think so, otherwise I'd have the same problems locally. I'm trying to understand what exactly is happening with hope that this will give me some idea how to prevent it.

EDIT: I figured it out and did a workaround but it's still a workaround, not a solution. So my GAE app calls another web service from outside GAE which sometimes gzips response and sometimes doesn't. If it does, GAE strips away content-type header from response, thus preventing my app from correctly decoding response body. My workaround so far is to get response bytes and test if response is valid JSON, unzipping it manually if it isn't. Would still want to know if stripping content-type can be prevented...

Community
  • 1
  • 1
Domchi
  • 10,705
  • 6
  • 54
  • 64

1 Answers1

0

As explained at https://cloud.google.com/appengine/kb/#compression , the application should not supply the content-encoding header: "Google App Engine does its best to serve gzipped content to browsers that support it. Taking advantage of this scheme is automatic and requires no modifications to applications".

I believe that the origin of this architecture (that content encoding is not controlled by the application side of things -- on App Engine, your application code -- but by the server/gateway side) originated with WSGI, the Python standard interface of applications to web servers/gateways (which App Engine uses on the Python runtime), but the architecture makes enough sense that we generalized it -- as the above page puts it, "This approach avoids some well-known bugs with gzipped content in popular browsers.".

The client is far from powerless, and in fact, if it so chooses, can control the content encoding -- still quoting, "To force gzipped content to be served, clients may supply 'gzip' as the value of both the Accept-Encoding and User-Agent request headers. Content will never be gzipped if no Accept-Encoding header is present.".

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Thanks for answering! Please see my edit. Not sure if I was clear enough - I'm not sending request from browser to my GAE app. I'm sending HTTP request FROM my GAE app to outside web service. The response from that webservice gets stripped of "content-encoding:gzip" header but the body is still zipped. Is this a GAE bug? – Domchi Nov 29 '15 at 02:28
  • If you're using urlfetch, as it now seems, see http://stackoverflow.com/questions/11088268/google-app-engine-urlfetch-gzip-to-string – Alex Martelli Nov 29 '15 at 04:06
  • So as I understand, basically what it suggests is what I did, unzip it manually. Wish there was a better way to find out if it's gzipped then testing the content. – Domchi Nov 30 '15 at 08:53