# Multiple caching solutions for anonymous and logged in users with SSI on

**URL:** <https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545>\
**Category:** NGINX\
**Created:** [March 4, 2012, 4:26pm UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545 "2012-03-04T16:26:41Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [March 4, 2012, 4:26pm UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/1 "2012-03-04T16:26:41Z")

</div>

Hi all,

I currently have a good caching solution for non-logged in users as  
shown  
below

location / {

proxy\_pass [http://localhost:82](http://localhost:82);

proxy\_set\_header Host $host;

proxy\_set\_header X-Real-IP $remote\_addr;

proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;

proxy\_set\_header Accept-Encoding “”;

proxy\_ignore\_headers Set-Cookie;

proxy\_ignore\_headers Cache-Control;

proxy\_ignore\_headers Expires;

proxy\_ignore\_headers X-Accel-Expires;

proxy\_no\_cache $cookie\_sessionid;

proxy\_cache\_bypass $cookie\_sessionid;

proxy\_cache cache;

proxy\_cache\_key $scheme$host$request\_uri;

proxy\_cache\_valid 200 302 5m;

proxy\_cache\_valid 404 1m;

proxy\_cache\_use\_stale updating;

}

But this is proving to be a lot of load when accessed by logged-in  
users(with cookie). Typically situations like homepage (collection of a  
lot  
of snippets)

So in the same location directive, _how can I apply an additional  
caching  
strategy with SSI on_(users name details which needs to be pulled up  
every  
time) for logged in users. Say cache pages for logged in users for a  
minute  
with caching for non logged in users at 15 minutes. I also want

proxy\_cache\_bypass $cookie\_sessionid;

to refresh cache entries.

I believe this is scenario for a lot of websites out there.

Can someone help please?

-Quintin

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 5, 2012, 4:21am UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/2 "2012-03-05T04:21:00Z")

</div>

Hi all,

I guess many people didn’t understand my question.

To make it simple, Can I have two caching strategies together:

one for logged in users and one for non-logged in users in the same  
location directive?

-Quintin

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 2:00am UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/3 "2012-03-06T02:00:46Z")

</div>

On 5 Mar 2012 04h20 CET, [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi all,
> 
> I guess many people didn’t understand my question.
> 
> To make it simple, Can I have two caching strategies together:
> 
> one for logged in users and one for non-logged in users in the same  
> location directive?

I think that you need two locations for each batch of users. Define  
two locations and use map to test for the session cookie. If Present  
return a 418 and use error\_page to redirect to the logged in users  
setup.

You probably can do more “dynamic” things using the embedded Lua  
module [1].

— appa

[1] [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/HttpLuaModule)

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 9:50am UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/4 "2012-03-06T09:50:31Z")

</div>

Thanks Antonio.

On a side note, if I craft a proxy cache key with cookie\_sessionid and  
if  
the sessionid cookie does not exist, _will nginx take it as an empty  
value_?

Can nginx do a try\_files or “if” on the existence of a cookie? This will  
help me deliver two caching strategies in the same location directive.

-Quintin

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 12:12pm UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/5 "2012-03-06T12:12:57Z")

</div>

Bird brain me 🙂

What does this mean?

~SESS[[:alnum:]]+=(?\<session\_id\>[[:graph:]]+) $session\_id;

Also “if” is evil inside a location. Right ?

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 11:02am UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/6 "2012-03-06T11:02:39Z")

</div>

> Thanks Antonio.
> 
> On a side note, if I craft a proxy cache key with cookie\_sessionid and if  
> the sessionid cookie does not exist, _will nginx take it as an empty  
> value_?

Sure. Here’s an example using map.

map $http\_cookie $cache\_id {  
default nil; # hommage to Lisp 🙂  
~SESS[[:alnum:]]+=(?\<session\_id\>[[:graph:]]+) $session\_id;  
}

When there’s no SESS cookie then $cache\_id is nil.

> Can nginx do a try\_files or ‘if’ on the existence of a cookie? This  
> will  
> help me deliver two caching strategies in the same location directive.

Sure. Example. At the http level:

map $http\_cookie $cookie\_exists {  
default 0;  
~ 1;  
}

On the “main” cache location:

error\_page 418 @other-cache-location;

if ($cookie\_exists) {  
return 418;  
}

Something of this kind will work.

–appa

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 12:15pm UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/7 "2012-03-06T12:15:27Z")

</div>

> Bird brain me 🙂
> 
> What does this mean?
> 
> ~SESS[[:alnum:]]+=(?\<session\_id\>[[:graph:]]+) $session\_id;
> 
> Also ‘if’ is evil inside a location. Right ?

Not really. Here it’s a mere return. From the famous IfIsEvil wiki page:

The only 100% safe things which may be done inside if in location  
context  
are:

return …;  
rewrite … last;

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 5:46pm UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/8 "2012-03-06T17:46:45Z")

</div>

On 05/03/2012 03:20, Quintin P. wrote:

> ```
> I believe this is scenario for a lot of websites out there.
> 
> ```

In theory GET is designed to be idempotent, therefore whilst it’s  
desirable to customise pages per user, you quickly get tied in knots, as  
here.

Can you  
a) Make the URLs different for logged in and non logged in users? Then  
the problem goes away. eg user sees site at [http://profile/myname](http://profile/myname) or  
whatever

b) Use client side features to customise the page, ie write the username  
to a cookie (sounds like it’s done already). Then use client side  
javascript to customise the page for each request. In this way each  
page is absolutely identical, any modifications are done client side.  
Frequently it can be designed to fail gracefully in the case of disabled  
javascript, etc

I think that whilst this has some compromises, if you can accept those  
then you end up with a MUCH simpler application and simpler caching?

Good luck

Ed W

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 7:15pm UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/9 "2012-03-06T19:15:05Z")

</div>

06 марта 2012, 14:02 от “Antonio P.P. Almeida” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> ~SESS[[:alnum:]]+=(?<session_id>[[:graph:]]+) $session_id;
> 
> ```
> 
> map $http\_cookie $cookie\_exists {  
> }  
> What a load of… unnecessary directives! This does the job  
> much more efficiently and cleanly:

```
server {

    if ($cookie_sessionid) {
        rewrite ^ /logged_in$request_uri last;
    }

    location / {
        # Non-logged in clients
        #...
    }

    location /logged_in {
        # Logged in clients

        internal;

        proxy_cache_key $cookie_sessionid$scheme$host$request_uri;

        proxy_pass http://localhost:82/; # Note the trailing slash
        #...
    }
}

```

Max

---

<div class="post-metadata">

**Author:** ![Quintin\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/13edae/32.png) [@Quintin\_P](https://www.ruby-forum.com/u/Quintin_P)\
**Post date:** [March 6, 2012, 6:54pm UTC](https://www.ruby-forum.com/t/multiple-caching-solutions-for-anonymous-and-logged-in-users-with-ssi-on/217545/10 "2012-03-06T18:54:30Z")

</div>

06 марта 2012, 14:02 от “Antonio P.P. Almeida” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
