mirror of
https://github.com/nginx/nginx.git
synced 2024-12-20 00:47:48 +08:00
Merge of r3979, r3980, r3981, r3983, r3987, r3994, r3995:
Accept-Encoding refactoring: *) "gzip; q=0" support *) and removal of ancient MSIE 4.x test for gzip
This commit is contained in:
parent
ee25a6384c
commit
1a6c657f77
@ -70,6 +70,8 @@ static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||||||
static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
void *conf);
|
||||||
#if (NGX_HTTP_GZIP)
|
#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 char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
|
static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
void *conf);
|
void *conf);
|
||||||
#endif
|
#endif
|
||||||
@ -2016,24 +2018,35 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
|
|||||||
time_t date, expires;
|
time_t date, expires;
|
||||||
ngx_uint_t p;
|
ngx_uint_t p;
|
||||||
ngx_array_t *cc;
|
ngx_array_t *cc;
|
||||||
ngx_table_elt_t *e, *d;
|
ngx_table_elt_t *e, *d, *ae;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
r->gzip_tested = 1;
|
r->gzip_tested = 1;
|
||||||
|
|
||||||
if (r != r->main
|
if (r != r->main) {
|
||||||
|| r->headers_in.accept_encoding == NULL
|
return NGX_DECLINED;
|
||||||
|| ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
|
}
|
||||||
"gzip", 4 - 1)
|
|
||||||
== NULL
|
|
||||||
|
|
||||||
/*
|
ae = r->headers_in.accept_encoding;
|
||||||
* if the URL (without the "http://" prefix) is longer than 253 bytes,
|
if (ae == NULL) {
|
||||||
* then MSIE 4.x can not handle the compressed stream - it waits
|
return NGX_DECLINED;
|
||||||
* too long, hangs up or crashes
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|| (r->headers_in.msie4 && r->unparsed_uri.len > 200))
|
if (ae->value.len < sizeof("gzip") - 1) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* test first for the most common case "gzip,...":
|
||||||
|
* MSIE: "gzip, deflate"
|
||||||
|
* Firefox: "gzip,deflate"
|
||||||
|
* Chrome: "gzip,deflate,sdch"
|
||||||
|
* Safari: "gzip, deflate"
|
||||||
|
* Opera: "gzip, deflate"
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
|
||||||
|
&& ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_DECLINED;
|
return NGX_DECLINED;
|
||||||
}
|
}
|
||||||
@ -2159,6 +2172,135 @@ ok:
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gzip 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_gzip_accept_encoding(ngx_str_t *ae)
|
||||||
|
{
|
||||||
|
u_char *p, *start, *last;
|
||||||
|
|
||||||
|
start = ae->data;
|
||||||
|
last = start + ae->len;
|
||||||
|
|
||||||
|
for ( ;; ) {
|
||||||
|
p = ngx_strcasestrn(start, "gzip", 4 - 1);
|
||||||
|
if (p == NULL) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = p + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
p += 4;
|
||||||
|
|
||||||
|
while (p < last) {
|
||||||
|
switch(*p++) {
|
||||||
|
case ',':
|
||||||
|
return NGX_OK;
|
||||||
|
case ';':
|
||||||
|
goto quantity;
|
||||||
|
case ' ':
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
|
||||||
|
quantity:
|
||||||
|
|
||||||
|
while (p < last) {
|
||||||
|
switch(*p++) {
|
||||||
|
case 'q':
|
||||||
|
case 'Q':
|
||||||
|
goto equal;
|
||||||
|
case ' ':
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
|
||||||
|
equal:
|
||||||
|
|
||||||
|
if (p + 2 > last || *p++ != '=') {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_http_gzip_quantity(p, last) == 0) {
|
||||||
|
return NGX_DECLINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ngx_uint_t
|
||||||
|
ngx_http_gzip_quantity(u_char *p, u_char *last)
|
||||||
|
{
|
||||||
|
u_char c;
|
||||||
|
ngx_uint_t n, q;
|
||||||
|
|
||||||
|
c = *p++;
|
||||||
|
|
||||||
|
if (c != '0' && c != '1') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
q = (c - '0') * 100;
|
||||||
|
|
||||||
|
if (p == last) {
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = *p++;
|
||||||
|
|
||||||
|
if (c == ',' || c == ' ') {
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c != '.') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
while (p < last) {
|
||||||
|
c = *p++;
|
||||||
|
|
||||||
|
if (c == ',' || c == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
q += c - '0';
|
||||||
|
n++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (q > 100 || n > 3) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1439,8 +1439,6 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
|
|||||||
|
|
||||||
switch (msie[5]) {
|
switch (msie[5]) {
|
||||||
case '4':
|
case '4':
|
||||||
r->headers_in.msie4 = 1;
|
|
||||||
/* fall through */
|
|
||||||
case '5':
|
case '5':
|
||||||
r->headers_in.msie6 = 1;
|
r->headers_in.msie6 = 1;
|
||||||
break;
|
break;
|
||||||
@ -1463,7 +1461,6 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
|
|||||||
if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
|
if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
|
||||||
r->headers_in.opera = 1;
|
r->headers_in.opera = 1;
|
||||||
r->headers_in.msie = 0;
|
r->headers_in.msie = 0;
|
||||||
r->headers_in.msie4 = 0;
|
|
||||||
r->headers_in.msie6 = 0;
|
r->headers_in.msie6 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,6 @@ typedef struct {
|
|||||||
|
|
||||||
unsigned connection_type:2;
|
unsigned connection_type:2;
|
||||||
unsigned msie:1;
|
unsigned msie:1;
|
||||||
unsigned msie4:1;
|
|
||||||
unsigned msie6:1;
|
unsigned msie6:1;
|
||||||
unsigned opera:1;
|
unsigned opera:1;
|
||||||
unsigned gecko:1;
|
unsigned gecko:1;
|
||||||
|
Loading…
Reference in New Issue
Block a user