[PATCH] Add static brotli module
Eugene Kluchnikov
eustas.ru at gmail.com
Thu Feb 23 12:11:56 UTC 2017
# HG changeset patch
# User Evgenii Kliuchnikov <eustas.ru at gmail.com>
# Date 1487764873 -3600
# Wed Feb 22 13:01:13 2017 +0100
# Node ID 96939e63f30579f2f32e843d217bd46fa6086bb4
# Parent 87cf6ddb41c216876d13cffa5e637a61b159362c
Add brotli static serving support.
Both .gz and .br static content is served by
ngx_http_gzip_static_modile, but have separate configuration.
diff -r 87cf6ddb41c2 -r 96939e63f305 contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim Fri Feb 17 17:01:27 2017 +0300
+++ b/contrib/vim/syntax/nginx.vim Wed Feb 22 13:01:13 2017 +0100
@@ -86,6 +86,7 @@
syn keyword ngxDirective autoindex
syn keyword ngxDirective autoindex_exact_size
syn keyword ngxDirective autoindex_localtime
+syn keyword ngxDirective brotli_static
syn keyword ngxDirective charset
syn keyword ngxDirective charset_types
syn keyword ngxDirective chunked_transfer_encoding
diff -r 87cf6ddb41c2 -r 96939e63f305
src/http/modules/ngx_http_gzip_static_module.c
--- a/src/http/modules/ngx_http_gzip_static_module.c Fri Feb 17 17:01:27
2017 +0300
+++ b/src/http/modules/ngx_http_gzip_static_module.c Wed Feb 22 13:01:13
2017 +0100
@@ -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,13 @@
};
+static ngx_str_t encoding_gzip = ngx_string("gzip");
+static ngx_str_t encoding_brotli = ngx_string("brotli");
+
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 +110,56 @@
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);
- } else {
- /* always */
- rc = NGX_OK;
+ 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;
+ }
+ 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_gzip == NGX_HTTP_GZIP_STATIC_ON) {
+ rc = ngx_http_gzip_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 +167,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 +230,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 +285,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 +335,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 +348,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 87cf6ddb41c2 -r 96939e63f305 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Fri Feb 17 17:01:27 2017 +0300
+++ b/src/http/ngx_http_core_module.c Wed Feb 22 13:01:13 2017 +0100
@@ -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
@@ -2170,7 +2170,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;
}
@@ -2297,15 +2297,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;
@@ -2313,7 +2340,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;
}
@@ -2322,10 +2349,10 @@
break;
}
- start = p + 4;
- }
-
- p += 4;
+ start = p + n;
+ }
+
+ p += n;
while (p < last) {
switch (*p++) {
@@ -2364,7 +2391,7 @@
return NGX_DECLINED;
}
- if (ngx_http_gzip_quantity(p, last) == 0) {
+ if (ngx_http_encoding_quantity(p, last) == 0) {
return NGX_DECLINED;
}
@@ -2373,7 +2400,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 87cf6ddb41c2 -r 96939e63f305 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Fri Feb 17 17:01:27 2017 +0300
+++ b/src/http/ngx_http_core_module.h Wed Feb 22 13:01:13 2017 +0100
@@ -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
Take 2 - modify ngx_http_gzip_static_modile to serve both .gz and .br.
On 22 February 2017 at 16:10, Eugene Kluchnikov <eustas.ru at gmail.com> wrote:
> Yup. Going to try to create a "combined" module soon =)
>
> On 22 February 2017 at 15:40, Valentin V. Bartenev <vbart at nginx.com>
> wrote:
>>
>> At the first glance, the differences are really small and
>> such functionality can be combined in one module.
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20170223/93367deb/attachment-0001.html>
More information about the nginx-devel
mailing list