# SSI and expires header

**URL:** <https://www.ruby-forum.com/t/ssi-and-expires-header/220923>\
**Category:** NGINX\
**Created:** [June 25, 2012, 4:13pm UTC](https://www.ruby-forum.com/t/ssi-and-expires-header/220923 "2012-06-25T16:13:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [June 25, 2012, 4:13pm UTC](https://www.ruby-forum.com/t/ssi-and-expires-header/220923/1 "2012-06-25T16:13:35Z")

</div>

Hello,

We use SSI for serving a specific file but we want it to be cached by  
the clients for a few hours. We know SSI removes the Expires header set  
by the standard headers module so we wrote a small perl\_set sub that  
returns a proper HTTP expires date in the future which we set using the  
headers\_more module. Testing via curl -i returns and checking in the  
browser confirms the Expires header is set correctly. We also output a  
Cache-Control header.

The browser, however, doesn’t seem to cache the object so we must do  
something wrong here. I assume we also need a LastModified header but  
how can we force to send that header while SSI is on?

Thanks,  
Markus

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [June 26, 2012, 1:34pm UTC](https://www.ruby-forum.com/t/ssi-and-expires-header/220923/2 "2012-06-26T13:34:10Z")

</div>

We also tried using the Nginx sub module but this module as well strips  
away any Last-Modified header, even when we force the Last-Modified  
header with headers more using a perl\_set subroutine returning the  
proper date.

Any suggestions are very welcome 🙂  
Markus

-----Original message-----

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [July 4, 2012, 11:56am UTC](https://www.ruby-forum.com/t/ssi-and-expires-header/220923/3 "2012-07-04T11:56:54Z")

</div>

On 25/06/12, 15:12:58, “Markus J.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote  
regarding SSI and expires header:

Hello,

> We use SSI for serving a specific file but we want it to be cached  
> by the clients for a few hours. We know SSI removes the Expires  
> header set by the standard headers module so

SSI + expires works for me, example below.

> The browser, however, doesn’t seem to cache the object so we must do  
> something wrong here. I assume we also need a LastModified header  
> but how can we force to send that header while SSI is on?

```
location /ssi/ {
    ssi on;
    expires 1w;
    add_header Last-Modified 'not added';
}
location /ssi-with-last-modified/ {
    proxy_pass http://localhost/ssi/;
    proxy_set_header Host www.HOST.co.uk;
    add_header Last-Modified 'this works!';
}

```

$ curl -I [http://www.HOST.co.uk/ssi/](http://www.HOST.co.uk/ssi/)  
HTTP/1.1 200 OK  
Server: nginx/1.2.2  
Date: Wed, 04 Jul 2012 09:44:28 GMT  
Content-Type: text/html; charset=8858-1  
Connection: keep-alive  
Vary: Accept-Encoding  
Expires: Wed, 11 Jul 2012 09:44:28 GMT  
Cache-Control: max-age=604800

$ curl -I [http://www.HOST.co.uk/ssi-with-last-modified/](http://www.HOST.co.uk/ssi-with-last-modified/)  
HTTP/1.1 200 OK  
Server: nginx/1.2.2  
Date: Wed, 04 Jul 2012 09:44:38 GMT  
Content-Type: text/html; charset=8858-1  
Connection: keep-alive  
Vary: Accept-Encoding  
Vary: Accept-Encoding  
Expires: Wed, 11 Jul 2012 09:44:38 GMT  
Cache-Control: max-age=604800  
Last-Modified: this works!

James.

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [July 4, 2012, 3:10pm UTC](https://www.ruby-forum.com/t/ssi-and-expires-header/220923/4 "2012-07-04T15:10:58Z")

</div>

On Jul 4, 2012, at 5:56 AM, James Lee wrote:

> }

With this config, every request will actually cause two hits to nginx.

Last-Modified is removed from SSI in every web server I know because  
you’d really need to show the last modified time of the newest included  
element. Also, if there are dynamic elements, how do you handle those?

I did simple Lua header filter that adds the current time to  
Last-Modified when needed. Depending on which browsers you need to  
support, however, just adding Expires and/or Cache-Control headers is  
enough to get the browser to cache. I know that not all browsers behave  
correctly, however.

Something simple like:

header\_filter\_by\_lua ’  
ngx.header[“Last-Modified”] = ngx.http\_time(ngx.time())  
';

Of course, you may want to check to see if it’s already been set, only  
set if a flag is present, etc.

The “proxy to yourself” solution is unacceptable for a busy site.

–Brian

---

<div class="post-metadata">

**Author:** ![mflive](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e99b99/32.png) [@mflive](https://www.ruby-forum.com/u/mflive)\
**Post date:** [July 4, 2012, 3:48pm UTC](https://www.ruby-forum.com/t/ssi-and-expires-header/220923/5 "2012-07-04T15:48:31Z")

</div>

Thank you both for your comments.

We attempted to set the Last-Modified header because expires and  
cache-control alone did not seem to work at all, the object is still  
transferred over the wire. We even increased the expires time from two  
to six hours but different browsers still download the object. These are  
the object’s response headers:

Cache-Control:public,max-age=28800  
Connection:keep-alive  
Content-Encoding:gzip  
Content-Type:application/x-javascript; charset=utf-8  
Date:Wed, 04 Jul 2012 13:45:37 GMT  
Expires:Wed, 04 Jul 2012 21:45:37 GMT  
Transfer-Encoding:chunked

I don’t see anything really missing. Any hints to share?

Thanks!

-----Original message-----
