Running httpd(8) since quite a while, I'm missing an easy way to
configure type dependent HTTP cache-control headers. As I consider
running relayd(8) solely for that purpose kind of overkill (and I know
I'm not the only one out there who thinks that way), here is a little
proposal for cache-control headers to be defined in httpd.conf(5)...

---------------------- snip ------------------------
Index: http.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/http.h,v
retrieving revision 1.15
diff -u -p -r1.15 http.h
--- http.h      8 May 2019 21:41:06 -0000       1.15
+++ http.h      26 Oct 2019 12:53:06 -0000
@@ -208,6 +208,7 @@ struct http_mediatype {
        char            *media_name;
        char            *media_type;
        char            *media_subtype;
+       char            *media_cache;
 };
 /*
  * Some default media types based on (2014-08-04 version):
Index: httpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.107
diff -u -p -r1.107 httpd.conf.5
--- httpd.conf.5        8 May 2019 21:46:56 -0000       1.107
+++ httpd.conf.5        26 Oct 2019 12:53:06 -0000
@@ -678,7 +678,7 @@ The
 section must include one or more lines of the following syntax,
 enclosed in curly braces:
 .Bl -tag -width Ds
-.It Ar type/subtype Ar name Op Ar name ...
+.It Ar type/subtype Oo Bro Ic cache Ar string Brc Oc Ar name Oo Ar name
... Oc
 Set the media
 .Ar type
 and
@@ -686,6 +686,9 @@ and
 to the specified extension
 .Ar name .
 One or more names can be specified per line.
+If required, a
+.Ar cache
+control string may as well be specified.
 Each line may end with an optional semicolon.
 .It Ic include Ar file
 Include types definitions from an external file, for example
@@ -712,14 +715,14 @@ server "default" {
 }

 types {
-       text/css                css
-       text/html               html htm
-       text/plain              txt
-       image/gif               gif
-       image/jpeg              jpeg jpg
-       image/png               png
-       application/javascript  js
-       application/xml         xml
+       text/css                                        css
+       text/html                                       html htm
+       text/plain                                      txt
+       image/gif                                       gif
+       image/jpeg { cache "max-age=2592000, public" }        jpeg jpg
+       image/png                                       png
+       application/javascript                          js
+       application/xml                                 xml
 }
 .Ed
 .Pp
Index: httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
retrieving revision 1.145
diff -u -p -r1.145 httpd.h
--- httpd.h     8 May 2019 19:57:45 -0000       1.145
+++ httpd.h     26 Oct 2019 12:53:06 -0000
@@ -56,7 +56,8 @@
 #define HTTPD_MAX_ALIAS_IP     16
 #define HTTPD_REALM_MAX                255
 #define HTTPD_LOCATION_MAX     255
-#define HTTPD_DEFAULT_TYPE     { "bin", "application", "octet-stream", NULL }
+#define HTTPD_DEFAULT_TYPE     { \
+       "bin", "application", "octet-stream", "", NULL }
 #define HTTPD_LOGVIS           VIS_NL|VIS_TAB|VIS_CSTYLE
 #define HTTPD_TLS_CERT         "/etc/ssl/server.crt"
 #define HTTPD_TLS_KEY          "/etc/ssl/private/server.key"
@@ -88,6 +89,7 @@

 #define MEDIATYPE_NAMEMAX      128     /* file name extension */
 #define MEDIATYPE_TYPEMAX      64      /* length of type/subtype */
+#define MEDIATYPE_CACHEMAX     128     /* length of cache control */

 #define CONFIG_RELOAD          0x00
 #define CONFIG_MEDIA           0x01
@@ -453,6 +455,7 @@ struct media_type {
        char                     media_name[MEDIATYPE_NAMEMAX];
        char                     media_type[MEDIATYPE_TYPEMAX];
        char                     media_subtype[MEDIATYPE_TYPEMAX];
+       char                     media_cache[MEDIATYPE_CACHEMAX];
        char                    *media_encoding;
        RB_ENTRY(media_type)     media_entry;
 };
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.113
diff -u -p -r1.113 parse.y
--- parse.y     28 Jun 2019 13:32:47 -0000      1.113
+++ parse.y     26 Oct 2019 12:53:07 -0000
@@ -140,7 +140,7 @@ typedef struct {
 %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG
TCP TICKET
 %token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD
REQUEST
 %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE
-%token CA CLIENT CRL OPTIONAL PARAM FORWARDED
+%token CA CLIENT CRL OPTIONAL PARAM FORWARDED CACHE
 %token <v.string>        STRING
 %token  <v.number>       NUMBER
 %type  <v.port>  port
@@ -1137,7 +1137,7 @@ mediaopts_l       : mediaopts_l mediaoptsl nl
                | mediaoptsl nl
                ;

-mediaoptsl     : mediastring medianames_l optsemicolon
+mediaoptsl     : mediastring optmediacache medianames_l optsemicolon
                | include
                ;

@@ -1158,6 +1158,24 @@ mediastring      : STRING '/' STRING     {
                }
                ;

+optmediacache  : /* empty */ {
+                       *media.media_cache = '\0';
+               }
+               | '{' optnl mediacache '}'
+               ;
+
+mediacache     : CACHE STRING optnl {
+                       if (strlcpy(media.media_cache, $2,
+                           sizeof(media.media_cache)) >=
+                           sizeof(media.media_cache)) {
+                               yyerror("cache string too long");
+                               free($2);
+                               YYERROR;
+                       }
+                       free($2);
+               }
+               ;
+
 medianames_l   : medianames_l medianamesl
                | medianamesl
                ;
@@ -1285,6 +1303,7 @@ lookup(char *s)
                { "body",             BODY },
                { "buffer",           BUFFER },
                { "ca",                       CA },
+               { "cache",            CACHE },
                { "certificate",      CERTIFICATE },
                { "chroot",           CHROOT },
                { "ciphers",          CIPHERS },
@@ -1797,6 +1816,7 @@ load_config(const char *filename, struct
                        (void)strlcpy(m.media_subtype,
                            mediatypes[i].media_subtype,
                            sizeof(m.media_subtype));
+                       *m.media_cache = '\0';
                        m.media_encoding = NULL;

                        if (media_add(conf->sc_mediatypes, &m) == NULL) {
Index: server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.134
diff -u -p -r1.134 server_http.c
--- server_http.c       22 Oct 2019 09:31:23 -0000      1.134
+++ server_http.c       26 Oct 2019 12:53:07 -0000
@@ -1424,7 +1424,7 @@ server_response_http(struct client *clt,
        struct http_descriptor  *desc = clt->clt_descreq;
        struct http_descriptor  *resp = clt->clt_descresp;
        const char              *error;
-       struct kv               *ct, *cl;
+       struct kv               *ct, *cl, *cc;
        char                     tmbuf[32];

        if (desc == NULL || media == NULL ||
@@ -1460,6 +1460,12 @@ server_response_http(struct client *clt,
        if (size >= 0 && ((cl =
            kv_add(&resp->http_headers, "Content-Length", NULL)) == NULL ||
            kv_set(cl, "%lld", (long long)size) == -1))
+               return (-1);
+
+       /* Set cache control, if specified */
+       if (strlen(media->media_cache) > 0 && ((cc =
+           kv_add(&resp->http_headers, "Cache-Control", NULL)) == NULL ||
+           kv_set(cc, "%s", media->media_cache) == -1))
                return (-1);

        /* Set last modification time */
---------------------- snip ------------------------

Reply via email to