Mercurial > hg > nginx-quic
comparison src/http/ngx_http_core_module.c @ 4040:0094c8636d5f stable-1.0
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
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 29 Aug 2011 10:39:23 +0000 |
parents | 1df827cf70c0 |
children | d9b486dbf7e5 |
comparison
equal
deleted
inserted
replaced
4039:ee270f311dea | 4040:0094c8636d5f |
---|---|
68 static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, | 68 static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, |
69 void *conf); | 69 void *conf); |
70 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, | 70 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, |
71 void *conf); | 71 void *conf); |
72 #if (NGX_HTTP_GZIP) | 72 #if (NGX_HTTP_GZIP) |
73 static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae); | |
74 static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last); | |
73 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, | 75 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, |
74 void *conf); | 76 void *conf); |
75 #endif | 77 #endif |
76 | 78 |
77 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data); | 79 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data); |
2014 ngx_http_gzip_ok(ngx_http_request_t *r) | 2016 ngx_http_gzip_ok(ngx_http_request_t *r) |
2015 { | 2017 { |
2016 time_t date, expires; | 2018 time_t date, expires; |
2017 ngx_uint_t p; | 2019 ngx_uint_t p; |
2018 ngx_array_t *cc; | 2020 ngx_array_t *cc; |
2019 ngx_table_elt_t *e, *d; | 2021 ngx_table_elt_t *e, *d, *ae; |
2020 ngx_http_core_loc_conf_t *clcf; | 2022 ngx_http_core_loc_conf_t *clcf; |
2021 | 2023 |
2022 r->gzip_tested = 1; | 2024 r->gzip_tested = 1; |
2023 | 2025 |
2024 if (r != r->main | 2026 if (r != r->main) { |
2025 || r->headers_in.accept_encoding == NULL | 2027 return NGX_DECLINED; |
2026 || ngx_strcasestrn(r->headers_in.accept_encoding->value.data, | 2028 } |
2027 "gzip", 4 - 1) | 2029 |
2028 == NULL | 2030 ae = r->headers_in.accept_encoding; |
2029 | 2031 if (ae == NULL) { |
2030 /* | 2032 return NGX_DECLINED; |
2031 * if the URL (without the "http://" prefix) is longer than 253 bytes, | 2033 } |
2032 * then MSIE 4.x can not handle the compressed stream - it waits | 2034 |
2033 * too long, hangs up or crashes | 2035 if (ae->value.len < sizeof("gzip") - 1) { |
2034 */ | 2036 return NGX_DECLINED; |
2035 | 2037 } |
2036 || (r->headers_in.msie4 && r->unparsed_uri.len > 200)) | 2038 |
2039 /* | |
2040 * test first for the most common case "gzip,...": | |
2041 * MSIE: "gzip, deflate" | |
2042 * Firefox: "gzip,deflate" | |
2043 * Chrome: "gzip,deflate,sdch" | |
2044 * Safari: "gzip, deflate" | |
2045 * Opera: "gzip, deflate" | |
2046 */ | |
2047 | |
2048 if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0 | |
2049 && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK) | |
2037 { | 2050 { |
2038 return NGX_DECLINED; | 2051 return NGX_DECLINED; |
2039 } | 2052 } |
2040 | 2053 |
2041 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 2054 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
2155 #endif | 2168 #endif |
2156 | 2169 |
2157 r->gzip_ok = 1; | 2170 r->gzip_ok = 1; |
2158 | 2171 |
2159 return NGX_OK; | 2172 return NGX_OK; |
2173 } | |
2174 | |
2175 | |
2176 /* | |
2177 * gzip is enabled for the following quantities: | |
2178 * "gzip; q=0.001" ... "gzip; q=1.000" | |
2179 * gzip is disabled for the following quantities: | |
2180 * "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases | |
2181 */ | |
2182 | |
2183 static ngx_int_t | |
2184 ngx_http_gzip_accept_encoding(ngx_str_t *ae) | |
2185 { | |
2186 u_char *p, *start, *last; | |
2187 | |
2188 start = ae->data; | |
2189 last = start + ae->len; | |
2190 | |
2191 for ( ;; ) { | |
2192 p = ngx_strcasestrn(start, "gzip", 4 - 1); | |
2193 if (p == NULL) { | |
2194 return NGX_DECLINED; | |
2195 } | |
2196 | |
2197 if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) { | |
2198 break; | |
2199 } | |
2200 | |
2201 start = p + 4; | |
2202 } | |
2203 | |
2204 p += 4; | |
2205 | |
2206 while (p < last) { | |
2207 switch(*p++) { | |
2208 case ',': | |
2209 return NGX_OK; | |
2210 case ';': | |
2211 goto quantity; | |
2212 case ' ': | |
2213 continue; | |
2214 default: | |
2215 return NGX_DECLINED; | |
2216 } | |
2217 } | |
2218 | |
2219 return NGX_OK; | |
2220 | |
2221 quantity: | |
2222 | |
2223 while (p < last) { | |
2224 switch(*p++) { | |
2225 case 'q': | |
2226 case 'Q': | |
2227 goto equal; | |
2228 case ' ': | |
2229 continue; | |
2230 default: | |
2231 return NGX_DECLINED; | |
2232 } | |
2233 } | |
2234 | |
2235 return NGX_OK; | |
2236 | |
2237 equal: | |
2238 | |
2239 if (p + 2 > last || *p++ != '=') { | |
2240 return NGX_DECLINED; | |
2241 } | |
2242 | |
2243 if (ngx_http_gzip_quantity(p, last) == 0) { | |
2244 return NGX_DECLINED; | |
2245 } | |
2246 | |
2247 return NGX_OK; | |
2248 } | |
2249 | |
2250 | |
2251 ngx_uint_t | |
2252 ngx_http_gzip_quantity(u_char *p, u_char *last) | |
2253 { | |
2254 u_char c; | |
2255 ngx_uint_t n, q; | |
2256 | |
2257 c = *p++; | |
2258 | |
2259 if (c != '0' && c != '1') { | |
2260 return 0; | |
2261 } | |
2262 | |
2263 q = (c - '0') * 100; | |
2264 | |
2265 if (p == last) { | |
2266 return q; | |
2267 } | |
2268 | |
2269 c = *p++; | |
2270 | |
2271 if (c == ',' || c == ' ') { | |
2272 return q; | |
2273 } | |
2274 | |
2275 if (c != '.') { | |
2276 return 0; | |
2277 } | |
2278 | |
2279 n = 0; | |
2280 | |
2281 while (p < last) { | |
2282 c = *p++; | |
2283 | |
2284 if (c == ',' || c == ' ') { | |
2285 break; | |
2286 } | |
2287 | |
2288 if (c >= '0' && c <= '9') { | |
2289 q += c - '0'; | |
2290 n++; | |
2291 continue; | |
2292 } | |
2293 | |
2294 return 0; | |
2295 } | |
2296 | |
2297 if (q > 100 || n > 3) { | |
2298 return 0; | |
2299 } | |
2300 | |
2301 return q; | |
2160 } | 2302 } |
2161 | 2303 |
2162 #endif | 2304 #endif |
2163 | 2305 |
2164 | 2306 |