Mercurial > hg > nginx-quic
comparison src/http/ngx_http_core_module.c @ 3980:19de03b4217f
Accept-Encoding refactoring: "gzip; q=0" support
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 01 Aug 2011 11:02:12 +0000 |
parents | 1d9353fbc077 |
children | aab3889c41e9 |
comparison
equal
deleted
inserted
replaced
3979:1d9353fbc077 | 3980:19de03b4217f |
---|---|
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); | |
73 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, | 74 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, |
74 void *conf); | 75 void *conf); |
75 #endif | 76 #endif |
76 | 77 |
77 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data); | 78 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data); |
2011 #if (NGX_HTTP_GZIP) | 2012 #if (NGX_HTTP_GZIP) |
2012 | 2013 |
2013 ngx_int_t | 2014 ngx_int_t |
2014 ngx_http_gzip_ok(ngx_http_request_t *r) | 2015 ngx_http_gzip_ok(ngx_http_request_t *r) |
2015 { | 2016 { |
2016 u_char *g; | |
2017 time_t date, expires; | 2017 time_t date, expires; |
2018 ngx_uint_t p; | 2018 ngx_uint_t p; |
2019 ngx_array_t *cc; | 2019 ngx_array_t *cc; |
2020 ngx_table_elt_t *e, *d, *ae; | 2020 ngx_table_elt_t *e, *d, *ae; |
2021 ngx_http_core_loc_conf_t *clcf; | 2021 ngx_http_core_loc_conf_t *clcf; |
2029 ae = r->headers_in.accept_encoding; | 2029 ae = r->headers_in.accept_encoding; |
2030 if (ae == NULL) { | 2030 if (ae == NULL) { |
2031 return NGX_DECLINED; | 2031 return NGX_DECLINED; |
2032 } | 2032 } |
2033 | 2033 |
2034 if (ngx_strncmp(ae->value.data, "gzip,", 5) == 0) { | 2034 if (ae->value.len < 5) { |
2035 /* | |
2036 * test for the most common case "gzip,...": | |
2037 * MSIE: "gzip, deflate" | |
2038 * Firefox: "gzip,deflate" | |
2039 * Chrome: "gzip,deflate,sdch" | |
2040 * Safari: "gzip, deflate" | |
2041 * Opera: "gzip, deflate" | |
2042 */ | |
2043 goto found; | |
2044 } | |
2045 | |
2046 g = ngx_strcasestrn(ae->value.data, "gzip", 4 - 1); | |
2047 if (g == NULL) { | |
2048 return NGX_DECLINED; | 2035 return NGX_DECLINED; |
2049 } | 2036 } |
2050 | 2037 |
2051 found: | 2038 /* |
2039 * test first for the most common case "gzip,...": | |
2040 * MSIE: "gzip, deflate" | |
2041 * Firefox: "gzip,deflate" | |
2042 * Chrome: "gzip,deflate,sdch" | |
2043 * Safari: "gzip, deflate" | |
2044 * Opera: "gzip, deflate" | |
2045 */ | |
2046 | |
2047 if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0 | |
2048 && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK) | |
2049 { | |
2050 return NGX_DECLINED; | |
2051 } | |
2052 | 2052 |
2053 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 2053 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
2054 | 2054 |
2055 if (r->headers_in.msie6 && clcf->gzip_disable_msie6) { | 2055 if (r->headers_in.msie6 && clcf->gzip_disable_msie6) { |
2056 return NGX_DECLINED; | 2056 return NGX_DECLINED; |
2167 #endif | 2167 #endif |
2168 | 2168 |
2169 r->gzip_ok = 1; | 2169 r->gzip_ok = 1; |
2170 | 2170 |
2171 return NGX_OK; | 2171 return NGX_OK; |
2172 } | |
2173 | |
2174 | |
2175 /* | |
2176 * gzip is enabled for the following quantities: | |
2177 * "gzip; q=0.001" ... "gzip; q=0.999", "gzip; q=1" | |
2178 * gzip is disabled for the following quantities: | |
2179 * "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases | |
2180 */ | |
2181 | |
2182 static ngx_int_t | |
2183 ngx_http_gzip_accept_encoding(ngx_str_t *ae) | |
2184 { | |
2185 u_char c, *p, *start, *last; | |
2186 ngx_uint_t n, q; | |
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 c = *p++; | |
2244 | |
2245 if (c == '1') { | |
2246 if (p == last || *p == ',' || *p == ' ') { | |
2247 return NGX_OK; | |
2248 } | |
2249 return NGX_DECLINED; | |
2250 } | |
2251 | |
2252 if (c != '0') { | |
2253 return NGX_DECLINED; | |
2254 } | |
2255 | |
2256 if (p == last) { | |
2257 return NGX_DECLINED; | |
2258 } | |
2259 | |
2260 if (*p++ != '.') { | |
2261 return NGX_DECLINED; | |
2262 } | |
2263 | |
2264 n = 0; | |
2265 q = 0; | |
2266 | |
2267 while (p < last) { | |
2268 c = *p++; | |
2269 | |
2270 if (c == ',') { | |
2271 break; | |
2272 } | |
2273 | |
2274 if (c >= '1' && c <= '9') { | |
2275 n++; | |
2276 q++; | |
2277 continue; | |
2278 } | |
2279 | |
2280 if (c == '0') { | |
2281 n++; | |
2282 continue; | |
2283 } | |
2284 | |
2285 return NGX_DECLINED; | |
2286 } | |
2287 | |
2288 if (n < 4 && q != 0) { | |
2289 return NGX_OK; | |
2290 } | |
2291 | |
2292 return NGX_DECLINED; | |
2172 } | 2293 } |
2173 | 2294 |
2174 #endif | 2295 #endif |
2175 | 2296 |
2176 | 2297 |