# HG changeset patch
# User Evgenii Kliuchnikov <eustas.ru@gmail.com>
# Date 1487932524 -3600
# Fri Feb 24 11:35:24 2017 +0100
# Node ID 662115ad250f48cfdd7963de40bfe7c7c8ae8ba3
# Parent 1ad0999a7ded3d4fb01c7acf8ff57c80b643da7e
Add brotli static serving support (ontoZZ 1.11.10)
Both .gz and .br static content is served by
ngx_http_gzip_static_modile, but have separate configuration.
diff -r 1ad0999a7ded -r 662115ad250f contrib/vim/syntax/nginx.vim
|
a
|
b
|
|
| 86 | 86 | syn keyword ngxDirective autoindex |
| 87 | 87 | syn keyword ngxDirective autoindex_exact_size |
| 88 | 88 | syn keyword ngxDirective autoindex_localtime |
| | 89 | syn keyword ngxDirective brotli_static |
| 89 | 90 | syn keyword ngxDirective charset |
| 90 | 91 | syn keyword ngxDirective charset_types |
| 91 | 92 | syn keyword ngxDirective chunked_transfer_encoding |
diff -r 1ad0999a7ded -r 662115ad250f src/http/modules/ngx_http_gzip_static_module.c
|
a
|
b
|
|
| 16 | 16 | |
| 17 | 17 | |
| 18 | 18 | typedef struct { |
| 19 | | ngx_uint_t enable; |
| | 19 | ngx_uint_t enable_gzip; |
| | 20 | ngx_uint_t enable_brotli; |
| 20 | 21 | } ngx_http_gzip_static_conf_t; |
| 21 | 22 | |
| 22 | 23 | |
| | 24 | static ngx_int_t ngx_http_gzip_static_serve_file(ngx_http_request_t *r, |
| | 25 | ngx_uint_t enable, ngx_uint_t ok, ngx_http_core_loc_conf_t *clcf, |
| | 26 | ngx_str_t *encoding); |
| 23 | 27 | static ngx_int_t ngx_http_gzip_static_handler(ngx_http_request_t *r); |
| 24 | 28 | static void *ngx_http_gzip_static_create_conf(ngx_conf_t *cf); |
| 25 | 29 | static char *ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent, |
| … |
… |
|
| 41 | 45 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 42 | 46 | ngx_conf_set_enum_slot, |
| 43 | 47 | NGX_HTTP_LOC_CONF_OFFSET, |
| 44 | | offsetof(ngx_http_gzip_static_conf_t, enable), |
| | 48 | offsetof(ngx_http_gzip_static_conf_t, enable_gzip), |
| | 49 | &ngx_http_gzip_static }, |
| | 50 | |
| | 51 | { ngx_string("brotli_static"), |
| | 52 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| | 53 | ngx_conf_set_enum_slot, |
| | 54 | NGX_HTTP_LOC_CONF_OFFSET, |
| | 55 | offsetof(ngx_http_gzip_static_conf_t, enable_brotli), |
| 45 | 56 | &ngx_http_gzip_static }, |
| 46 | 57 | |
| 47 | 58 | ngx_null_command |
| … |
… |
|
| 79 | 90 | }; |
| 80 | 91 | |
| 81 | 92 | |
| | 93 | static ngx_str_t encoding_gzip = ngx_string("gzip"); |
| | 94 | static ngx_str_t encoding_brotli = ngx_string("br"); |
| | 95 | |
| | 96 | |
| 82 | 97 | static ngx_int_t |
| 83 | 98 | ngx_http_gzip_static_handler(ngx_http_request_t *r) |
| 84 | 99 | { |
| 85 | | u_char *p; |
| 86 | | size_t root; |
| 87 | | ngx_str_t path; |
| 88 | 100 | ngx_int_t rc; |
| 89 | | ngx_uint_t level; |
| 90 | | ngx_log_t *log; |
| 91 | | ngx_buf_t *b; |
| 92 | | ngx_chain_t out; |
| 93 | | ngx_table_elt_t *h; |
| 94 | | ngx_open_file_info_t of; |
| 95 | 101 | ngx_http_core_loc_conf_t *clcf; |
| 96 | 102 | ngx_http_gzip_static_conf_t *gzcf; |
| 97 | 103 | |
| … |
… |
|
| 105 | 111 | |
| 106 | 112 | gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module); |
| 107 | 113 | |
| 108 | | if (gzcf->enable == NGX_HTTP_GZIP_STATIC_OFF) { |
| | 114 | if (gzcf->enable_gzip == NGX_HTTP_GZIP_STATIC_OFF |
| | 115 | && gzcf->enable_brotli == NGX_HTTP_GZIP_STATIC_OFF) { |
| 109 | 116 | return NGX_DECLINED; |
| 110 | 117 | } |
| 111 | 118 | |
| 112 | | if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) { |
| 113 | | rc = ngx_http_gzip_ok(r); |
| | 119 | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
| 114 | 120 | |
| 115 | | } else { |
| 116 | | /* always */ |
| 117 | | rc = NGX_OK; |
| | 121 | rc = NGX_DECLINED; |
| | 122 | if (gzcf->enable_gzip != NGX_HTTP_GZIP_STATIC_OFF) { |
| | 123 | if (gzcf->enable_gzip == NGX_HTTP_GZIP_STATIC_ON) { |
| | 124 | rc = ngx_http_gzip_ok(r); |
| | 125 | } else { |
| | 126 | /* always */ |
| | 127 | rc = NGX_OK; |
| | 128 | } |
| | 129 | rc = ngx_http_gzip_static_serve_file(r, gzcf->enable_gzip, rc, clcf, |
| | 130 | &encoding_gzip); |
| 118 | 131 | } |
| 119 | 132 | |
| 120 | | clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
| | 133 | if (gzcf->enable_brotli != NGX_HTTP_GZIP_STATIC_OFF && rc == NGX_DECLINED) { |
| | 134 | if (gzcf->enable_gzip == NGX_HTTP_GZIP_STATIC_ON) { |
| | 135 | rc = ngx_http_gzip_ok(r); |
| | 136 | } else { |
| | 137 | /* always */ |
| | 138 | rc = NGX_OK; |
| | 139 | } |
| | 140 | rc = ngx_http_gzip_static_serve_file(r, gzcf->enable_brotli, rc, clcf, |
| | 141 | &encoding_brotli); |
| | 142 | } |
| | 143 | |
| | 144 | return rc; |
| | 145 | } |
| | 146 | |
| | 147 | |
| | 148 | static ngx_int_t |
| | 149 | ngx_http_gzip_static_serve_file(ngx_http_request_t *r, ngx_uint_t enable, |
| | 150 | ngx_uint_t ok, ngx_http_core_loc_conf_t *clcf, ngx_str_t *encoding) |
| | 151 | { |
| | 152 | u_char *p; |
| | 153 | size_t root; |
| | 154 | ngx_str_t path; |
| | 155 | ngx_int_t rc; |
| | 156 | ngx_uint_t level; |
| | 157 | ngx_log_t *log; |
| | 158 | ngx_buf_t *b; |
| | 159 | ngx_chain_t out; |
| | 160 | ngx_table_elt_t *h; |
| | 161 | ngx_open_file_info_t of; |
| | 162 | |
| | 163 | rc = ok; |
| 121 | 164 | |
| 122 | 165 | if (!clcf->gzip_vary && rc != NGX_OK) { |
| 123 | 166 | return NGX_DECLINED; |
| … |
… |
|
| 125 | 168 | |
| 126 | 169 | log = r->connection->log; |
| 127 | 170 | |
| 128 | | p = ngx_http_map_uri_to_path(r, &path, &root, sizeof(".gz") - 1); |
| | 171 | p = ngx_http_map_uri_to_path(r, &path, &root, 4 - 1); |
| 129 | 172 | if (p == NULL) { |
| 130 | 173 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
| 131 | 174 | } |
| 132 | 175 | |
| 133 | 176 | *p++ = '.'; |
| 134 | | *p++ = 'g'; |
| 135 | | *p++ = 'z'; |
| | 177 | *p++ = encoding->data[0]; |
| | 178 | *p++ = encoding->data[1]; |
| 136 | 179 | *p = '\0'; |
| 137 | 180 | |
| 138 | 181 | path.len = p - path.data; |
| … |
… |
|
| 188 | 231 | return NGX_DECLINED; |
| 189 | 232 | } |
| 190 | 233 | |
| 191 | | if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) { |
| | 234 | if (enable == NGX_HTTP_GZIP_STATIC_ON) { |
| 192 | 235 | r->gzip_vary = 1; |
| 193 | 236 | |
| 194 | 237 | if (rc != NGX_OK) { |
| … |
… |
|
| 243 | 286 | |
| 244 | 287 | h->hash = 1; |
| 245 | 288 | ngx_str_set(&h->key, "Content-Encoding"); |
| 246 | | ngx_str_set(&h->value, "gzip"); |
| | 289 | h->value = *encoding; |
| 247 | 290 | r->headers_out.content_encoding = h; |
| 248 | 291 | |
| 249 | 292 | /* we need to allocate all before the header would be sent */ |
| … |
… |
|
| 293 | 336 | return NULL; |
| 294 | 337 | } |
| 295 | 338 | |
| 296 | | conf->enable = NGX_CONF_UNSET_UINT; |
| | 339 | conf->enable_gzip = NGX_CONF_UNSET_UINT; |
| | 340 | conf->enable_brotli = NGX_CONF_UNSET_UINT; |
| 297 | 341 | |
| 298 | 342 | return conf; |
| 299 | 343 | } |
| … |
… |
|
| 305 | 349 | ngx_http_gzip_static_conf_t *prev = parent; |
| 306 | 350 | ngx_http_gzip_static_conf_t *conf = child; |
| 307 | 351 | |
| 308 | | ngx_conf_merge_uint_value(conf->enable, prev->enable, |
| | 352 | ngx_conf_merge_uint_value(conf->enable_gzip, prev->enable_gzip, |
| | 353 | NGX_HTTP_GZIP_STATIC_OFF); |
| | 354 | ngx_conf_merge_uint_value(conf->enable_brotli, prev->enable_brotli, |
| 309 | 355 | NGX_HTTP_GZIP_STATIC_OFF); |
| 310 | 356 | |
| 311 | 357 | return NGX_CONF_OK; |
diff -r 1ad0999a7ded -r 662115ad250f src/http/ngx_http_core_module.c
|
a
|
b
|
|
| 74 | 74 | static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, |
| 75 | 75 | void *conf); |
| 76 | 76 | #if (NGX_HTTP_GZIP) |
| 77 | | static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae); |
| 78 | | static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last); |
| | 77 | static ngx_int_t ngx_http_accept_encoding(ngx_str_t *ae, char *e, size_t n); |
| | 78 | static ngx_uint_t ngx_http_encoding_quantity(u_char *p, u_char *last); |
| 79 | 79 | static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, |
| 80 | 80 | void *conf); |
| 81 | 81 | #endif |
| … |
… |
|
| 2170 | 2170 | */ |
| 2171 | 2171 | |
| 2172 | 2172 | if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0 |
| 2173 | | && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK) |
| | 2173 | && ngx_http_accept_encoding(&ae->value, "gzip", 4) != NGX_OK) |
| 2174 | 2174 | { |
| 2175 | 2175 | return NGX_DECLINED; |
| 2176 | 2176 | } |
| … |
… |
|
| 2297 | 2297 | } |
| 2298 | 2298 | |
| 2299 | 2299 | |
| | 2300 | ngx_int_t |
| | 2301 | ngx_http_brotli_ok(ngx_http_request_t *r) |
| | 2302 | { |
| | 2303 | ngx_table_elt_t *ae; |
| | 2304 | |
| | 2305 | if (r != r->main) { |
| | 2306 | return NGX_DECLINED; |
| | 2307 | } |
| | 2308 | |
| | 2309 | ae = r->headers_in.accept_encoding; |
| | 2310 | if (ae == NULL) { |
| | 2311 | return NGX_DECLINED; |
| | 2312 | } |
| | 2313 | |
| | 2314 | if (ae->value.len < sizeof("br") - 1) { |
| | 2315 | return NGX_DECLINED; |
| | 2316 | } |
| | 2317 | |
| | 2318 | if (ngx_http_accept_encoding(&ae->value, "br", 2) != NGX_OK) |
| | 2319 | { |
| | 2320 | return NGX_DECLINED; |
| | 2321 | } |
| | 2322 | |
| | 2323 | return NGX_OK; |
| | 2324 | } |
| | 2325 | |
| | 2326 | |
| 2300 | 2327 | /* |
| 2301 | | * gzip is enabled for the following quantities: |
| | 2328 | * encoding is enabled for the following quantities: |
| 2302 | 2329 | * "gzip; q=0.001" ... "gzip; q=1.000" |
| 2303 | | * gzip is disabled for the following quantities: |
| 2304 | | * "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases |
| | 2330 | * encoding is disabled for the following quantities: |
| | 2331 | * "br; q=0" ... "br; q=0.000", and for any invalid cases |
| 2305 | 2332 | */ |
| 2306 | 2333 | |
| 2307 | 2334 | static ngx_int_t |
| 2308 | | ngx_http_gzip_accept_encoding(ngx_str_t *ae) |
| | 2335 | ngx_http_accept_encoding(ngx_str_t *ae, char *e, size_t n) |
| 2309 | 2336 | { |
| 2310 | 2337 | u_char *p, *start, *last; |
| 2311 | 2338 | |
| … |
… |
|
| 2313 | 2340 | last = start + ae->len; |
| 2314 | 2341 | |
| 2315 | 2342 | for ( ;; ) { |
| 2316 | | p = ngx_strcasestrn(start, "gzip", 4 - 1); |
| | 2343 | p = ngx_strcasestrn(start, e, n - 1); |
| 2317 | 2344 | if (p == NULL) { |
| 2318 | 2345 | return NGX_DECLINED; |
| 2319 | 2346 | } |
| … |
… |
|
| 2322 | 2349 | break; |
| 2323 | 2350 | } |
| 2324 | 2351 | |
| 2325 | | start = p + 4; |
| 2326 | | } |
| 2327 | | |
| 2328 | | p += 4; |
| | 2352 | start = p + n; |
| | 2353 | } |
| | 2354 | |
| | 2355 | p += n; |
| 2329 | 2356 | |
| 2330 | 2357 | while (p < last) { |
| 2331 | 2358 | switch (*p++) { |
| … |
… |
|
| 2364 | 2391 | return NGX_DECLINED; |
| 2365 | 2392 | } |
| 2366 | 2393 | |
| 2367 | | if (ngx_http_gzip_quantity(p, last) == 0) { |
| | 2394 | if (ngx_http_encoding_quantity(p, last) == 0) { |
| 2368 | 2395 | return NGX_DECLINED; |
| 2369 | 2396 | } |
| 2370 | 2397 | |
| … |
… |
|
| 2373 | 2400 | |
| 2374 | 2401 | |
| 2375 | 2402 | static ngx_uint_t |
| 2376 | | ngx_http_gzip_quantity(u_char *p, u_char *last) |
| | 2403 | ngx_http_encoding_quantity(u_char *p, u_char *last) |
| 2377 | 2404 | { |
| 2378 | 2405 | u_char c; |
| 2379 | 2406 | ngx_uint_t n, q; |
diff -r 1ad0999a7ded -r 662115ad250f src/http/ngx_http_core_module.h
|
a
|
b
|
|
| 504 | 504 | ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r); |
| 505 | 505 | #if (NGX_HTTP_GZIP) |
| 506 | 506 | ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r); |
| | 507 | ngx_int_t ngx_http_brotli_ok(ngx_http_request_t *r); |
| 507 | 508 | #endif |
| 508 | 509 | |
| 509 | 510 | |