GAE: Enabling Edge Cache with webapp2 (Python) - google-app-engine

There has been this new video on youtube demonstrating the strength of EdgeCaching in the GAE architecture, and at this particular point in the video they demonstrate how easy it is to leverage:
http://www.youtube.com/watch?v=QJp6hmASstQ#t=11m12
Unfortunately it's not that easy...
I'm looking to enable edge caching using the webapp2 framework provided by Google.
I'm calling:
self.response.pragma = 'Public'
self.response.cache_expires(300)
but it seems overridden by something else.
The header I get is:
HTTP/1.1 200 OK
Pragma: Public
Cache-Control: max-age=300, no-cache
Expires: Sat, 23 Feb 2013 19:15:11 GMT
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
X-AppEngine-Estimated-CPM-US-Dollars: $0.000085
X-AppEngine-Resource-Usage: ms=39 cpu_ms=64
Date: Sat, 23 Feb 2013 19:10:11 GMT
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control: no-cache, must-revalidate
Vary: Accept-Encoding
Server: Google Frontend
Content-Length: 600
I'm using ndb top level:
app = ndb.toplevel(webapp2.WSGIApplication(...
I tried the technics explained here, but they don't seem to apply to webapp2:
http://code.google.com/p/googleappengine/issues/detail?id=2258#c14
I also looked at this post too:
https://groups.google.com/d/topic/webapp2/NmHXoZZSVvo/discussion
I tried to set everything manually with no success. Something is overriding my cache settings.
Is there a way to make it work with webapp2? Any other option is welcome.
EDIT: I'm using an url with version prefix: http://version.appname.appspot.com and it's probably the cause of my problem.

This should be all you need:
self.response.cache_control = 'public'
self.response.cache_control.max_age = 300

Check Caching Details for more information, may be you broke some rules. Next the best part:
A response can be stored in Cloud CDN caches only if all of the following are true:
It was served by a backend service with caching enabled.
It was a response to a GET request.
The status code was 200, 203, 300, 301, 302, 307, or 410.
It has a Cache-Control: public directive.
It has a Cache-Control: s-maxage, Cache-Control: max-age, or Expires
header.
It has either a Content-Length header or a Transfer-Encoding header.
Additionally, there are checks that will block caching of responses. A response will not be cached if any of the following are true:
It has a Set-Cookie header.
Its body exceeds 4 MB.
It has a Vary header with a value other than Accept, Accept-Encoding, or - Origin.
It has a Cache-Control: no-store, no-cache, or private directive.
The corresponding request had a Cache-Control: no-store directive.

I'm guessing that you're mixing up two related but distinct ideas.
The first idea, which the video you link to talks about, is arranging to have certain files in your app served by a pool of App Engine servers that specialize in serving static content. This is faster than having your app serve these files, since there won't be a delay to start up a new instance of your app to serve a static file. (Strongly consider serving up your .js and .css this way.) This static serving facility is controlled entirely at app update (upload) time, via declarations you make in app.yaml (or appengine-web.xml for Java apps).
The second idea is arranging, via HTTP response headers, for pages that your app emits to be cacheable by caches outside of app engine.
If you declare files as static, you have some control over addition HTTP response headers that get served along with the file. See the documentation on configuring static files.

Related

Google App Engine : default_expiration not overriden by Cache-Control:no-cache

Hello I want to put "One Year" of cache on all files, except ìndex.html that I want Cache-Control: no-cache
But I get :
I expect the last line to override the default_expiration but i get :
cache-control: no-cache
cache-control: public, max-age=31536000
my app.yaml
runtime: nodejs12
default_expiration: '365d'
env_variables:
environment: '--prod'
handlers:
- url: /
static_files: myproject/index.html
upload: myproject/index.html
http_headers:
Cache-Control: no-cache
On the index.html.... both at the same time do you have an idea how to have only the first header ?
This is actually an expected behavior at the moment.
1) If you set default_expiration: 0 and Cache-Control: no-cache is set in the http_headers of the handlers then the following headers will be set:
cache-control: no-cache, must-revalidate
expires: Fri, 01 Jan 1990 00:00:00 GMT
2) If default_expiration is the default (10m), or a particular value is set as in your Case, '365d' and you override expiration on per-handler basis, then handlers with expiration: 0 will be served also with 10m or the value set caching. So, the output you got is actually the expected output at the moment.
I agree that 2) may be unexpected and this same concern has been raised with the App Engine team on this thread and on this issue link. It is not considered a bug at the moment, but an internal feature request was submitted to the App Engine team for necessary modifications. I suggest you bookmark the issue link for updates on the fixes as there is no ETA for the implementation at this time.

How can I store cookies on a local client that are returned from a local backend API?

I have two applications that I am running locally. A React frontend and a Flask backend. The backend handles all of the OAuth authentication and provides a bunch of end-points for the front-end.
React: http://www.local-app.com:3000/
Flask: http://www.local-app.com/
If I post to the URL http://www.local-app.com/v1/auth/login I get this response data:
Access-Control-Allow-Origin: http://www.local-app.com:3000
Connection: keep-alive
Content-Length: 2
Content-Type: text/html; charset=utf-8
Date: Fri, 08 Nov 2019 03:13:04 GMT
Server: nginx
Set-Cookie: remember_token=username|long_remember_token_here; Expires=Sat, 07-Nov-2020 03:13:04 GMT; Path=/
Set-Cookie: session=long_session_token_here; Domain=.local-app.com; Expires=Mon, 09-Dec-2019 03:13:04 GMT; HttpOnly; Path=/
Vary: Origin
This seems correct to me but the Cookie is never stored on the client no matter what I have tried.
Posting to http://www.local-app.com/v1/auth/login in postman works. The cookie is set and persisted across other end-points.
I think the problem lies with the cookie domain. I have tried setting a proxy and all sorts but nothing has worked.
Any suggestions?
The problem was due to the Flask Cors module overwriting my Nginx CORS configuration. Adding the following code to the Flask app solved the problem for me.
CORS(app, supports_credentials=True)
Thanks Selcuk for pointing me in the right direction.

AngularJs html metadata was changed by google storage

I have a plan to change the hosting of my angularJS static app from a S3 bucket to a GCS bucket. But I have some problems with the metadata of the html template files.
I have copied the files with the command gsutil and I have already set all files in the bucket with the public_read permission. Now I can access the index.html file and serve it with text/html content-type, but the template file metadata has been changed by google storage to application/xml and, when accessing it, the status code is 401.
Status Code: 401 Unauthorized
Cache-Control: private, max-age=0
Content-Length: 131
Content-Type: application/xml; charset=UTF-8
Date: Thu, 24 May 2018 03:44:21 GMT
Expires: Thu, 24 May 2018 03:44:21 GMT
Server: UploadServer
WWW-Authenticate: Bearer realm="https://accounts.google.com/"
Sometime it works and sometime it doesn't. What can I do in this situation?

Google Webmaster Tools gets 301 Redirect incorrectly

In Google Webmaster Tools, I tell Google to crawl and render my site:
Inlcuding:
http://smartnavi-app.com/download
Google shows me its HTTP Response:
HTTP/1.1 301 Moved Permanently
Date: Mon, 11 Aug 2014 07:24:56 GMT
Server: nginx/1.4.2
Connection: Keep-Alive
Content-Type: text/html;charset=UTF-8
Location: http://smartnavi-app.com/index.html
Content-Length: 0
Keep-Alive: timeout=5, max=100
But there should be NO redirect for that URL!
If I open this URL I am correctly not redirected. So why is Google?
I got it. I am using prerender.io to cache my AJAX Website for Crawler-Bots.
In the .htaccess my Domain in the prerender.io part was an old one, so there was kind of a redirect loop.
So if you change redirects etc. never forget your prerender.io stuff!

Google App Engine not generating 304, instead generating 200 always

Google App engine always generates 200 for the url /test.js and
test.js is not a static resource, but a url pattern for dynamically generated content. The content will expire after N hours and a fresh content will be generated.
I've tried with Last-Modified, ETag and Cache-Control. None seems to work.
Request
Request URL:http://localhost:8081/test.js
Request Method:GET
Status Code: 200 OK
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8081
If-Modified-Since:Fri, 18 Oct 2013 14:10:39 GMT
If-None-Match:"1B2M2Y8AsgTpgAmY7PhCfg"
Referer:http://localhost:8080/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
Response Headers
cache-control:public, max-age=360000
Content-Length:2
content-type:application/script; charset=utf-8
Date:Fri, 18 Oct 2013 14:10:40 GMT
etag:"1B2M2Y8AsgTpgAmY7PhCfg"
expires:Tue, 22 Oct 2013 18:10:40 GMT
last-modified:Fri, 18 Oct 2013 14:10:40 GMT
Server:Development/2.0
Your request has Cache-Control:max-age=0, so any intermediate caches (incl. the browser-cache) won't serve cached content. This is likely a result of a setting in your browser.
For requests with revalidate headers (If-X), you need to have the logic in place to act properly. To save bandwidth, this is pretty simple with
webob (which is used by webapp2 and other frameworks) and the conditional-response setting. Avoiding computation as well depends a little more on what you're doing, but webob helps here too.
Redbot is a really useful tool for checking HTTP cache behaviour.
Refer to this for HTTP status:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
200 is just the correct HTTP OK status, that doesn't have any interpretation on whether the resource is static or not. (Try any dynamic web page out there like e.g. facebook) and you will notice it's 200. Having a response of 200 is perfectly normal
for 304 it's "Not Modified" - As mentioned in w3 "The 304 response MUST NOT contain a message-body". This is not what you want.
In your case your concern should be to set the correct expiry time for these http header (do it within your program code), so that the browser always request for a fresh copy of content after the expiry time (e.g. after 1 hour):
cache-control:public, max-age=3600
expires:Tue, 20 Oct 2013 18:10:40 GMT

Resources