Set `expires` by MIME type

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Set `expires` by MIME type

wld75
Hello.
I am attempting to use `expires` on Nginx 1.15.3 to define the expiry of
files on a per MIME type basis.

I have used [1] as a base, and constructed the following `map` in the `http`
section of a `include`-d `server` block (domain sanitised):

    map $sent_http_content_type $www_example_com_expires {
        default 1M;
        application/atom+xml 1h;
        application/javascript 1M;
        application/json 0s;
        application/ld+json 0s;
        application/manifest+json 1w;
        application/rdf+xml 1h;
        application/rss+xml 1h;
        application/schema+json 0s;
        application/x-javascript 1M;
        application/xml 0s;
        font/woff 1M;
        image/gif 1M;
        image/jpeg 1M;
        image/png 1M;
        image/svg+xml 1M;
        image/vnd.microsoft.icon 1M;
        image/webp 1M;
        image/x-icon 1M;
        text/cache-manifest 0s;
        text/css 1M;
        text/html 0s;
        text/javascript 1M;
        text/x-cross-domain-policy 1w;
        text/xml 0s;
        video/mp4 1M;
        video/webm 1M;
    }

Later on, after the `map` is defined, I call it using `expires` in a
`server` block:

    server {#IPv4 and IPv6, https, PHP fastcgi, check https://cipherli.st
for latest ciphers
        access_log /var/log/nginx/www.example.com.access.log ipscrubbed;
        add_header Access-Control-Allow-Origin "https://*.example.com";
        add_header Content-Security-Policy "default-src 'self'; connect-src
'self' https://api.github.com; font-src 'self'; img-src 'self' data: *
https://*; media-src 'self' * https://*; style-src 'self' 'unsafe-in$
        add_header Expect-CT "max-age=0;
report-uri=https://example.com/expect-ct-report";
        add_header Feature-Policy "camera 'self'; geolocation 'none';
microphone 'none'; midi 'none'; payment 'none'";
        add_header Referrer-Policy strict-origin;
        add_header Strict-Transport-Security "max-age=15768000;
includeSubDomains; preload";
        add_header X-Content-Type-Options nosniff;
        add_header X-Frame-Options DENY;
        add_header X-XSS-Protection "1; mode=block";
        error_log /var/log/nginx/www.example.com.error.log crit;
        etag off;
        expires $www_example_com_expires;
        index index.html index.php;
        listen [::]:443 http2 ssl;
        listen 443 http2 ssl;
        [...]
    }

My config passes the `nginx -t` self-test with no errors, and I can restart
Nginx without issue.

In the browser inspector, all MIME types are assigned a 1 month expiry, as
if they're inheriting the `default` value from the map. Example headers for
a .php file:

    Date: Mon, 03 Sep 2018 20:09:30 GMT
    Expires: Wed, 03 Oct 2018 20:09:30 GMT

If I remove the `expires` directive, the 'Expires:' header is not shown, so
`expires` is doing *something*.

I suspect my syntax is wrong, and I would be very grateful for any feedback
-- I am particularly interested a clue or pointer to aid my research into
why this is not working.

Thank you for your attention and interest.

[1] http://nginx.org/en/docs/http/ngx_http_headers_module.html#expires

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,281087,281087#msg-281087

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Set `expires` by MIME type

Richard Stanway
I recently implemented something similar, and one issue I ran in to was that $sent_http_content_type doesn't always map to a mime type. For example, "Content-Type: text/html" would match mime type text/html, but "Content-Type: text/html; charset=utf-8" would match only the default. You need to all Content-Type header variants to your map for it to work as expected, or use a regular expression.

On Mon, Sep 3, 2018 at 10:13 PM petecooper <[hidden email]> wrote:
Hello.
I am attempting to use `expires` on Nginx 1.15.3 to define the expiry of
files on a per MIME type basis.

I have used [1] as a base, and constructed the following `map` in the `http`
section of a `include`-d `server` block (domain sanitised):

    map $sent_http_content_type $www_example_com_expires {
        default 1M;
        application/atom+xml 1h;
        application/javascript 1M;
        application/json 0s;
        application/ld+json 0s;
        application/manifest+json 1w;
        application/rdf+xml 1h;
        application/rss+xml 1h;
        application/schema+json 0s;
        application/x-javascript 1M;
        application/xml 0s;
        font/woff 1M;
        image/gif 1M;
        image/jpeg 1M;
        image/png 1M;
        image/svg+xml 1M;
        image/vnd.microsoft.icon 1M;
        image/webp 1M;
        image/x-icon 1M;
        text/cache-manifest 0s;
        text/css 1M;
        text/html 0s;
        text/javascript 1M;
        text/x-cross-domain-policy 1w;
        text/xml 0s;
        video/mp4 1M;
        video/webm 1M;
    }

Later on, after the `map` is defined, I call it using `expires` in a
`server` block:

    server {#IPv4 and IPv6, https, PHP fastcgi, check https://cipherli.st
for latest ciphers
        access_log /var/log/nginx/www.example.com.access.log ipscrubbed;
        add_header Access-Control-Allow-Origin "https://*.example.com";
        add_header Content-Security-Policy "default-src 'self'; connect-src
'self' https://api.github.com; font-src 'self'; img-src 'self' data: *
https://*; media-src 'self' * https://*; style-src 'self' 'unsafe-in$
        add_header Expect-CT "max-age=0;
report-uri=https://example.com/expect-ct-report";
        add_header Feature-Policy "camera 'self'; geolocation 'none';
microphone 'none'; midi 'none'; payment 'none'";
        add_header Referrer-Policy strict-origin;
        add_header Strict-Transport-Security "max-age=15768000;
includeSubDomains; preload";
        add_header X-Content-Type-Options nosniff;
        add_header X-Frame-Options DENY;
        add_header X-XSS-Protection "1; mode=block";
        error_log /var/log/nginx/www.example.com.error.log crit;
        etag off;
        expires $www_example_com_expires;
        index index.html index.php;
        listen [::]:443 http2 ssl;
        listen 443 http2 ssl;
        [...]
    }

My config passes the `nginx -t` self-test with no errors, and I can restart
Nginx without issue.

In the browser inspector, all MIME types are assigned a 1 month expiry, as
if they're inheriting the `default` value from the map. Example headers for
a .php file:

    Date: Mon, 03 Sep 2018 20:09:30 GMT
    Expires: Wed, 03 Oct 2018 20:09:30 GMT

If I remove the `expires` directive, the 'Expires:' header is not shown, so
`expires` is doing *something*.

I suspect my syntax is wrong, and I would be very grateful for any feedback
-- I am particularly interested a clue or pointer to aid my research into
why this is not working.

Thank you for your attention and interest.

[1] http://nginx.org/en/docs/http/ngx_http_headers_module.html#expires

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,281087,281087#msg-281087

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Set `expires` by MIME type

Francis Daly
In reply to this post by wld75
On Mon, Sep 03, 2018 at 04:13:51PM -0400, petecooper wrote:

Hi there,

> I am attempting to use `expires` on Nginx 1.15.3 to define the expiry of
> files on a per MIME type basis.

It seems to work for me:

"xml" should have 0s, so now.
"rss" should have 1h.
"png" should have 1M.

$ curl -s -i http://127.0.0.1/a.xml | grep '^Content-Type\|^Expires'
Content-Type: text/xml
Expires: Tue, 04 Sep 2018 12:16:40 GMT

$ curl -s -i http://127.0.0.1/a.rss | grep '^Content-Type\|^Expires'
Content-Type: application/rss+xml
Expires: Tue, 04 Sep 2018 13:16:41 GMT

$ curl -s -i http://127.0.0.1/a.png | grep '^Content-Type\|^Expires'
Content-Type: image/png
Expires: Thu, 04 Oct 2018 12:16:42 GMT

> In the browser inspector, all MIME types are assigned a 1 month expiry, as
> if they're inheriting the `default` value from the map. Example headers for
> a .php file:
>
>     Date: Mon, 03 Sep 2018 20:09:30 GMT
>     Expires: Wed, 03 Oct 2018 20:09:30 GMT

Can you do a test like the above, and show the Content-Type that is
received as well?

"A .php file" could be anything.

Good luck with it,

        f
--
Francis Daly        [hidden email]
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Set `expires` by MIME type

wld75
Francis Daly Wrote:
-------------------------------------------------------

> It seems to work for me:
>
> "xml" should have 0s, so now.
> "rss" should have 1h.
> "png" should have 1M.
>
> $ curl -s -i http://127.0.0.1/a.xml | grep '^Content-Type\|^Expires'
> Content-Type: text/xml
> Expires: Tue, 04 Sep 2018 12:16:40 GMT
>
> $ curl -s -i http://127.0.0.1/a.rss | grep '^Content-Type\|^Expires'
> Content-Type: application/rss+xml
> Expires: Tue, 04 Sep 2018 13:16:41 GMT
>
> $ curl -s -i http://127.0.0.1/a.png | grep '^Content-Type\|^Expires'
> Content-Type: image/png
> Expires: Thu, 04 Oct 2018 12:16:42 GMT

Hello Francis - thank you very much for your sanity check, greatly
appreciated.

I stripped down and rebuilt the `map` this morning and now I'm seeing
successful caching values. I am not certain what changed, and a
before-and-after diff shows nothing of value, so I must put it down to user
error.

> Can you do a test like the above, and show the Content-Type that is
> received as well?

I confirm it's working as expected now, Content-Type and Expires is received
correctly.

Thank you for your time and attention.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,281087,281094#msg-281094

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Set `expires` by MIME type

Francis Daly
On Tue, Sep 04, 2018 at 09:41:44AM -0400, petecooper wrote:

Hi there,

> I confirm it's working as expected now, Content-Type and Expires is received
> correctly.

Great that you have it working for you now.

Cheers,

        f
--
Francis Daly        [hidden email]
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx