The last version of AppEngine removed some usefull headers like X-APPENGINE-COUNTRY, X-APPENGINE-REGION, X-APPENGINE-CITY and X-APPENGINE-CITYLATLONG.
I liked this headers because it was an easy/free way to approximately geolocalize users. Is there an alternative or other headers to keep this simplicity ?
Thank you.
The documentation has been updated and these headers are not planned to be removed anymore:
Removed headers
Headers that match the following pattern are removed from the request:
X-Google-* In addition, some selected headers that match the following
pattern are removed from the request:
X-Appengine-* Added headers
App Engine adds the following headers to all requests:
Via: "1.1 google"
X-AppEngine-Country [...]
X-AppEngine-Region [...]
X-AppEngine-City [...]
X-AppEngine-CityLatLong [...]
X-Cloud-Trace-Context [...]
X-Forwarded-For: [...]
X-Forwarded-Proto [...]
As far as I know the headers are still there according to the Nov 16 update.
https://cloud.google.com/appengine/docs/go/how-requests-are-handled
Some standards were deprecated in order to apply the ISO standard.
Currently, the X-AppEngine-(Country|City|CityLatLong|Region) headers are not available in the flexible environment.
To clarify Nilo_DS's response, the headers are still available in the Standard environment, https://cloud.google.com/appengine/docs/python/how-requests-are-handled#app-engine-specific-headers.
https://cloud.google.com/appengine/docs/flexible/python/reference/request-headers
The docs suggest the headers can be used in flex.
I have tested a nodejs flex service and got information back for:
"x-appengine-country": "GB",
"x-appengine-region": "eng",
"x-appengine-city": "blank for security",
"x-appengine-citylatlong": "blank for security"
Related
I was looking for the specific security reasons as to why this was added. It was kind of a WTH moment when I was implementing cors and could see all the headers being returned but I couldn't access them via javascript..
CORS is implemented in such a way that it does not break assumptions made in the pre-CORS, same-origin-only world.
In the pre-CORS world, a client could trigger a cross-origin request (for example, via a script tag), but it could not read the response headers.
In order to ensure that CORS doesn't break this assumption, the CORS spec requires the server to give explicit permissions for the client to read those headers (via the Access-Control-Expose-Headers header). This way, unauthorized CORS requests behave as they did in a pre-CORS world.
Here is the reason why Access-Control-Expose-Headers is needed :
Access-Control-Expose-Headers (optional) - The XMLHttpRequest 2 object has a getResponseHeader() method that returns the value of a particular response header. During a CORS request, the getResponseHeader() method can only access simple response headers. Simple response headers are defined as follows:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
If you want clients to be able to access other headers, you have to use the Access-Control-Expose-Headers header. The value of this header is a comma-delimited list of response headers you want to expose to the client.
for more reference please dig into the link https://www.html5rocks.com/en/tutorials/cors/
Happy coding !!
This is a pretty good question. Looking through http://www.w3.org/TR/cors/#simple-response-header, it's not obvious why you would want to or need to do this.
The CORS spec puts a lot of weight into the idea that you have to have a pre-request handshake where the client asks for a type of connection and the server responds that it'll allow it - so this may just be another aspect of that.
By default content-length isn't a permitted header so I ran into the same issue (later on when I needed to access WebDAV and had to modify the allowable params).. CORS really doesn't make a lot of sense (to me) in the first place so it wouldn't surprise me if swaths of it that are capricious.
I'm testing an application on Google App Engine.
I use the Flexible environment with a custom python runtime.
In my application I need a "session.id" header on HTTP requests.
My web application code extracts the value of session.id and validates it, if it's invalid or missing the web application returns HTTP 401.
When I issue a HTTP POST to my GAE web application using curl and setting the header, e.g.:
curl -v -X POST --data "echo" -H "session.id: someweirdandlargestring" https://*****.appspot.com/echo
it seems GAE proxy removes the "session.id" header, then the web app returns 401. If I send "session.id" as a Cookie everything works fine and the server returns 200. I've debugged the application and the header does not reach the web application.
I've read the docs (https://cloud.google.com/appengine/docs/flexible/python/how-requests-are-handled) and they describe headers that are expected to be removed or added from requests before they reach our actual server. But they say:
For security purposes, some headers are sanitized or amended by intermediate proxies before they reach the application.
What makes believe me GAE is removing the HTTP header I've set.
My questions:
Is this an expected behavior from GAE?
What would you suggest to fix it? In order words: how to make my header entry to reach the web server application code?
Note that using a cookie is not an option in short term.
As #viz has suggested I've tested a header name without the dot. It works.
If I use, let's say, "sessionid", then the header reaches the server.
GAE web servers are discarding malformed http headers.
The best I've found about HTTP header conventions are on NGINX docs http://nginx.org/en/docs/http/ngx_http_core_module.html#ignore_invalid_headers:
Valid names are composed of English letters, digits, hyphens, and possibly underscores
If this can help, please let me bring this September 21 update, as I bumped intot he same issue for PHP7, which GAE was seemingly discarding my "api_secret" header for (not really RFC-ish, it is?). I deployed a little debugging tool which dumped the headers, and carried on experiments.
Outcome:
headers are forced to camel case;
apisecret became Apisecret;
api-secret became Api-Secret;
api.secret was discarded;
I finally chose X-Api-Secret, to be in line with RFC2047 recommendation for user-defined headers.
As I am running following set of the code
AngularJS
HTML
3. Error
Installing above mentioned plugin for chrome is not a permanent solution for your issue and you cannot ask the end user to do the same.
Best way to do is to handle it in your api code.
There are plenty of resources available to see how it is configured for various languages api. The following link will make you to understand about it and how to configure.
Why does my JavaScript get a “No 'Access-Control-Allow-Origin' header is present on the requested resource” error when Postman does not?
You can try below plugin in chrome browser:
Core extension
And if you want to add on server side then on server you can add below headers (for PHP add this in index.php)
header("Access-Control-Allow-Origin:*");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, X-CLIENT-ID, X-CLIENT-SECRET');
header('Access-Control-Allow-Credentials: true');
Javascript was designed to not forward from a domain to another. You're going from localhost to another domain. There is a relatively new process to do it: Cross Origin Resource Sharing or CORS. Here, the server and client agree to permit it. It's done via headers. You need a CORS header. Here is a reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
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).
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.