<div dir="ltr"><div><div># HG changeset patch</div><div># User Evgenii Kliuchnikov <<a href="mailto:eustas.ru@gmail.com">eustas.ru@gmail.com</a>></div><div># Date 1491397672 -7200</div><div>#      Wed Apr 05 15:07:52 2017 +0200</div><div># Node ID 2110fbba14fa090de04de72eeb995ef9ccca4c61</div><div># Parent  29ba1d6a2da9320e68ef2b7a2516c4c424672ea8</div><div>Extend gzip_static module to serve "br" encoding.</div><div><br></div><div>Refactored encoding and quality parsing utilities to</div><div>get encoding as a parameter.</div><div><br></div><div>HG Enter commit message.  Lines beginning with 'HG:' are removed.</div><div><br></div><div>diff -r 29ba1d6a2da9 -r 2110fbba14fa contrib/vim/syntax/nginx.vim</div><div>--- a/contrib/vim/syntax/nginx.vim<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>Tue Apr 04 18:01:57 2017 +0300</div><div>+++ b/contrib/vim/syntax/nginx.vim<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>Wed Apr 05 15:07:52 2017 +0200</div><div>@@ -111,6 +111,7 @@</div><div> syn keyword ngxDirective autoindex_exact_size</div><div> syn keyword ngxDirective autoindex_format</div><div> syn keyword ngxDirective autoindex_localtime</div><div>+syn keyword ngxDirective brotli_static</div><div> syn keyword ngxDirective charset</div><div> syn keyword ngxDirective charset_map</div><div> syn keyword ngxDirective charset_types</div><div>diff -r 29ba1d6a2da9 -r 2110fbba14fa src/http/modules/ngx_http_gzip_static_module.c</div><div>--- a/src/http/modules/ngx_http_gzip_static_module.c<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>Tue Apr 04 18:01:57 2017 +0300</div><div>+++ b/src/http/modules/ngx_http_gzip_static_module.c<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>Wed Apr 05 15:07:52 2017 +0200</div><div>@@ -16,10 +16,14 @@</div><div> </div><div> </div><div> typedef struct {</div><div>-    ngx_uint_t  enable;</div><div>+    ngx_uint_t  enable_gzip;</div><div>+    ngx_uint_t  enable_brotli;</div><div> } ngx_http_gzip_static_conf_t;</div><div> </div><div> </div><div>+static ngx_int_t ngx_http_gzip_static_serve_file(ngx_http_request_t *r,</div><div>+    ngx_uint_t enable, ngx_uint_t ok, ngx_http_core_loc_conf_t *clcf,</div><div>+    ngx_str_t *encoding);</div><div> static ngx_int_t ngx_http_gzip_static_handler(ngx_http_request_t *r);</div><div> static void *ngx_http_gzip_static_create_conf(ngx_conf_t *cf);</div><div> static char *ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent,</div><div>@@ -41,7 +45,14 @@</div><div>       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,</div><div>       ngx_conf_set_enum_slot,</div><div>       NGX_HTTP_LOC_CONF_OFFSET,</div><div>-      offsetof(ngx_http_gzip_static_conf_t, enable),</div><div>+      offsetof(ngx_http_gzip_static_conf_t, enable_gzip),</div><div>+      &ngx_http_gzip_static },</div><div>+</div><div>+    { ngx_string("brotli_static"),</div><div>+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,</div><div>+      ngx_conf_set_enum_slot,</div><div>+      NGX_HTTP_LOC_CONF_OFFSET,</div><div>+      offsetof(ngx_http_gzip_static_conf_t, enable_brotli),</div><div>       &ngx_http_gzip_static },</div><div> </div><div>       ngx_null_command</div><div>@@ -79,19 +90,14 @@</div><div> };</div><div> </div><div> </div><div>+static ngx_str_t  encoding_gzip = ngx_string("gzip");</div><div>+static ngx_str_t  encoding_brotli = ngx_string("br");</div><div>+</div><div>+</div><div> static ngx_int_t</div><div> ngx_http_gzip_static_handler(ngx_http_request_t *r)</div><div> {</div><div>-    u_char                       *p;</div><div>-    size_t                        root;</div><div>-    ngx_str_t                     path;</div><div>     ngx_int_t                     rc;</div><div>-    ngx_uint_t                    level;</div><div>-    ngx_log_t                    *log;</div><div>-    ngx_buf_t                    *b;</div><div>-    ngx_chain_t                   out;</div><div>-    ngx_table_elt_t              *h;</div><div>-    ngx_open_file_info_t          of;</div><div>     ngx_http_core_loc_conf_t     *clcf;</div><div>     ngx_http_gzip_static_conf_t  *gzcf;</div><div> </div><div>@@ -105,19 +111,58 @@</div><div> </div><div>     gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);</div><div> </div><div>-    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_OFF) {</div><div>+    if (gzcf->enable_gzip == NGX_HTTP_GZIP_STATIC_OFF</div><div>+        && gzcf->enable_brotli == NGX_HTTP_GZIP_STATIC_OFF) {</div><div>         return NGX_DECLINED;</div><div>     }</div><div> </div><div>-    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {</div><div>-        rc = ngx_http_gzip_ok(r);</div><div>+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);</div><div>+</div><div>+    rc = NGX_DECLINED;</div><div>+    if (gzcf->enable_gzip != NGX_HTTP_GZIP_STATIC_OFF) {</div><div>+        if (gzcf->enable_gzip == NGX_HTTP_GZIP_STATIC_ON) {</div><div>+            rc = ngx_http_gzip_ok(r);</div><div> </div><div>-    } else {</div><div>-        /* always */</div><div>-        rc = NGX_OK;</div><div>+        } else {</div><div>+            /* always */</div><div>+            rc = NGX_OK;</div><div>+        }</div><div>+        rc = ngx_http_gzip_static_serve_file(r, gzcf->enable_gzip, rc, clcf,</div><div>+            &encoding_gzip);</div><div>     }</div><div> </div><div>-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);</div><div>+    if (gzcf->enable_brotli != NGX_HTTP_GZIP_STATIC_OFF && rc == NGX_DECLINED) {</div><div>+        if (gzcf->enable_brotli == NGX_HTTP_GZIP_STATIC_ON) {</div><div>+            rc = ngx_http_brotli_ok(r);</div><div>+        } else {</div><div>+</div><div>+            /* always */</div><div>+            rc = NGX_OK;</div><div>+        }</div><div>+        rc = ngx_http_gzip_static_serve_file(r, gzcf->enable_brotli, rc, clcf,</div><div>+            &encoding_brotli);</div><div>+    }</div><div>+</div><div>+    return rc;</div><div>+}</div><div>+</div><div>+</div><div>+static ngx_int_t</div><div>+ngx_http_gzip_static_serve_file(ngx_http_request_t *r, ngx_uint_t enable,</div><div>+    ngx_uint_t ok, ngx_http_core_loc_conf_t *clcf, ngx_str_t *encoding)</div><div>+{</div><div>+    u_char               *p;</div><div>+    size_t                root;</div><div>+    ngx_str_t             path;</div><div>+    ngx_int_t             rc;</div><div>+    ngx_uint_t            level;</div><div>+    ngx_log_t            *log;</div><div>+    ngx_buf_t            *b;</div><div>+    ngx_chain_t           out;</div><div>+    ngx_table_elt_t      *h;</div><div>+    ngx_open_file_info_t  of;</div><div>+</div><div>+    rc = ok;</div><div> </div><div>     if (!clcf->gzip_vary && rc != NGX_OK) {</div><div>         return NGX_DECLINED;</div><div>@@ -125,14 +170,14 @@</div><div> </div><div>     log = r->connection->log;</div><div> </div><div>-    p = ngx_http_map_uri_to_path(r, &path, &root, sizeof(".gz") - 1);</div><div>+    p = ngx_http_map_uri_to_path(r, &path, &root, 4 - 1);</div><div>     if (p == NULL) {</div><div>         return NGX_HTTP_INTERNAL_SERVER_ERROR;</div><div>     }</div><div> </div><div>     *p++ = '.';</div><div>-    *p++ = 'g';</div><div>-    *p++ = 'z';</div><div>+    *p++ = encoding->data[0];</div><div>+    *p++ = encoding->data[1];</div><div>     *p = '\0';</div><div> </div><div>     path.len = p - path.data;</div><div>@@ -188,7 +233,7 @@</div><div>         return NGX_DECLINED;</div><div>     }</div><div> </div><div>-    if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {</div><div>+    if (enable == NGX_HTTP_GZIP_STATIC_ON) {</div><div>         r->gzip_vary = 1;</div><div> </div><div>         if (rc != NGX_OK) {</div><div>@@ -243,7 +288,7 @@</div><div> </div><div>     h->hash = 1;</div><div>     ngx_str_set(&h->key, "Content-Encoding");</div><div>-    ngx_str_set(&h->value, "gzip");</div><div>+    h->value = *encoding;</div><div>     r->headers_out.content_encoding = h;</div><div> </div><div>     /* we need to allocate all before the header would be sent */</div><div>@@ -293,7 +338,8 @@</div><div>         return NULL;</div><div>     }</div><div> </div><div>-    conf->enable = NGX_CONF_UNSET_UINT;</div><div>+    conf->enable_gzip = NGX_CONF_UNSET_UINT;</div><div>+    conf->enable_brotli = NGX_CONF_UNSET_UINT;</div><div> </div><div>     return conf;</div><div> }</div><div>@@ -305,7 +351,9 @@</div><div>     ngx_http_gzip_static_conf_t *prev = parent;</div><div>     ngx_http_gzip_static_conf_t *conf = child;</div><div> </div><div>-    ngx_conf_merge_uint_value(conf->enable, prev->enable,</div><div>+    ngx_conf_merge_uint_value(conf->enable_gzip, prev->enable_gzip,</div><div>+                              NGX_HTTP_GZIP_STATIC_OFF);</div><div>+    ngx_conf_merge_uint_value(conf->enable_brotli, prev->enable_brotli,</div><div>                               NGX_HTTP_GZIP_STATIC_OFF);</div><div> </div><div>     return NGX_CONF_OK;</div><div>diff -r 29ba1d6a2da9 -r 2110fbba14fa src/http/ngx_http_core_module.c</div><div>--- a/src/http/ngx_http_core_module.c<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>Tue Apr 04 18:01:57 2017 +0300</div><div>+++ b/src/http/ngx_http_core_module.c<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Wed Apr 05 15:07:52 2017 +0200</div><div>@@ -74,8 +74,8 @@</div><div> static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,</div><div>     void *conf);</div><div> #if (NGX_HTTP_GZIP)</div><div>-static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);</div><div>-static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);</div><div>+static ngx_int_t ngx_http_accept_encoding(ngx_str_t *ae, char *e, size_t n);</div><div>+static ngx_uint_t ngx_http_encoding_quantity(u_char *p, u_char *last);</div><div> static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,</div><div>     void *conf);</div><div> #endif</div><div>@@ -2175,7 +2175,7 @@</div><div>      */</div><div> </div><div>     if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0</div><div>-        && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)</div><div>+        && ngx_http_accept_encoding(&ae->value, "gzip", 4) != NGX_OK)</div><div>     {</div><div>         return NGX_DECLINED;</div><div>     }</div><div>@@ -2302,15 +2302,42 @@</div><div> }</div><div> </div><div> </div><div>+ngx_int_t</div><div>+ngx_http_brotli_ok(ngx_http_request_t *r)</div><div>+{</div><div>+    ngx_table_elt_t  *ae;</div><div>+</div><div>+    if (r != r->main) {</div><div>+        return NGX_DECLINED;</div><div>+    }</div><div>+</div><div>+    ae = r->headers_in.accept_encoding;</div><div>+    if (ae == NULL) {</div><div>+        return NGX_DECLINED;</div><div>+    }</div><div>+</div><div>+    if (ae->value.len < sizeof("br") - 1) {</div><div>+        return NGX_DECLINED;</div><div>+    }</div><div>+</div><div>+    if (ngx_http_accept_encoding(&ae->value, "br", 2) != NGX_OK)</div><div>+    {</div><div>+        return NGX_DECLINED;</div><div>+    }</div><div>+</div><div>+    return NGX_OK;</div><div>+}</div><div>+</div><div>+</div><div> /*</div><div>- * gzip is enabled for the following quantities:</div><div>+ * encoding is enabled for the following quantities:</div><div>  *     "gzip; q=0.001" ... "gzip; q=1.000"</div><div>- * gzip is disabled for the following quantities:</div><div>- *     "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases</div><div>+ * encoding is disabled for the following quantities:</div><div>+ *     "br; q=0" ... "br; q=0.000", and for any invalid cases</div><div>  */</div><div> </div><div> static ngx_int_t</div><div>-ngx_http_gzip_accept_encoding(ngx_str_t *ae)</div><div>+ngx_http_accept_encoding(ngx_str_t *ae, char *e, size_t n)</div><div> {</div><div>     u_char  *p, *start, *last;</div><div> </div><div>@@ -2318,7 +2345,7 @@</div><div>     last = start + ae->len;</div><div> </div><div>     for ( ;; ) {</div><div>-        p = ngx_strcasestrn(start, "gzip", 4 - 1);</div><div>+        p = ngx_strcasestrn(start, e, n - 1);</div><div>         if (p == NULL) {</div><div>             return NGX_DECLINED;</div><div>         }</div><div>@@ -2327,10 +2354,10 @@</div><div>             break;</div><div>         }</div><div> </div><div>-        start = p + 4;</div><div>-    }</div><div>-</div><div>-    p += 4;</div><div>+        start = p + n;</div><div>+    }</div><div>+</div><div>+    p += n;</div><div> </div><div>     while (p < last) {</div><div>         switch (*p++) {</div><div>@@ -2369,7 +2396,7 @@</div><div>         return NGX_DECLINED;</div><div>     }</div><div> </div><div>-    if (ngx_http_gzip_quantity(p, last) == 0) {</div><div>+    if (ngx_http_encoding_quantity(p, last) == 0) {</div><div>         return NGX_DECLINED;</div><div>     }</div><div> </div><div>@@ -2378,7 +2405,7 @@</div><div> </div><div> </div><div> static ngx_uint_t</div><div>-ngx_http_gzip_quantity(u_char *p, u_char *last)</div><div>+ngx_http_encoding_quantity(u_char *p, u_char *last)</div><div> {</div><div>     u_char      c;</div><div>     ngx_uint_t  n, q;</div><div>diff -r 29ba1d6a2da9 -r 2110fbba14fa src/http/ngx_http_core_module.h</div><div>--- a/src/http/ngx_http_core_module.h<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>Tue Apr 04 18:01:57 2017 +0300</div><div>+++ b/src/http/ngx_http_core_module.h<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Wed Apr 05 15:07:52 2017 +0200</div><div>@@ -504,6 +504,7 @@</div><div> ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r);</div><div> #if (NGX_HTTP_GZIP)</div><div> ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r);</div><div>+ngx_int_t ngx_http_brotli_ok(ngx_http_request_t *r);</div><div> #endif</div><div> </div><div> </div></div><div><br></div><div><br></div><div><br></div></div>