Filter out headers for fastcgi cache

Greetings,

I would like to propose that an additional feature for nginx be
considered related to fastcgi caching: the ability to specify headers
that will not be stored in cache, but will be sent to the client when
the cached version is created (sent to the client responsible for
creating the cached copy). If some solution already exists providing
this functionality, my apologies, I was not able to track one down -
currently assuming one does not exist.

Here is one scenario where such an option would be useful (I am sure
there are others):

A typical scenario where fastcgi caching can be employed for performance
benefits is when the default version of a page is loaded. By “default”,
I mean the client has no prior session data which might result in unique
session specific request elements. In the case of PHP, the presence of
session data is typically determined by checking for the presence of a
“PHPSESSID” cookie. So if this cookie does not exist, then it can be
assumed there is no session - an optimal time to create a cached version
of the page in many scenarios. However, many PHP apps/sites/etc. also
create a session in the event one does not exist (a behavior I assume is
not specific to PHP) - meaning the the response typically contains a
Set-Cookie: PHPSESSID… header. Nginx’s default behavior is not to
cache any page with a Set-Cookie header, and that makes sense as a
default - but lets assume for this example that fastcgi_ignore_headers
Set-Cookie; is in effect and the cached version of the default version
of the page gets created. The problem here is that the cached version
created also has the Set-Cookie header cached as well - which causes
problems for obvious reasons (hands out the same session ID/cookie for
all users). Ideally, we could specify to cache everything except the
specified headers - Set-Cookie in this example.

Am I the only one who would find this option useful or are there others?

If this would be found to be useful by others and there is consensus
that such an addition is called for by those with the resources to
implement it, I am not sure if it makes sense to strip the headers prior
storage in cache or when reading from cache - probably whichever is
easier.

Thoughts?
Michael

On 9 Fev 2012 23h37 WET, [email protected] wrote:

Here is one scenario where such an option would be useful (I am sure
many scenarios. However, many PHP apps/sites/etc. also create a
Ideally, we could specify to cache everything except the specified

Thoughts?
Michael

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass_header

Also, you can capture the session ID and use it in
fastcgi_cache_key. Like this, for example:

Set a cache_uid variable for authenticated users.

map $http_cookie $cache_uid {
default nil; # hommage to Lisp :slight_smile:
~SESS[[:alnum:]]+=(?<session_id>[[:alnum:]]+) $session_id;
}

fastcgi_cache_key $cache_uid@$host$request_uri;

— appa

Antnio P. P. Almeida wrote, On 02/09/2012 04:45 PM:

track one down - currently assuming one does not exist.
if this cookie does not exist, then it can be assumed there is no
Set-Cookie header cached as well - which causes problems for obvious
prior storage in cache or when reading from cache - probably
map $http_cookie $cache_uid {
default nil; # hommage to Lisp :slight_smile:
~SESS[[:alnum:]]+=(?<session_id>[[:alnum:]]+) $session_id;
}

fastcgi_cache_key $cache_uid@$host$request_uri;

— appa

How does fastcgi_pass_header help in this instance? From the docs, that
directive “explicitly allows to pass named headers to the client.” In
the example, I need to drop the Set-Cookie header from the cached copy.

As far as setting up cache files for each session, that is less useful
for me (but a cool feature). The main benefit in caching for me is for
users that are not logged in (or doing anything that modifies site
content) since they represent around 75% of page loads and there is no
user specific variance in the pages themselves. I would suspect many
other sites follow a similar usage pattern.

Max wrote, On 02/10/2012 03:54 PM:

when passing cached content back to clients

proxy_hide_header Set-Cookie;

You could also include session cookies in the fastcgi_cache_key
to make sure new users get the default cached content, while
everyone else gets their session-specific cached content:

fastcgi_cache_key
“$cookie_PHPSESSID$scheme$request_method$host$server_port$request_uri”;

Max

Thanks Max!

14 февраля 2012, 22:48 от Michael McCallister
[email protected]:

Strip the Set-Cookie header from cached content

Max

Thanks Max!

You’re welcome! Just run s/proxy_/fastcgi_/ on the above to get
the fastcgi directives. Those directives are the same in all of
the (fastcgi|proxy|scgi|uwsgi) modules:

(fastcgi|proxy|scgi|uwsgi)_ignore_headers
http://wiki.nginx.org/NginxHttpFcgiModule#fastcgi_ignore_headers

(fastcgi|proxy|scgi|uwsgi)_hide_header
http://wiki.nginx.org/NginxHttpFcgiModule#fastcgi_hide_header

Max

10 февраля 2012, 03:39 от Michael McCallister
[email protected]:

Here is one scenario where such an option would be useful (I am sure
create a session in the event one does not exist (a behavior I assume is

Am I the only one who would find this option useful or are there others?

If this would be found to be useful by others and there is consensus
that such an addition is called for by those with the resources to
implement it, I am not sure if it makes sense to strip the headers prior
storage in cache or when reading from cache - probably whichever is easier.

Thoughts?

http://wiki.nginx.org/NginxHttpProxyModule#proxy_hide_header

The proxy_hide_header directive does exactly what you described,
the cookies get stored in the cache, but they are not passed back
to the client, so this is all you’d need:

Cache responses containing the Set-Cookie header as well

fastcgi_ignore_headers Set-Cookie;

Strip the Set-Cookie header from cached content

when passing cached content back to clients

proxy_hide_header Set-Cookie;

You could also include session cookies in the fastcgi_cache_key
to make sure new users get the default cached content, while
everyone else gets their session-specific cached content:

fastcgi_cache_key
“$cookie_PHPSESSID$scheme$request_method$host$server_port$request_uri”;

Max