[PATCH] Extend gzip_static module to serve brotli content

Eugene Kluchnikov eustas.ru at gmail.com
Wed Apr 5 13:10:56 UTC 2017


# HG changeset patch
# User Evgenii Kliuchnikov <eustas.ru at gmail.com>
# Date 1491397672 -7200
#      Wed Apr 05 15:07:52 2017 +0200
# Node ID 2110fbba14fa090de04de72eeb995ef9ccca4c61
# Parent  29ba1d6a2da9320e68ef2b7a2516c4c424672ea8
Extend gzip_static module to serve "br" encoding.

Refactored encoding and quality parsing utilities to
get encoding as a parameter.

HG Enter commit message.  Lines beginning with 'HG:' are removed.

diff -r 29ba1d6a2da9 -r 2110fbba14fa contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim Tue Apr 04 18:01:57 2017 +0300
+++ b/contrib/vim/syntax/nginx.vim Wed Apr 05 15:07:52 2017 +0200
@@ -111,6 +111,7 @@
 syn keyword ngxDirective autoindex_exact_size
 syn keyword ngxDirective autoindex_format
 syn keyword ngxDirective autoindex_localtime
+syn keyword ngxDirective brotli_static
 syn keyword ngxDirective charset
 syn keyword ngxDirective charset_map
 syn keyword ngxDirective charset_types
diff -r 29ba1d6a2da9 -r 2110fbba14fa
src/http/modules/ngx_http_gzip_static_module.c
--- a/src/http/modules/ngx_http_gzip_static_module.c Tue Apr 04 18:01:57
2017 +0300
+++ b/src/http/modules/ngx_http_gzip_static_module.c Wed Apr 05 15:07:52
2017 +0200
@@ -16,10 +16,14 @@


 typedef struct {
-    ngx_uint_t  enable;
+    ngx_uint_t  enable_gzip;
+    ngx_uint_t  enable_brotli;
 } ngx_http_gzip_static_conf_t;


+static ngx_int_t ngx_http_gzip_static_serve_file(ngx_http_request_t *r,
+    ngx_uint_t enable, ngx_uint_t ok, ngx_http_core_loc_conf_t *clcf,
+    ngx_str_t *encoding);
 static ngx_int_t ngx_http_gzip_static_handler(ngx_http_request_t *r);
 static void *ngx_http_gzip_static_create_conf(ngx_conf_t *cf);
 static char *ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent,
@@ -41,7 +45,14 @@

 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_enum_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
-      offsetof(ngx_http_gzip_static_conf_t, enable),
+      offsetof(ngx_http_gzip_static_conf_t, enable_gzip),
+      &ngx_http_gzip_static },
+
+    { ngx_string("brotli_static"),
+
 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_enum_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_gzip_static_conf_t, enable_brotli),
       &ngx_http_gzip_static },

       ngx_null_command
@@ -79,19 +90,14 @@
 };


+static ngx_str_t  encoding_gzip = ngx_string("gzip");
+static ngx_str_t  encoding_brotli = ngx_string("br");
+
+
 static ngx_int_t
 ngx_http_gzip_static_handler(ngx_http_request_t *r)
 {
-    u_char                       *p;
-    size_t                        root;
-    ngx_str_t                     path;
     ngx_int_t                     rc;
-    ngx_uint_t                    level;
-    ngx_log_t                    *log;
-    ngx_buf_t                    *b;
-    ngx_chain_t                   out;
-    ngx_table_elt_t              *h;
-    ngx_open_file_info_t          of;
     ngx_http_core_loc_conf_t     *clcf;
     ngx_http_gzip_static_conf_t  *gzcf;

@@ -105,19 +111,58 @@

     gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);

-    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_OFF) {
+    if (gzcf->enable_gzip == NGX_HTTP_GZIP_STATIC_OFF
+        && gzcf->enable_brotli == NGX_HTTP_GZIP_STATIC_OFF) {
         return NGX_DECLINED;
     }

-    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {
-        rc = ngx_http_gzip_ok(r);
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    rc = NGX_DECLINED;
+    if (gzcf->enable_gzip != NGX_HTTP_GZIP_STATIC_OFF) {
+        if (gzcf->enable_gzip == NGX_HTTP_GZIP_STATIC_ON) {
+            rc = ngx_http_gzip_ok(r);

-    } else {
-        /* always */
-        rc = NGX_OK;
+        } else {
+            /* always */
+            rc = NGX_OK;
+        }
+        rc = ngx_http_gzip_static_serve_file(r, gzcf->enable_gzip, rc,
clcf,
+            &encoding_gzip);
     }

-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+    if (gzcf->enable_brotli != NGX_HTTP_GZIP_STATIC_OFF && rc ==
NGX_DECLINED) {
+        if (gzcf->enable_brotli == NGX_HTTP_GZIP_STATIC_ON) {
+            rc = ngx_http_brotli_ok(r);
+        } else {
+
+            /* always */
+            rc = NGX_OK;
+        }
+        rc = ngx_http_gzip_static_serve_file(r, gzcf->enable_brotli, rc,
clcf,
+            &encoding_brotli);
+    }
+
+    return rc;
+}
+
+
+static ngx_int_t
+ngx_http_gzip_static_serve_file(ngx_http_request_t *r, ngx_uint_t enable,
+    ngx_uint_t ok, ngx_http_core_loc_conf_t *clcf, ngx_str_t *encoding)
+{
+    u_char               *p;
+    size_t                root;
+    ngx_str_t             path;
+    ngx_int_t             rc;
+    ngx_uint_t            level;
+    ngx_log_t            *log;
+    ngx_buf_t            *b;
+    ngx_chain_t           out;
+    ngx_table_elt_t      *h;
+    ngx_open_file_info_t  of;
+
+    rc = ok;

     if (!clcf->gzip_vary && rc != NGX_OK) {
         return NGX_DECLINED;
@@ -125,14 +170,14 @@

     log = r->connection->log;

-    p = ngx_http_map_uri_to_path(r, &path, &root, sizeof(".gz") - 1);
+    p = ngx_http_map_uri_to_path(r, &path, &root, 4 - 1);
     if (p == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }

     *p++ = '.';
-    *p++ = 'g';
-    *p++ = 'z';
+    *p++ = encoding->data[0];
+    *p++ = encoding->data[1];
     *p = '\0';

     path.len = p - path.data;
@@ -188,7 +233,7 @@
         return NGX_DECLINED;
     }

-    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {
+    if (enable == NGX_HTTP_GZIP_STATIC_ON) {
         r->gzip_vary = 1;

         if (rc != NGX_OK) {
@@ -243,7 +288,7 @@

     h->hash = 1;
     ngx_str_set(&h->key, "Content-Encoding");
-    ngx_str_set(&h->value, "gzip");
+    h->value = *encoding;
     r->headers_out.content_encoding = h;

     /* we need to allocate all before the header would be sent */
@@ -293,7 +338,8 @@
         return NULL;
     }

-    conf->enable = NGX_CONF_UNSET_UINT;
+    conf->enable_gzip = NGX_CONF_UNSET_UINT;
+    conf->enable_brotli = NGX_CONF_UNSET_UINT;

     return conf;
 }
@@ -305,7 +351,9 @@
     ngx_http_gzip_static_conf_t *prev = parent;
     ngx_http_gzip_static_conf_t *conf = child;

-    ngx_conf_merge_uint_value(conf->enable, prev->enable,
+    ngx_conf_merge_uint_value(conf->enable_gzip, prev->enable_gzip,
+                              NGX_HTTP_GZIP_STATIC_OFF);
+    ngx_conf_merge_uint_value(conf->enable_brotli, prev->enable_brotli,
                               NGX_HTTP_GZIP_STATIC_OFF);

     return NGX_CONF_OK;
diff -r 29ba1d6a2da9 -r 2110fbba14fa src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Tue Apr 04 18:01:57 2017 +0300
+++ b/src/http/ngx_http_core_module.c Wed Apr 05 15:07:52 2017 +0200
@@ -74,8 +74,8 @@
 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 #if (NGX_HTTP_GZIP)
-static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);
-static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
+static ngx_int_t ngx_http_accept_encoding(ngx_str_t *ae, char *e, size_t
n);
+static ngx_uint_t ngx_http_encoding_quantity(u_char *p, u_char *last);
 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 #endif
@@ -2175,7 +2175,7 @@
      */

     if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
-        && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
+        && ngx_http_accept_encoding(&ae->value, "gzip", 4) != NGX_OK)
     {
         return NGX_DECLINED;
     }
@@ -2302,15 +2302,42 @@
 }


+ngx_int_t
+ngx_http_brotli_ok(ngx_http_request_t *r)
+{
+    ngx_table_elt_t  *ae;
+
+    if (r != r->main) {
+        return NGX_DECLINED;
+    }
+
+    ae = r->headers_in.accept_encoding;
+    if (ae == NULL) {
+        return NGX_DECLINED;
+    }
+
+    if (ae->value.len < sizeof("br") - 1) {
+        return NGX_DECLINED;
+    }
+
+    if (ngx_http_accept_encoding(&ae->value, "br", 2) != NGX_OK)
+    {
+        return NGX_DECLINED;
+    }
+
+    return NGX_OK;
+}
+
+
 /*
- * gzip is enabled for the following quantities:
+ * encoding is enabled for the following quantities:
  *     "gzip; q=0.001" ... "gzip; q=1.000"
- * gzip is disabled for the following quantities:
- *     "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
+ * encoding is disabled for the following quantities:
+ *     "br; q=0" ... "br; q=0.000", and for any invalid cases
  */

 static ngx_int_t
-ngx_http_gzip_accept_encoding(ngx_str_t *ae)
+ngx_http_accept_encoding(ngx_str_t *ae, char *e, size_t n)
 {
     u_char  *p, *start, *last;

@@ -2318,7 +2345,7 @@
     last = start + ae->len;

     for ( ;; ) {
-        p = ngx_strcasestrn(start, "gzip", 4 - 1);
+        p = ngx_strcasestrn(start, e, n - 1);
         if (p == NULL) {
             return NGX_DECLINED;
         }
@@ -2327,10 +2354,10 @@
             break;
         }

-        start = p + 4;
-    }
-
-    p += 4;
+        start = p + n;
+    }
+
+    p += n;

     while (p < last) {
         switch (*p++) {
@@ -2369,7 +2396,7 @@
         return NGX_DECLINED;
     }

-    if (ngx_http_gzip_quantity(p, last) == 0) {
+    if (ngx_http_encoding_quantity(p, last) == 0) {
         return NGX_DECLINED;
     }

@@ -2378,7 +2405,7 @@


 static ngx_uint_t
-ngx_http_gzip_quantity(u_char *p, u_char *last)
+ngx_http_encoding_quantity(u_char *p, u_char *last)
 {
     u_char      c;
     ngx_uint_t  n, q;
diff -r 29ba1d6a2da9 -r 2110fbba14fa src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Tue Apr 04 18:01:57 2017 +0300
+++ b/src/http/ngx_http_core_module.h Wed Apr 05 15:07:52 2017 +0200
@@ -504,6 +504,7 @@
 ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r);
 #if (NGX_HTTP_GZIP)
 ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r);
+ngx_int_t ngx_http_brotli_ok(ngx_http_request_t *r);
 #endif
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20170405/9c9dc7a2/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: add-brotli.patch
Type: application/octet-stream
Size: 9890 bytes
Desc: not available
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20170405/9c9dc7a2/attachment-0001.obj>


More information about the nginx-devel mailing list