Klaus Demo nginx / 721f47e
Accept-Encoding refactoring: "gzip; q=0" support Igor Sysoev 10 years ago
1 changed file(s) with 137 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
6969 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
7070 void *conf);
7171 #if (NGX_HTTP_GZIP)
72 static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);
7273 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
7374 void *conf);
7475 #endif
20122013 ngx_int_t
20132014 ngx_http_gzip_ok(ngx_http_request_t *r)
20142015 {
2015 u_char *g;
20162016 time_t date, expires;
20172017 ngx_uint_t p;
20182018 ngx_array_t *cc;
20302030 return NGX_DECLINED;
20312031 }
20322032
2033 if (ngx_strncmp(ae->value.data, "gzip,", 5) == 0) {
2034 /*
2035 * test for the most common case "gzip,...":
2036 * MSIE: "gzip, deflate"
2037 * Firefox: "gzip,deflate"
2038 * Chrome: "gzip,deflate,sdch"
2039 * Safari: "gzip, deflate"
2040 * Opera: "gzip, deflate"
2041 */
2042 goto found;
2043 }
2044
2045 g = ngx_strcasestrn(ae->value.data, "gzip", 4 - 1);
2046 if (g == NULL) {
2033 if (ae->value.len < 5) {
20472034 return NGX_DECLINED;
20482035 }
20492036
2050 found:
2037 /*
2038 * test first for the most common case "gzip,...":
2039 * MSIE: "gzip, deflate"
2040 * Firefox: "gzip,deflate"
2041 * Chrome: "gzip,deflate,sdch"
2042 * Safari: "gzip, deflate"
2043 * Opera: "gzip, deflate"
2044 */
2045
2046 if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
2047 && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
2048 {
2049 return NGX_DECLINED;
2050 }
20512051
20522052 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
20532053
21682168 r->gzip_ok = 1;
21692169
21702170 return NGX_OK;
2171 }
2172
2173
2174 /*
2175 * gzip is enabled for the following quantities:
2176 * "gzip; q=0.001" ... "gzip; q=0.999", "gzip; q=1"
2177 * gzip is disabled for the following quantities:
2178 * "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
2179 */
2180
2181 static ngx_int_t
2182 ngx_http_gzip_accept_encoding(ngx_str_t *ae)
2183 {
2184 u_char c, *p, *start, *last;
2185 ngx_uint_t n, q;
2186
2187 start = ae->data;
2188 last = start + ae->len;
2189
2190 for ( ;; ) {
2191 p = ngx_strcasestrn(start, "gzip", 4 - 1);
2192 if (p == NULL) {
2193 return NGX_DECLINED;
2194 }
2195
2196 if (p > start && (*(p - 1) == ',' || *(p - 1) == ' ')) {
2197 break;
2198 }
2199
2200 start = p + 4;
2201 }
2202
2203 p += 4;
2204
2205 while (p < last) {
2206 switch(*p++) {
2207 case ',':
2208 return NGX_OK;
2209 case ';':
2210 goto quantity;
2211 case ' ':
2212 continue;
2213 default:
2214 return NGX_DECLINED;
2215 }
2216 }
2217
2218 return NGX_OK;
2219
2220 quantity:
2221
2222 while (p < last) {
2223 switch(*p++) {
2224 case 'q':
2225 case 'Q':
2226 goto equal;
2227 case ' ':
2228 continue;
2229 default:
2230 return NGX_DECLINED;
2231 }
2232 }
2233
2234 return NGX_OK;
2235
2236 equal:
2237
2238 if (p + 2 > last || *p++ != '=') {
2239 return NGX_DECLINED;
2240 }
2241
2242 c = *p++;
2243
2244 if (c == '1') {
2245 if (p == last || *p == ',' || *p == ' ') {
2246 return NGX_OK;
2247 }
2248 return NGX_DECLINED;
2249 }
2250
2251 if (c != '0') {
2252 return NGX_DECLINED;
2253 }
2254
2255 if (p == last) {
2256 return NGX_DECLINED;
2257 }
2258
2259 if (*p++ != '.') {
2260 return NGX_DECLINED;
2261 }
2262
2263 n = 0;
2264 q = 0;
2265
2266 while (p < last) {
2267 c = *p++;
2268
2269 if (c == ',') {
2270 break;
2271 }
2272
2273 if (c >= '1' && c <= '9') {
2274 n++;
2275 q++;
2276 continue;
2277 }
2278
2279 if (c == '0') {
2280 n++;
2281 continue;
2282 }
2283
2284 return NGX_DECLINED;
2285 }
2286
2287 if (n < 4 && q != 0) {
2288 return NGX_OK;
2289 }
2290
2291 return NGX_DECLINED;
21712292 }
21722293
21732294 #endif