Some reverse-proxy caches, CDNs, and browsers can cache redirects (e.g 301 or 302) which avoids a drupal bootstrap on the backend. However, in order for this caching to work, we need an expires or max-age header. I suggest that adding such a header be added as an option for each redirect.
see also: http://code.google.com/speed/page-speed/docs/rtt.html
In addition, according to the HTTP/1.1 specification, 301 and 302 responses can be cached by the browser. This means that even if the resource itself is not cacheable, the browser can at least look up the correct URL in its local cache. 301 responses are cacheable by default unless otherwise specified. To make a 302 response cacheable, you need to configure your web server to add an Expires or Cache-Control max-age header (see Leverage browser caching for details). The caveat here is that many browsers don't actually honor the spec, and won't cache either 301 or 302 responses; see Browserscope for a list of conforming and non-conforming browsers.
Comment | File | Size | Author |
---|---|---|---|
#4 | 1392974-4.patch | 450 bytes | pwolanin |
Comments
Comment #1
Dave ReidWe already support storing redirects in the page cache which adds its default headers into the page cache bin. I'm not sure how much we should be adding extra code to support external cache users? Maybe I just don't have a good idea of how much we need to add to support this.
Comment #2
pwolanin CreditAttribution: pwolanin commentedDave Reid tells me this should work in combination with core page cache if the setting/variable redirect_page_cache is true in combination with other settings.
Examining the code compared to core, this is not quite true.
In theory this might currently work to send the right headers the *second* time the redirect is hit if it is cached, but it will certainly not work the 1st time. Thus, if I'm using an external page cache like Varnish, the max-age header is never sent to Varnish.
I think what's missing is a call to
drupal_serve_page_from_cache($cache);
Comment #3
pwolanin CreditAttribution: pwolanin commentedHere's the suggested change per discussion in IRC
Comment #4
pwolanin CreditAttribution: pwolanin commentedComment #5
ndeschildre CreditAttribution: ndeschildre commentedEven though I haven't directly tested this patch on this module, putting these lines directly on drupal_exit (which your redirect_goto function is based on):
will give the intended behavior (Varnish now caching the redirect).
Comment #6
ndeschildre CreditAttribution: ndeschildre commentedIt seems there is a kind of conflict with the naming of functions and how they interact with external proxies:
For the SQL cache_page cache, obviously:
But in a varnish configuration:
So no problem for HTTP 200 pages for both internal and external caches, since the following code is called:
But for the 301/302 redirects with drupal_goto(), it may be cached in the internal cache (as Dave Reid seems to imply, haven't found the drupal_page_set_cache() but haven't deeply searched), but drupal_serve_page_from_cache() is definitely not called, and as a consequence it is not cached in the external cache.
I guess one solution for the core would be to add the Cache-Control= public, max-age=XX header in drupal_page_set_cache() to cover both case...
Meanwhile, for the external proxy users, here is a dirty way to cache the redirects (not to be used by SQL cache users).
Comment #7
BerdirI tested this on our environment and can confirm that redirects are now successfully cached on Varnish. Yay!
Comment #8
Dave ReidThanks everyone! I committed #4 with some additional comments to 7.x-1.x. http://drupalcode.org/project/redirect.git/commit/3e15329
Comment #10
sjancich CreditAttribution: sjancich commentedNote that the code snippet #3 can lead to 503 errors when used with Varnish.
Comment #11
Dave Reid@sjancich: Can you please file a new bug report for what you're seeing?
Comment #12
sjancich CreditAttribution: sjancich commentedSure! Sorry for the delay.
https://drupal.org/node/1928334