Mercurial > hg > nginx
annotate src/http/modules/ngx_http_memcached_module.c @ 9052:2e51cf3ffd90 quic
QUIC: defer stream removal until all its data is acked.
Previously, stream was kept alive until all its data is sent. This resulted
in disabling retransmission of final part of stream when QUIC connection
was closed right after closing stream connection.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 22 Aug 2022 15:33:23 +0400 |
parents | d26db4f82d7d |
children |
rev | line source |
---|---|
581 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
581 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 typedef struct { | |
14 ngx_http_upstream_conf_t upstream; | |
1076 | 15 ngx_int_t index; |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
16 ngx_uint_t gzip_flag; |
581 | 17 } ngx_http_memcached_loc_conf_t; |
18 | |
19 | |
20 typedef struct { | |
21 size_t rest; | |
22 ngx_http_request_t *request; | |
597 | 23 ngx_str_t key; |
581 | 24 } ngx_http_memcached_ctx_t; |
25 | |
26 | |
27 static ngx_int_t ngx_http_memcached_create_request(ngx_http_request_t *r); | |
28 static ngx_int_t ngx_http_memcached_reinit_request(ngx_http_request_t *r); | |
29 static ngx_int_t ngx_http_memcached_process_header(ngx_http_request_t *r); | |
30 static ngx_int_t ngx_http_memcached_filter_init(void *data); | |
31 static ngx_int_t ngx_http_memcached_filter(void *data, ssize_t bytes); | |
32 static void ngx_http_memcached_abort_request(ngx_http_request_t *r); | |
33 static void ngx_http_memcached_finalize_request(ngx_http_request_t *r, | |
34 ngx_int_t rc); | |
35 | |
36 static void *ngx_http_memcached_create_loc_conf(ngx_conf_t *cf); | |
37 static char *ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, | |
38 void *parent, void *child); | |
39 | |
40 static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, | |
41 void *conf); | |
42 | |
43 | |
44 static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = { | |
45 { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, | |
46 { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, | |
47 { ngx_string("invalid_response"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, | |
48 { ngx_string("not_found"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, | |
665 | 49 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, |
581 | 50 { ngx_null_string, 0 } |
51 }; | |
52 | |
53 | |
54 static ngx_command_t ngx_http_memcached_commands[] = { | |
55 | |
56 { ngx_string("memcached_pass"), | |
1788
f10228d7ea06
allow memached_pass inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1787
diff
changeset
|
57 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, |
581 | 58 ngx_http_memcached_pass, |
59 NGX_HTTP_LOC_CONF_OFFSET, | |
60 0, | |
61 NULL }, | |
62 | |
3271
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
63 { ngx_string("memcached_bind"), |
6530
1d0e03db9f8e
Upstream: the "transparent" parameter of proxy_bind and friends.
Roman Arutyunyan <arut@nginx.com>
parents:
6480
diff
changeset
|
64 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, |
3399 | 65 ngx_http_upstream_bind_set_slot, |
3271
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
66 NGX_HTTP_LOC_CONF_OFFSET, |
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
67 offsetof(ngx_http_memcached_loc_conf_t, upstream.local), |
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
68 NULL }, |
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
69 |
7371
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
70 { ngx_string("memcached_socket_keepalive"), |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
71 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
72 ngx_conf_set_flag_slot, |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
73 NGX_HTTP_LOC_CONF_OFFSET, |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
74 offsetof(ngx_http_memcached_loc_conf_t, upstream.socket_keepalive), |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
75 NULL }, |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
76 |
581 | 77 { ngx_string("memcached_connect_timeout"), |
78 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
79 ngx_conf_set_msec_slot, | |
80 NGX_HTTP_LOC_CONF_OFFSET, | |
81 offsetof(ngx_http_memcached_loc_conf_t, upstream.connect_timeout), | |
82 NULL }, | |
83 | |
84 { ngx_string("memcached_send_timeout"), | |
85 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
86 ngx_conf_set_msec_slot, | |
87 NGX_HTTP_LOC_CONF_OFFSET, | |
88 offsetof(ngx_http_memcached_loc_conf_t, upstream.send_timeout), | |
89 NULL }, | |
90 | |
91 { ngx_string("memcached_buffer_size"), | |
92 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
93 ngx_conf_set_size_slot, | |
94 NGX_HTTP_LOC_CONF_OFFSET, | |
95 offsetof(ngx_http_memcached_loc_conf_t, upstream.buffer_size), | |
96 NULL }, | |
97 | |
98 { ngx_string("memcached_read_timeout"), | |
99 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
100 ngx_conf_set_msec_slot, | |
101 NGX_HTTP_LOC_CONF_OFFSET, | |
102 offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), | |
103 NULL }, | |
104 | |
105 { ngx_string("memcached_next_upstream"), | |
106 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
107 ngx_conf_set_bitmask_slot, | |
108 NGX_HTTP_LOC_CONF_OFFSET, | |
109 offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream), | |
110 &ngx_http_memcached_next_upstream_masks }, | |
111 | |
5832
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
112 { ngx_string("memcached_next_upstream_tries"), |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
113 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
114 ngx_conf_set_num_slot, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
115 NGX_HTTP_LOC_CONF_OFFSET, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
116 offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream_tries), |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
117 NULL }, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
118 |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
119 { ngx_string("memcached_next_upstream_timeout"), |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
120 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
121 ngx_conf_set_msec_slot, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
122 NGX_HTTP_LOC_CONF_OFFSET, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
123 offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream_timeout), |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
124 NULL }, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
125 |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
126 { ngx_string("memcached_gzip_flag"), |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
127 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
128 ngx_conf_set_num_slot, |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
129 NGX_HTTP_LOC_CONF_OFFSET, |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
130 offsetof(ngx_http_memcached_loc_conf_t, gzip_flag), |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
131 NULL }, |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
132 |
581 | 133 ngx_null_command |
134 }; | |
135 | |
136 | |
667 | 137 static ngx_http_module_t ngx_http_memcached_module_ctx = { |
581 | 138 NULL, /* preconfiguration */ |
139 NULL, /* postconfiguration */ | |
140 | |
141 NULL, /* create main configuration */ | |
142 NULL, /* init main configuration */ | |
143 | |
144 NULL, /* create server configuration */ | |
145 NULL, /* merge server configuration */ | |
146 | |
4499
778ef9c3fd2d
Fixed spelling in single-line comments.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
147 ngx_http_memcached_create_loc_conf, /* create location configuration */ |
778ef9c3fd2d
Fixed spelling in single-line comments.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
148 ngx_http_memcached_merge_loc_conf /* merge location configuration */ |
581 | 149 }; |
150 | |
151 | |
152 ngx_module_t ngx_http_memcached_module = { | |
153 NGX_MODULE_V1, | |
154 &ngx_http_memcached_module_ctx, /* module context */ | |
155 ngx_http_memcached_commands, /* module directives */ | |
156 NGX_HTTP_MODULE, /* module type */ | |
157 NULL, /* init master */ | |
158 NULL, /* init module */ | |
159 NULL, /* init process */ | |
160 NULL, /* init thread */ | |
161 NULL, /* exit thread */ | |
162 NULL, /* exit process */ | |
163 NULL, /* exit master */ | |
164 NGX_MODULE_V1_PADDING | |
165 }; | |
166 | |
167 | |
1076 | 168 static ngx_str_t ngx_http_memcached_key = ngx_string("memcached_key"); |
169 | |
170 | |
581 | 171 #define NGX_HTTP_MEMCACHED_END (sizeof(ngx_http_memcached_end) - 1) |
172 static u_char ngx_http_memcached_end[] = CRLF "END" CRLF; | |
173 | |
174 | |
175 static ngx_int_t | |
176 ngx_http_memcached_handler(ngx_http_request_t *r) | |
177 { | |
178 ngx_int_t rc; | |
179 ngx_http_upstream_t *u; | |
180 ngx_http_memcached_ctx_t *ctx; | |
181 ngx_http_memcached_loc_conf_t *mlcf; | |
182 | |
645 | 183 if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { |
581 | 184 return NGX_HTTP_NOT_ALLOWED; |
185 } | |
186 | |
1370
cc114c85be0f
rename ngx_http_discard_body() to ngx_http_discard_request_body()
Igor Sysoev <igor@sysoev.ru>
parents:
1333
diff
changeset
|
187 rc = ngx_http_discard_request_body(r); |
581 | 188 |
1374 | 189 if (rc != NGX_OK) { |
581 | 190 return rc; |
191 } | |
192 | |
193 if (ngx_http_set_content_type(r) != NGX_OK) { | |
194 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
195 } | |
196 | |
3006
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
197 if (ngx_http_upstream_create(r) != NGX_OK) { |
581 | 198 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
199 } | |
200 | |
3006
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
201 u = r->upstream; |
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
202 |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3487
diff
changeset
|
203 ngx_str_set(&u->schema, "memcached://"); |
3006
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
204 u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module; |
581 | 205 |
3006
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
206 mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); |
581 | 207 |
208 u->conf = &mlcf->upstream; | |
209 | |
210 u->create_request = ngx_http_memcached_create_request; | |
211 u->reinit_request = ngx_http_memcached_reinit_request; | |
212 u->process_header = ngx_http_memcached_process_header; | |
213 u->abort_request = ngx_http_memcached_abort_request; | |
214 u->finalize_request = ngx_http_memcached_finalize_request; | |
215 | |
216 ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t)); | |
217 if (ctx == NULL) { | |
218 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
219 } | |
220 | |
221 ctx->request = r; | |
222 | |
597 | 223 ngx_http_set_ctx(r, ctx, ngx_http_memcached_module); |
224 | |
581 | 225 u->input_filter_init = ngx_http_memcached_filter_init; |
226 u->input_filter = ngx_http_memcached_filter; | |
227 u->input_filter_ctx = ctx; | |
228 | |
3061
f444f291ed38
fix request counter for memcached, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3006
diff
changeset
|
229 r->main->count++; |
f444f291ed38
fix request counter for memcached, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3006
diff
changeset
|
230 |
581 | 231 ngx_http_upstream_init(r); |
232 | |
233 return NGX_DONE; | |
234 } | |
235 | |
236 | |
237 static ngx_int_t | |
238 ngx_http_memcached_create_request(ngx_http_request_t *r) | |
239 { | |
1076 | 240 size_t len; |
1333
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
241 uintptr_t escape; |
1076 | 242 ngx_buf_t *b; |
243 ngx_chain_t *cl; | |
244 ngx_http_memcached_ctx_t *ctx; | |
245 ngx_http_variable_value_t *vv; | |
246 ngx_http_memcached_loc_conf_t *mlcf; | |
247 | |
248 mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); | |
581 | 249 |
1076 | 250 vv = ngx_http_get_indexed_variable(r, mlcf->index); |
251 | |
252 if (vv == NULL || vv->not_found || vv->len == 0) { | |
253 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
254 "the \"$memcached_key\" variable is not set"); | |
255 return NGX_ERROR; | |
256 } | |
257 | |
1333
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
258 escape = 2 * ngx_escape_uri(NULL, vv->data, vv->len, NGX_ESCAPE_MEMCACHED); |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
259 |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
260 len = sizeof("get ") - 1 + vv->len + escape + sizeof(CRLF) - 1; |
581 | 261 |
262 b = ngx_create_temp_buf(r->pool, len); | |
263 if (b == NULL) { | |
264 return NGX_ERROR; | |
265 } | |
266 | |
267 cl = ngx_alloc_chain_link(r->pool); | |
268 if (cl == NULL) { | |
269 return NGX_ERROR; | |
270 } | |
271 | |
272 cl->buf = b; | |
273 cl->next = NULL; | |
274 | |
275 r->upstream->request_bufs = cl; | |
276 | |
277 *b->last++ = 'g'; *b->last++ = 'e'; *b->last++ = 't'; *b->last++ = ' '; | |
278 | |
597 | 279 ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module); |
280 | |
281 ctx->key.data = b->last; | |
282 | |
1333
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
283 if (escape == 0) { |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
284 b->last = ngx_copy(b->last, vv->data, vv->len); |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
285 |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
286 } else { |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
287 b->last = (u_char *) ngx_escape_uri(b->last, vv->data, vv->len, |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
288 NGX_ESCAPE_MEMCACHED); |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
289 } |
581 | 290 |
597 | 291 ctx->key.len = b->last - ctx->key.data; |
581 | 292 |
293 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
597 | 294 "http memcached request: \"%V\"", &ctx->key); |
581 | 295 |
1088
2d8e72584534
eliminate the useless space symbol
Igor Sysoev <igor@sysoev.ru>
parents:
1076
diff
changeset
|
296 *b->last++ = CR; *b->last++ = LF; |
581 | 297 |
298 return NGX_OK; | |
299 } | |
300 | |
301 | |
302 static ngx_int_t | |
303 ngx_http_memcached_reinit_request(ngx_http_request_t *r) | |
304 { | |
305 return NGX_OK; | |
306 } | |
307 | |
308 | |
309 static ngx_int_t | |
310 ngx_http_memcached_process_header(ngx_http_request_t *r) | |
311 { | |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
312 u_char *p, *start; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
313 ngx_str_t line; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
314 ngx_uint_t flags; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
315 ngx_table_elt_t *h; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
316 ngx_http_upstream_t *u; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
317 ngx_http_memcached_ctx_t *ctx; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
318 ngx_http_memcached_loc_conf_t *mlcf; |
581 | 319 |
320 u = r->upstream; | |
321 | |
322 for (p = u->buffer.pos; p < u->buffer.last; p++) { | |
323 if (*p == LF) { | |
324 goto found; | |
325 } | |
326 } | |
327 | |
328 return NGX_AGAIN; | |
329 | |
330 found: | |
331 | |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
332 line.data = u->buffer.pos; |
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
333 line.len = p - u->buffer.pos; |
581 | 334 |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
335 if (line.len == 0 || *(p - 1) != CR) { |
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
336 goto no_valid; |
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
337 } |
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
338 |
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
339 *p = '\0'; |
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
340 line.len--; |
581 | 341 |
342 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
343 "memcached: \"%V\"", &line); | |
344 | |
345 p = u->buffer.pos; | |
346 | |
597 | 347 ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module); |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
348 mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); |
597 | 349 |
581 | 350 if (ngx_strncmp(p, "VALUE ", sizeof("VALUE ") - 1) == 0) { |
351 | |
352 p += sizeof("VALUE ") - 1; | |
353 | |
597 | 354 if (ngx_strncmp(p, ctx->key.data, ctx->key.len) != 0) { |
581 | 355 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
356 "memcached sent invalid key in response \"%V\" " | |
357 "for key \"%V\"", | |
597 | 358 &line, &ctx->key); |
581 | 359 |
360 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
361 } | |
362 | |
597 | 363 p += ctx->key.len; |
581 | 364 |
365 if (*p++ != ' ') { | |
366 goto no_valid; | |
367 } | |
368 | |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
369 /* flags */ |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
370 |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
371 start = p; |
581 | 372 |
373 while (*p) { | |
374 if (*p++ == ' ') { | |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
375 if (mlcf->gzip_flag) { |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
376 goto flags; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
377 } else { |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
378 goto length; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
379 } |
581 | 380 } |
381 } | |
382 | |
383 goto no_valid; | |
384 | |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
385 flags: |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
386 |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
387 flags = ngx_atoi(start, p - start - 1); |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
388 |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
389 if (flags == (ngx_uint_t) NGX_ERROR) { |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
390 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
391 "memcached sent invalid flags in response \"%V\" " |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
392 "for key \"%V\"", |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
393 &line, &ctx->key); |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
394 return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
395 } |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
396 |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
397 if (flags & mlcf->gzip_flag) { |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
398 h = ngx_list_push(&r->headers_out.headers); |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
399 if (h == NULL) { |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
400 return NGX_ERROR; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
401 } |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
402 |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
403 h->hash = 1; |
8031
d26db4f82d7d
All known output headers can be linked lists now.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7674
diff
changeset
|
404 h->next = NULL; |
5765
d80543940f9a
Style: use ngx_str_set().
Tatsuhiko Kubo <cubicdaiya@gmail.com>
parents:
5359
diff
changeset
|
405 ngx_str_set(&h->key, "Content-Encoding"); |
d80543940f9a
Style: use ngx_str_set().
Tatsuhiko Kubo <cubicdaiya@gmail.com>
parents:
5359
diff
changeset
|
406 ngx_str_set(&h->value, "gzip"); |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
407 r->headers_out.content_encoding = h; |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
408 } |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
409 |
581 | 410 length: |
411 | |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
412 start = p; |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
413 p = line.data + line.len; |
581 | 414 |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
415 u->headers_in.content_length_n = ngx_atoof(start, p - start); |
5801
ab48149b77a6
Style: use specified macro instead of magic-number.
Tatsuhiko Kubo <cubicdaiya@gmail.com>
parents:
5765
diff
changeset
|
416 if (u->headers_in.content_length_n == NGX_ERROR) { |
581 | 417 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
418 "memcached sent invalid length in response \"%V\" " | |
419 "for key \"%V\"", | |
597 | 420 &line, &ctx->key); |
581 | 421 return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
422 } | |
423 | |
424 u->headers_in.status_n = 200; | |
1567
31d4278d51c0
memcached did not set $upstream_response_time
Igor Sysoev <igor@sysoev.ru>
parents:
1554
diff
changeset
|
425 u->state->status = 200; |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
426 u->buffer.pos = p + sizeof(CRLF) - 1; |
581 | 427 |
428 return NGX_OK; | |
429 } | |
430 | |
431 if (ngx_strcmp(p, "END\x0d") == 0) { | |
432 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | |
597 | 433 "key: \"%V\" was not found by memcached", &ctx->key); |
581 | 434 |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
435 u->headers_in.content_length_n = 0; |
581 | 436 u->headers_in.status_n = 404; |
1567
31d4278d51c0
memcached did not set $upstream_response_time
Igor Sysoev <igor@sysoev.ru>
parents:
1554
diff
changeset
|
437 u->state->status = 404; |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
438 u->buffer.pos = p + sizeof("END" CRLF) - 1; |
4121
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
439 u->keepalive = 1; |
581 | 440 |
441 return NGX_OK; | |
442 } | |
443 | |
444 no_valid: | |
445 | |
446 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
447 "memcached sent invalid response: \"%V\"", &line); | |
448 | |
449 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
450 } | |
451 | |
452 | |
453 static ngx_int_t | |
454 ngx_http_memcached_filter_init(void *data) | |
455 { | |
456 ngx_http_memcached_ctx_t *ctx = data; | |
457 | |
458 ngx_http_upstream_t *u; | |
459 | |
460 u = ctx->request->upstream; | |
461 | |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
462 if (u->headers_in.status_n != 404) { |
5300
f538a67c9f77
Upstream: u->length now defaults to -1 (API change).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5226
diff
changeset
|
463 u->length = u->headers_in.content_length_n + NGX_HTTP_MEMCACHED_END; |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
464 ctx->rest = NGX_HTTP_MEMCACHED_END; |
5300
f538a67c9f77
Upstream: u->length now defaults to -1 (API change).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5226
diff
changeset
|
465 |
f538a67c9f77
Upstream: u->length now defaults to -1 (API change).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5226
diff
changeset
|
466 } else { |
f538a67c9f77
Upstream: u->length now defaults to -1 (API change).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5226
diff
changeset
|
467 u->length = 0; |
5226
a30ea5c6451d
Memcached: stricten header validation.
Ruslan Ermilov <ru@nginx.com>
parents:
5008
diff
changeset
|
468 } |
581 | 469 |
470 return NGX_OK; | |
471 } | |
472 | |
473 | |
474 static ngx_int_t | |
475 ngx_http_memcached_filter(void *data, ssize_t bytes) | |
476 { | |
477 ngx_http_memcached_ctx_t *ctx = data; | |
478 | |
479 u_char *last; | |
480 ngx_buf_t *b; | |
481 ngx_chain_t *cl, **ll; | |
482 ngx_http_upstream_t *u; | |
483 | |
484 u = ctx->request->upstream; | |
485 b = &u->buffer; | |
486 | |
4118
dbddec65fdab
Upstream: r->upstream->length type change to off_t.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4117
diff
changeset
|
487 if (u->length == (ssize_t) ctx->rest) { |
581 | 488 |
7674
7731c710796f
Memcached: protect from too long responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7371
diff
changeset
|
489 if (bytes > u->length |
7731c710796f
Memcached: protect from too long responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7371
diff
changeset
|
490 || ngx_strncmp(b->last, |
1548 | 491 ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest, |
3487
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
492 bytes) |
7674
7731c710796f
Memcached: protect from too long responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7371
diff
changeset
|
493 != 0) |
581 | 494 { |
495 ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, | |
496 "memcached sent invalid trailer"); | |
3487
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
497 |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
498 u->length = 0; |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
499 ctx->rest = 0; |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
500 |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
501 return NGX_OK; |
581 | 502 } |
503 | |
3487
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
504 u->length -= bytes; |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
505 ctx->rest -= bytes; |
581 | 506 |
4121
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
507 if (u->length == 0) { |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
508 u->keepalive = 1; |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
509 } |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
510 |
581 | 511 return NGX_OK; |
512 } | |
513 | |
514 for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) { | |
515 ll = &cl->next; | |
516 } | |
517 | |
518 cl = ngx_chain_get_free_buf(ctx->request->pool, &u->free_bufs); | |
519 if (cl == NULL) { | |
520 return NGX_ERROR; | |
521 } | |
522 | |
523 cl->buf->flush = 1; | |
524 cl->buf->memory = 1; | |
525 | |
526 *ll = cl; | |
527 | |
1554
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
528 last = b->last; |
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
529 cl->buf->pos = last; |
581 | 530 b->last += bytes; |
531 cl->buf->last = b->last; | |
1908
f2953601ed3c
fix memory leak in long-lived non buffered connections
Igor Sysoev <igor@sysoev.ru>
parents:
1788
diff
changeset
|
532 cl->buf->tag = u->output.tag; |
581 | 533 |
534 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0, | |
6480 | 535 "memcached filter bytes:%z size:%z length:%O rest:%z", |
581 | 536 bytes, b->last - b->pos, u->length, ctx->rest); |
537 | |
1554
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
538 if (bytes <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) { |
581 | 539 u->length -= bytes; |
540 return NGX_OK; | |
541 } | |
542 | |
5359
2fda9065d0f4
Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5300
diff
changeset
|
543 last += (size_t) (u->length - NGX_HTTP_MEMCACHED_END); |
581 | 544 |
7674
7731c710796f
Memcached: protect from too long responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7371
diff
changeset
|
545 if (bytes > u->length |
7731c710796f
Memcached: protect from too long responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7371
diff
changeset
|
546 || ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) |
7731c710796f
Memcached: protect from too long responses.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7371
diff
changeset
|
547 { |
581 | 548 ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, |
549 "memcached sent invalid trailer"); | |
4121
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
550 |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
551 b->last = last; |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
552 cl->buf->last = last; |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
553 u->length = 0; |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
554 ctx->rest = 0; |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
555 |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
556 return NGX_OK; |
581 | 557 } |
558 | |
1554
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
559 ctx->rest -= b->last - last; |
581 | 560 b->last = last; |
561 cl->buf->last = last; | |
562 u->length = ctx->rest; | |
563 | |
4121
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
564 if (u->length == 0) { |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
565 u->keepalive = 1; |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
566 } |
16c60162c35b
Keepalive support in memcached.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4118
diff
changeset
|
567 |
581 | 568 return NGX_OK; |
569 } | |
570 | |
571 | |
572 static void | |
573 ngx_http_memcached_abort_request(ngx_http_request_t *r) | |
574 { | |
575 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
576 "abort http memcached request"); | |
577 return; | |
578 } | |
579 | |
580 | |
581 static void | |
582 ngx_http_memcached_finalize_request(ngx_http_request_t *r, ngx_int_t rc) | |
583 { | |
584 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
585 "finalize http memcached request"); | |
586 return; | |
587 } | |
588 | |
589 | |
590 static void * | |
591 ngx_http_memcached_create_loc_conf(ngx_conf_t *cf) | |
592 { | |
593 ngx_http_memcached_loc_conf_t *conf; | |
594 | |
595 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_memcached_loc_conf_t)); | |
596 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2392
diff
changeset
|
597 return NULL; |
581 | 598 } |
599 | |
600 /* | |
601 * set by ngx_pcalloc(): | |
602 * | |
603 * conf->upstream.bufs.num = 0; | |
604 * conf->upstream.next_upstream = 0; | |
605 * conf->upstream.temp_path = NULL; | |
606 */ | |
607 | |
5008
fd84344f1df7
Fixed and improved the "*_bind" directives of proxying modules.
Ruslan Ermilov <ru@nginx.com>
parents:
4835
diff
changeset
|
608 conf->upstream.local = NGX_CONF_UNSET_PTR; |
7371
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
609 conf->upstream.socket_keepalive = NGX_CONF_UNSET; |
5832
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
610 conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT; |
581 | 611 conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; |
612 conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; | |
613 conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; | |
5832
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
614 conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; |
581 | 615 |
616 conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; | |
617 | |
884 | 618 /* the hardcoded values */ |
581 | 619 conf->upstream.cyclic_temp_file = 0; |
629 | 620 conf->upstream.buffering = 0; |
621 conf->upstream.ignore_client_abort = 0; | |
581 | 622 conf->upstream.send_lowat = 0; |
623 conf->upstream.bufs.num = 0; | |
624 conf->upstream.busy_buffers_size = 0; | |
625 conf->upstream.max_temp_file_size = 0; | |
626 conf->upstream.temp_file_write_size = 0; | |
657 | 627 conf->upstream.intercept_errors = 1; |
675 | 628 conf->upstream.intercept_404 = 1; |
581 | 629 conf->upstream.pass_request_headers = 0; |
630 conf->upstream.pass_request_body = 0; | |
6122
85f00678e54a
Memcached: enabled ranges.
Martin Mlynář <nexus@smoula.net>
parents:
5832
diff
changeset
|
631 conf->upstream.force_ranges = 1; |
581 | 632 |
1787
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
633 conf->index = NGX_CONF_UNSET; |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
634 conf->gzip_flag = NGX_CONF_UNSET_UINT; |
1787
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
635 |
581 | 636 return conf; |
637 } | |
638 | |
639 | |
640 static char * | |
641 ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
642 { | |
643 ngx_http_memcached_loc_conf_t *prev = parent; | |
644 ngx_http_memcached_loc_conf_t *conf = child; | |
645 | |
5008
fd84344f1df7
Fixed and improved the "*_bind" directives of proxying modules.
Ruslan Ermilov <ru@nginx.com>
parents:
4835
diff
changeset
|
646 ngx_conf_merge_ptr_value(conf->upstream.local, |
fd84344f1df7
Fixed and improved the "*_bind" directives of proxying modules.
Ruslan Ermilov <ru@nginx.com>
parents:
4835
diff
changeset
|
647 prev->upstream.local, NULL); |
fd84344f1df7
Fixed and improved the "*_bind" directives of proxying modules.
Ruslan Ermilov <ru@nginx.com>
parents:
4835
diff
changeset
|
648 |
7371
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
649 ngx_conf_merge_value(conf->upstream.socket_keepalive, |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
650 prev->upstream.socket_keepalive, 0); |
8b68d50090e4
Upstream: proxy_socket_keepalive and friends.
Vladimir Homutov <vl@nginx.com>
parents:
7321
diff
changeset
|
651 |
5832
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
652 ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
653 prev->upstream.next_upstream_tries, 0); |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
654 |
581 | 655 ngx_conf_merge_msec_value(conf->upstream.connect_timeout, |
656 prev->upstream.connect_timeout, 60000); | |
657 | |
658 ngx_conf_merge_msec_value(conf->upstream.send_timeout, | |
659 prev->upstream.send_timeout, 60000); | |
660 | |
661 ngx_conf_merge_msec_value(conf->upstream.read_timeout, | |
662 prev->upstream.read_timeout, 60000); | |
663 | |
5832
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
664 ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
665 prev->upstream.next_upstream_timeout, 0); |
d09b689911ac
Upstream: limited next_upstream time and tries (ticket #544).
Roman Arutyunyan <arut@nginx.com>
parents:
5801
diff
changeset
|
666 |
581 | 667 ngx_conf_merge_size_value(conf->upstream.buffer_size, |
668 prev->upstream.buffer_size, | |
669 (size_t) ngx_pagesize); | |
670 | |
671 ngx_conf_merge_bitmask_value(conf->upstream.next_upstream, | |
672 prev->upstream.next_upstream, | |
673 (NGX_CONF_BITMASK_SET | |
674 |NGX_HTTP_UPSTREAM_FT_ERROR | |
675 |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); | |
676 | |
665 | 677 if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) { |
678 conf->upstream.next_upstream = NGX_CONF_BITMASK_SET | |
679 |NGX_HTTP_UPSTREAM_FT_OFF; | |
680 } | |
681 | |
1787
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
682 if (conf->upstream.upstream == NULL) { |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
683 conf->upstream.upstream = prev->upstream.upstream; |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
684 } |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
685 |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
686 if (conf->index == NGX_CONF_UNSET) { |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
687 conf->index = prev->index; |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
688 } |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
689 |
4835
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
690 ngx_conf_merge_uint_value(conf->gzip_flag, prev->gzip_flag, 0); |
a4512d7737f6
Memcached: memcached_gzip_flag directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4499
diff
changeset
|
691 |
581 | 692 return NGX_CONF_OK; |
693 } | |
694 | |
695 | |
696 static char * | |
697 ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
698 { | |
2392 | 699 ngx_http_memcached_loc_conf_t *mlcf = conf; |
581 | 700 |
701 ngx_str_t *value; | |
807
3095bf59059b
now the "memcached_pass" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
675
diff
changeset
|
702 ngx_url_t u; |
581 | 703 ngx_http_core_loc_conf_t *clcf; |
704 | |
2392 | 705 if (mlcf->upstream.upstream) { |
581 | 706 return "is duplicate"; |
707 } | |
708 | |
709 value = cf->args->elts; | |
710 | |
807
3095bf59059b
now the "memcached_pass" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
675
diff
changeset
|
711 ngx_memzero(&u, sizeof(ngx_url_t)); |
581 | 712 |
807
3095bf59059b
now the "memcached_pass" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
675
diff
changeset
|
713 u.url = value[1]; |
884 | 714 u.no_resolve = 1; |
815
b630109560b7
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
807
diff
changeset
|
715 |
2392 | 716 mlcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); |
717 if (mlcf->upstream.upstream == NULL) { | |
884 | 718 return NGX_CONF_ERROR; |
581 | 719 } |
720 | |
721 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
722 | |
723 clcf->handler = ngx_http_memcached_handler; | |
724 | |
7321
45e513c3540d
Fixed invalid access to location defined as an empty string.
Ruslan Ermilov <ru@nginx.com>
parents:
7238
diff
changeset
|
725 if (clcf->name.len && clcf->name.data[clcf->name.len - 1] == '/') { |
581 | 726 clcf->auto_redirect = 1; |
727 } | |
728 | |
2392 | 729 mlcf->index = ngx_http_get_variable_index(cf, &ngx_http_memcached_key); |
1076 | 730 |
2392 | 731 if (mlcf->index == NGX_ERROR) { |
1076 | 732 return NGX_CONF_ERROR; |
733 } | |
734 | |
581 | 735 return NGX_CONF_OK; |
736 } |