Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_memcached_module.c @ 4835:a4512d7737f6
Memcached: memcached_gzip_flag directive.
This directive allows to test desired flag as returned by memcached and
sets Content-Encoding to gzip if one found.
This is reimplementation of patch by Tomash Brechko as available on
http://openhack.ru/. It should be a bit more correct though (at least
I think so). In particular, it doesn't try to detect if we are able to
gunzip data, but instead just sets correct Content-Encoding.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 10 Sep 2012 16:43:49 +0000 |
parents | 778ef9c3fd2d |
children | fd84344f1df7 |
comparison
equal
deleted
inserted
replaced
4834:ed470a7bf7fd | 4835:a4512d7737f6 |
---|---|
11 | 11 |
12 | 12 |
13 typedef struct { | 13 typedef struct { |
14 ngx_http_upstream_conf_t upstream; | 14 ngx_http_upstream_conf_t upstream; |
15 ngx_int_t index; | 15 ngx_int_t index; |
16 ngx_uint_t gzip_flag; | |
16 } ngx_http_memcached_loc_conf_t; | 17 } ngx_http_memcached_loc_conf_t; |
17 | 18 |
18 | 19 |
19 typedef struct { | 20 typedef struct { |
20 size_t rest; | 21 size_t rest; |
98 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | 99 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
99 ngx_conf_set_bitmask_slot, | 100 ngx_conf_set_bitmask_slot, |
100 NGX_HTTP_LOC_CONF_OFFSET, | 101 NGX_HTTP_LOC_CONF_OFFSET, |
101 offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream), | 102 offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream), |
102 &ngx_http_memcached_next_upstream_masks }, | 103 &ngx_http_memcached_next_upstream_masks }, |
104 | |
105 { ngx_string("memcached_gzip_flag"), | |
106 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
107 ngx_conf_set_num_slot, | |
108 NGX_HTTP_LOC_CONF_OFFSET, | |
109 offsetof(ngx_http_memcached_loc_conf_t, gzip_flag), | |
110 NULL }, | |
103 | 111 |
104 ngx_null_command | 112 ngx_null_command |
105 }; | 113 }; |
106 | 114 |
107 | 115 |
279 | 287 |
280 | 288 |
281 static ngx_int_t | 289 static ngx_int_t |
282 ngx_http_memcached_process_header(ngx_http_request_t *r) | 290 ngx_http_memcached_process_header(ngx_http_request_t *r) |
283 { | 291 { |
284 u_char *p, *len; | 292 u_char *p, *start; |
285 ngx_str_t line; | 293 ngx_str_t line; |
286 ngx_http_upstream_t *u; | 294 ngx_uint_t flags; |
287 ngx_http_memcached_ctx_t *ctx; | 295 ngx_table_elt_t *h; |
296 ngx_http_upstream_t *u; | |
297 ngx_http_memcached_ctx_t *ctx; | |
298 ngx_http_memcached_loc_conf_t *mlcf; | |
288 | 299 |
289 u = r->upstream; | 300 u = r->upstream; |
290 | 301 |
291 for (p = u->buffer.pos; p < u->buffer.last; p++) { | 302 for (p = u->buffer.pos; p < u->buffer.last; p++) { |
292 if (*p == LF) { | 303 if (*p == LF) { |
307 "memcached: \"%V\"", &line); | 318 "memcached: \"%V\"", &line); |
308 | 319 |
309 p = u->buffer.pos; | 320 p = u->buffer.pos; |
310 | 321 |
311 ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module); | 322 ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module); |
323 mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); | |
312 | 324 |
313 if (ngx_strncmp(p, "VALUE ", sizeof("VALUE ") - 1) == 0) { | 325 if (ngx_strncmp(p, "VALUE ", sizeof("VALUE ") - 1) == 0) { |
314 | 326 |
315 p += sizeof("VALUE ") - 1; | 327 p += sizeof("VALUE ") - 1; |
316 | 328 |
327 | 339 |
328 if (*p++ != ' ') { | 340 if (*p++ != ' ') { |
329 goto no_valid; | 341 goto no_valid; |
330 } | 342 } |
331 | 343 |
332 /* skip flags */ | 344 /* flags */ |
345 | |
346 start = p; | |
333 | 347 |
334 while (*p) { | 348 while (*p) { |
335 if (*p++ == ' ') { | 349 if (*p++ == ' ') { |
336 goto length; | 350 if (mlcf->gzip_flag) { |
351 goto flags; | |
352 } else { | |
353 goto length; | |
354 } | |
337 } | 355 } |
338 } | 356 } |
339 | 357 |
340 goto no_valid; | 358 goto no_valid; |
341 | 359 |
360 flags: | |
361 | |
362 flags = ngx_atoi(start, p - start - 1); | |
363 | |
364 if (flags == (ngx_uint_t) NGX_ERROR) { | |
365 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
366 "memcached sent invalid flags in response \"%V\" " | |
367 "for key \"%V\"", | |
368 &line, &ctx->key); | |
369 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
370 } | |
371 | |
372 if (flags & mlcf->gzip_flag) { | |
373 h = ngx_list_push(&r->headers_out.headers); | |
374 if (h == NULL) { | |
375 return NGX_ERROR; | |
376 } | |
377 | |
378 h->hash = 1; | |
379 h->key.len = sizeof("Content-Encoding") - 1; | |
380 h->key.data = (u_char *) "Content-Encoding"; | |
381 h->value.len = sizeof("gzip") - 1; | |
382 h->value.data = (u_char *) "gzip"; | |
383 | |
384 r->headers_out.content_encoding = h; | |
385 } | |
386 | |
342 length: | 387 length: |
343 | 388 |
344 len = p; | 389 start = p; |
345 | 390 |
346 while (*p && *p++ != CR) { /* void */ } | 391 while (*p && *p++ != CR) { /* void */ } |
347 | 392 |
348 u->headers_in.content_length_n = ngx_atoof(len, p - len - 1); | 393 u->headers_in.content_length_n = ngx_atoof(start, p - start - 1); |
349 if (u->headers_in.content_length_n == -1) { | 394 if (u->headers_in.content_length_n == -1) { |
350 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 395 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
351 "memcached sent invalid length in response \"%V\" " | 396 "memcached sent invalid length in response \"%V\" " |
352 "for key \"%V\"", | 397 "for key \"%V\"", |
353 &line, &ctx->key); | 398 &line, &ctx->key); |
548 conf->upstream.intercept_404 = 1; | 593 conf->upstream.intercept_404 = 1; |
549 conf->upstream.pass_request_headers = 0; | 594 conf->upstream.pass_request_headers = 0; |
550 conf->upstream.pass_request_body = 0; | 595 conf->upstream.pass_request_body = 0; |
551 | 596 |
552 conf->index = NGX_CONF_UNSET; | 597 conf->index = NGX_CONF_UNSET; |
598 conf->gzip_flag = NGX_CONF_UNSET_UINT; | |
553 | 599 |
554 return conf; | 600 return conf; |
555 } | 601 } |
556 | 602 |
557 | 603 |
591 | 637 |
592 if (conf->index == NGX_CONF_UNSET) { | 638 if (conf->index == NGX_CONF_UNSET) { |
593 conf->index = prev->index; | 639 conf->index = prev->index; |
594 } | 640 } |
595 | 641 |
642 ngx_conf_merge_uint_value(conf->gzip_flag, prev->gzip_flag, 0); | |
643 | |
596 return NGX_CONF_OK; | 644 return NGX_CONF_OK; |
597 } | 645 } |
598 | 646 |
599 | 647 |
600 static char * | 648 static char * |