Mercurial > hg > nginx
annotate src/http/modules/ngx_http_memcached_module.c @ 4253:6efec8b1ff52 stable-1.0
Merging r4193, r4194:
Autoindex fixes:
*) Autoindex: escape '?' in file names.
For files with '?' in their names autoindex generated links with '?' not
escaped. This resulted in effectively truncated links as '?' indicates
query string start.
This is an updated version of the patch originally posted at [1]. It
introduces generic NGX_ESCAPE_URI_COMPONENT which escapes everything but
unreserved characters as per RFC 3986. This approach also renders unneeded
special colon processing (as colon is percent-encoded now), it's dropped
accordingly.
[1] http://nginx.org/pipermail/nginx-devel/2010-February/000112.html
*) Autoindex: escape html in file names.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 01 Nov 2011 14:09:15 +0000 |
parents | 66a244ee8cf7 |
children | 103b0d9afe07 4919fb357a5d |
rev | line source |
---|---|
581 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
12 typedef struct { | |
13 ngx_http_upstream_conf_t upstream; | |
1076 | 14 ngx_int_t index; |
581 | 15 } ngx_http_memcached_loc_conf_t; |
16 | |
17 | |
18 typedef struct { | |
19 size_t rest; | |
20 ngx_http_request_t *request; | |
597 | 21 ngx_str_t key; |
581 | 22 } ngx_http_memcached_ctx_t; |
23 | |
24 | |
25 static ngx_int_t ngx_http_memcached_create_request(ngx_http_request_t *r); | |
26 static ngx_int_t ngx_http_memcached_reinit_request(ngx_http_request_t *r); | |
27 static ngx_int_t ngx_http_memcached_process_header(ngx_http_request_t *r); | |
28 static ngx_int_t ngx_http_memcached_filter_init(void *data); | |
29 static ngx_int_t ngx_http_memcached_filter(void *data, ssize_t bytes); | |
30 static void ngx_http_memcached_abort_request(ngx_http_request_t *r); | |
31 static void ngx_http_memcached_finalize_request(ngx_http_request_t *r, | |
32 ngx_int_t rc); | |
33 | |
34 static void *ngx_http_memcached_create_loc_conf(ngx_conf_t *cf); | |
35 static char *ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, | |
36 void *parent, void *child); | |
37 | |
38 static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, | |
39 void *conf); | |
40 | |
41 | |
42 static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = { | |
43 { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, | |
44 { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, | |
45 { ngx_string("invalid_response"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, | |
46 { ngx_string("not_found"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, | |
665 | 47 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, |
581 | 48 { ngx_null_string, 0 } |
49 }; | |
50 | |
51 | |
52 static ngx_command_t ngx_http_memcached_commands[] = { | |
53 | |
54 { ngx_string("memcached_pass"), | |
1788
f10228d7ea06
allow memached_pass inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1787
diff
changeset
|
55 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, |
581 | 56 ngx_http_memcached_pass, |
57 NGX_HTTP_LOC_CONF_OFFSET, | |
58 0, | |
59 NULL }, | |
60 | |
3271
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
61 { ngx_string("memcached_bind"), |
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
62 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
3399 | 63 ngx_http_upstream_bind_set_slot, |
3271
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
64 NGX_HTTP_LOC_CONF_OFFSET, |
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
65 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
|
66 NULL }, |
fcd98af88df3
proxy_bind, fastcgi_bind, and memcached_bind
Igor Sysoev <igor@sysoev.ru>
parents:
3061
diff
changeset
|
67 |
581 | 68 { ngx_string("memcached_connect_timeout"), |
69 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
70 ngx_conf_set_msec_slot, | |
71 NGX_HTTP_LOC_CONF_OFFSET, | |
72 offsetof(ngx_http_memcached_loc_conf_t, upstream.connect_timeout), | |
73 NULL }, | |
74 | |
75 { ngx_string("memcached_send_timeout"), | |
76 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
77 ngx_conf_set_msec_slot, | |
78 NGX_HTTP_LOC_CONF_OFFSET, | |
79 offsetof(ngx_http_memcached_loc_conf_t, upstream.send_timeout), | |
80 NULL }, | |
81 | |
82 { ngx_string("memcached_buffer_size"), | |
83 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
84 ngx_conf_set_size_slot, | |
85 NGX_HTTP_LOC_CONF_OFFSET, | |
86 offsetof(ngx_http_memcached_loc_conf_t, upstream.buffer_size), | |
87 NULL }, | |
88 | |
89 { ngx_string("memcached_read_timeout"), | |
90 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
91 ngx_conf_set_msec_slot, | |
92 NGX_HTTP_LOC_CONF_OFFSET, | |
93 offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout), | |
94 NULL }, | |
95 | |
96 { ngx_string("memcached_next_upstream"), | |
97 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
98 ngx_conf_set_bitmask_slot, | |
99 NGX_HTTP_LOC_CONF_OFFSET, | |
100 offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream), | |
101 &ngx_http_memcached_next_upstream_masks }, | |
102 | |
103 ngx_null_command | |
104 }; | |
105 | |
106 | |
667 | 107 static ngx_http_module_t ngx_http_memcached_module_ctx = { |
581 | 108 NULL, /* preconfiguration */ |
109 NULL, /* postconfiguration */ | |
110 | |
111 NULL, /* create main configuration */ | |
112 NULL, /* init main configuration */ | |
113 | |
114 NULL, /* create server configuration */ | |
115 NULL, /* merge server configuration */ | |
116 | |
117 ngx_http_memcached_create_loc_conf, /* create location configration */ | |
118 ngx_http_memcached_merge_loc_conf /* merge location configration */ | |
119 }; | |
120 | |
121 | |
122 ngx_module_t ngx_http_memcached_module = { | |
123 NGX_MODULE_V1, | |
124 &ngx_http_memcached_module_ctx, /* module context */ | |
125 ngx_http_memcached_commands, /* module directives */ | |
126 NGX_HTTP_MODULE, /* module type */ | |
127 NULL, /* init master */ | |
128 NULL, /* init module */ | |
129 NULL, /* init process */ | |
130 NULL, /* init thread */ | |
131 NULL, /* exit thread */ | |
132 NULL, /* exit process */ | |
133 NULL, /* exit master */ | |
134 NGX_MODULE_V1_PADDING | |
135 }; | |
136 | |
137 | |
1076 | 138 static ngx_str_t ngx_http_memcached_key = ngx_string("memcached_key"); |
139 | |
140 | |
581 | 141 #define NGX_HTTP_MEMCACHED_END (sizeof(ngx_http_memcached_end) - 1) |
142 static u_char ngx_http_memcached_end[] = CRLF "END" CRLF; | |
143 | |
144 | |
145 static ngx_int_t | |
146 ngx_http_memcached_handler(ngx_http_request_t *r) | |
147 { | |
148 ngx_int_t rc; | |
149 ngx_http_upstream_t *u; | |
150 ngx_http_memcached_ctx_t *ctx; | |
151 ngx_http_memcached_loc_conf_t *mlcf; | |
152 | |
645 | 153 if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { |
581 | 154 return NGX_HTTP_NOT_ALLOWED; |
155 } | |
156 | |
1370
cc114c85be0f
rename ngx_http_discard_body() to ngx_http_discard_request_body()
Igor Sysoev <igor@sysoev.ru>
parents:
1333
diff
changeset
|
157 rc = ngx_http_discard_request_body(r); |
581 | 158 |
1374 | 159 if (rc != NGX_OK) { |
581 | 160 return rc; |
161 } | |
162 | |
163 if (ngx_http_set_content_type(r) != NGX_OK) { | |
164 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
165 } | |
166 | |
3006
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
167 if (ngx_http_upstream_create(r) != NGX_OK) { |
581 | 168 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
169 } | |
170 | |
3006
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
171 u = r->upstream; |
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
172 |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3487
diff
changeset
|
173 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
|
174 u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module; |
581 | 175 |
3006
95972b9e790b
ngx_http_upstream_create() to cleanup the previous upstream after
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
176 mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); |
581 | 177 |
178 u->conf = &mlcf->upstream; | |
179 | |
180 u->create_request = ngx_http_memcached_create_request; | |
181 u->reinit_request = ngx_http_memcached_reinit_request; | |
182 u->process_header = ngx_http_memcached_process_header; | |
183 u->abort_request = ngx_http_memcached_abort_request; | |
184 u->finalize_request = ngx_http_memcached_finalize_request; | |
185 | |
186 ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t)); | |
187 if (ctx == NULL) { | |
188 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
189 } | |
190 | |
191 ctx->rest = NGX_HTTP_MEMCACHED_END; | |
192 ctx->request = r; | |
193 | |
597 | 194 ngx_http_set_ctx(r, ctx, ngx_http_memcached_module); |
195 | |
581 | 196 u->input_filter_init = ngx_http_memcached_filter_init; |
197 u->input_filter = ngx_http_memcached_filter; | |
198 u->input_filter_ctx = ctx; | |
199 | |
3061
f444f291ed38
fix request counter for memcached, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3006
diff
changeset
|
200 r->main->count++; |
f444f291ed38
fix request counter for memcached, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3006
diff
changeset
|
201 |
581 | 202 ngx_http_upstream_init(r); |
203 | |
204 return NGX_DONE; | |
205 } | |
206 | |
207 | |
208 static ngx_int_t | |
209 ngx_http_memcached_create_request(ngx_http_request_t *r) | |
210 { | |
1076 | 211 size_t len; |
1333
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
212 uintptr_t escape; |
1076 | 213 ngx_buf_t *b; |
214 ngx_chain_t *cl; | |
215 ngx_http_memcached_ctx_t *ctx; | |
216 ngx_http_variable_value_t *vv; | |
217 ngx_http_memcached_loc_conf_t *mlcf; | |
218 | |
219 mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); | |
581 | 220 |
1076 | 221 vv = ngx_http_get_indexed_variable(r, mlcf->index); |
222 | |
223 if (vv == NULL || vv->not_found || vv->len == 0) { | |
224 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
225 "the \"$memcached_key\" variable is not set"); | |
226 return NGX_ERROR; | |
227 } | |
228 | |
1333
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
229 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
|
230 |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
231 len = sizeof("get ") - 1 + vv->len + escape + sizeof(CRLF) - 1; |
581 | 232 |
233 b = ngx_create_temp_buf(r->pool, len); | |
234 if (b == NULL) { | |
235 return NGX_ERROR; | |
236 } | |
237 | |
238 cl = ngx_alloc_chain_link(r->pool); | |
239 if (cl == NULL) { | |
240 return NGX_ERROR; | |
241 } | |
242 | |
243 cl->buf = b; | |
244 cl->next = NULL; | |
245 | |
246 r->upstream->request_bufs = cl; | |
247 | |
248 *b->last++ = 'g'; *b->last++ = 'e'; *b->last++ = 't'; *b->last++ = ' '; | |
249 | |
597 | 250 ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module); |
251 | |
252 ctx->key.data = b->last; | |
253 | |
1333
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
254 if (escape == 0) { |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
255 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
|
256 |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
257 } else { |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
258 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
|
259 NGX_ESCAPE_MEMCACHED); |
07ebeeb55700
escape space, etc in $memcached_key
Igor Sysoev <igor@sysoev.ru>
parents:
1332
diff
changeset
|
260 } |
581 | 261 |
597 | 262 ctx->key.len = b->last - ctx->key.data; |
581 | 263 |
264 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
597 | 265 "http memcached request: \"%V\"", &ctx->key); |
581 | 266 |
1088
2d8e72584534
eliminate the useless space symbol
Igor Sysoev <igor@sysoev.ru>
parents:
1076
diff
changeset
|
267 *b->last++ = CR; *b->last++ = LF; |
581 | 268 |
269 return NGX_OK; | |
270 } | |
271 | |
272 | |
273 static ngx_int_t | |
274 ngx_http_memcached_reinit_request(ngx_http_request_t *r) | |
275 { | |
276 return NGX_OK; | |
277 } | |
278 | |
279 | |
280 static ngx_int_t | |
281 ngx_http_memcached_process_header(ngx_http_request_t *r) | |
282 { | |
597 | 283 u_char *p, *len; |
284 ngx_str_t line; | |
285 ngx_http_upstream_t *u; | |
286 ngx_http_memcached_ctx_t *ctx; | |
581 | 287 |
288 u = r->upstream; | |
289 | |
290 for (p = u->buffer.pos; p < u->buffer.last; p++) { | |
291 if (*p == LF) { | |
292 goto found; | |
293 } | |
294 } | |
295 | |
296 return NGX_AGAIN; | |
297 | |
298 found: | |
299 | |
300 *p = '\0'; | |
301 | |
302 line.len = p - u->buffer.pos - 1; | |
303 line.data = u->buffer.pos; | |
304 | |
305 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
306 "memcached: \"%V\"", &line); | |
307 | |
308 p = u->buffer.pos; | |
309 | |
597 | 310 ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module); |
311 | |
581 | 312 if (ngx_strncmp(p, "VALUE ", sizeof("VALUE ") - 1) == 0) { |
313 | |
314 p += sizeof("VALUE ") - 1; | |
315 | |
597 | 316 if (ngx_strncmp(p, ctx->key.data, ctx->key.len) != 0) { |
581 | 317 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
318 "memcached sent invalid key in response \"%V\" " | |
319 "for key \"%V\"", | |
597 | 320 &line, &ctx->key); |
581 | 321 |
322 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
323 } | |
324 | |
597 | 325 p += ctx->key.len; |
581 | 326 |
327 if (*p++ != ' ') { | |
328 goto no_valid; | |
329 } | |
330 | |
331 /* skip flags */ | |
332 | |
333 while (*p) { | |
334 if (*p++ == ' ') { | |
335 goto length; | |
336 } | |
337 } | |
338 | |
339 goto no_valid; | |
340 | |
341 length: | |
342 | |
343 len = p; | |
344 | |
345 while (*p && *p++ != CR) { /* void */ } | |
346 | |
347 r->headers_out.content_length_n = ngx_atoof(len, p - len - 1); | |
348 if (r->headers_out.content_length_n == -1) { | |
349 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
350 "memcached sent invalid length in response \"%V\" " | |
351 "for key \"%V\"", | |
597 | 352 &line, &ctx->key); |
581 | 353 return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
354 } | |
355 | |
356 u->headers_in.status_n = 200; | |
1567
31d4278d51c0
memcached did not set $upstream_response_time
Igor Sysoev <igor@sysoev.ru>
parents:
1554
diff
changeset
|
357 u->state->status = 200; |
581 | 358 u->buffer.pos = p + 1; |
359 | |
360 return NGX_OK; | |
361 } | |
362 | |
363 if (ngx_strcmp(p, "END\x0d") == 0) { | |
364 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | |
597 | 365 "key: \"%V\" was not found by memcached", &ctx->key); |
581 | 366 |
367 u->headers_in.status_n = 404; | |
1567
31d4278d51c0
memcached did not set $upstream_response_time
Igor Sysoev <igor@sysoev.ru>
parents:
1554
diff
changeset
|
368 u->state->status = 404; |
581 | 369 |
370 return NGX_OK; | |
371 } | |
372 | |
373 no_valid: | |
374 | |
375 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
376 "memcached sent invalid response: \"%V\"", &line); | |
377 | |
378 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
379 } | |
380 | |
381 | |
382 static ngx_int_t | |
383 ngx_http_memcached_filter_init(void *data) | |
384 { | |
385 ngx_http_memcached_ctx_t *ctx = data; | |
386 | |
387 ngx_http_upstream_t *u; | |
388 | |
389 u = ctx->request->upstream; | |
390 | |
391 u->length += NGX_HTTP_MEMCACHED_END; | |
392 | |
393 return NGX_OK; | |
394 } | |
395 | |
396 | |
397 static ngx_int_t | |
398 ngx_http_memcached_filter(void *data, ssize_t bytes) | |
399 { | |
400 ngx_http_memcached_ctx_t *ctx = data; | |
401 | |
402 u_char *last; | |
403 ngx_buf_t *b; | |
404 ngx_chain_t *cl, **ll; | |
405 ngx_http_upstream_t *u; | |
406 | |
407 u = ctx->request->upstream; | |
408 b = &u->buffer; | |
409 | |
410 if (u->length == ctx->rest) { | |
411 | |
412 if (ngx_strncmp(b->last, | |
1548 | 413 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
|
414 bytes) |
1548 | 415 != 0) |
581 | 416 { |
417 ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, | |
418 "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
|
419 |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
420 u->length = 0; |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
421 ctx->rest = 0; |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
422 |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
423 return NGX_OK; |
581 | 424 } |
425 | |
3487
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
426 u->length -= bytes; |
5d2acf153153
revert partially r1555 and fix the error "memcached sent invalid trailer"
Igor Sysoev <igor@sysoev.ru>
parents:
3399
diff
changeset
|
427 ctx->rest -= bytes; |
581 | 428 |
429 return NGX_OK; | |
430 } | |
431 | |
432 for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) { | |
433 ll = &cl->next; | |
434 } | |
435 | |
436 cl = ngx_chain_get_free_buf(ctx->request->pool, &u->free_bufs); | |
437 if (cl == NULL) { | |
438 return NGX_ERROR; | |
439 } | |
440 | |
441 cl->buf->flush = 1; | |
442 cl->buf->memory = 1; | |
443 | |
444 *ll = cl; | |
445 | |
1554
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
446 last = b->last; |
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
447 cl->buf->pos = last; |
581 | 448 b->last += bytes; |
449 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
|
450 cl->buf->tag = u->output.tag; |
581 | 451 |
452 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0, | |
453 "memcached filter bytes:%z size:%z length:%z rest:%z", | |
454 bytes, b->last - b->pos, u->length, ctx->rest); | |
455 | |
1554
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
456 if (bytes <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) { |
581 | 457 u->length -= bytes; |
458 return NGX_OK; | |
459 } | |
460 | |
1554
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
461 last += u->length - NGX_HTTP_MEMCACHED_END; |
581 | 462 |
463 if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) { | |
464 ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, | |
465 "memcached sent invalid trailer"); | |
466 } | |
467 | |
1554
30fcc8478d85
two commits those go together by mistake
Igor Sysoev <igor@sysoev.ru>
parents:
1548
diff
changeset
|
468 ctx->rest -= b->last - last; |
581 | 469 b->last = last; |
470 cl->buf->last = last; | |
471 u->length = ctx->rest; | |
472 | |
473 return NGX_OK; | |
474 } | |
475 | |
476 | |
477 static void | |
478 ngx_http_memcached_abort_request(ngx_http_request_t *r) | |
479 { | |
480 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
481 "abort http memcached request"); | |
482 return; | |
483 } | |
484 | |
485 | |
486 static void | |
487 ngx_http_memcached_finalize_request(ngx_http_request_t *r, ngx_int_t rc) | |
488 { | |
489 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
490 "finalize http memcached request"); | |
491 return; | |
492 } | |
493 | |
494 | |
495 static void * | |
496 ngx_http_memcached_create_loc_conf(ngx_conf_t *cf) | |
497 { | |
498 ngx_http_memcached_loc_conf_t *conf; | |
499 | |
500 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_memcached_loc_conf_t)); | |
501 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
|
502 return NULL; |
581 | 503 } |
504 | |
505 /* | |
506 * set by ngx_pcalloc(): | |
507 * | |
508 * conf->upstream.bufs.num = 0; | |
509 * conf->upstream.next_upstream = 0; | |
510 * conf->upstream.temp_path = NULL; | |
511 * conf->upstream.uri = { 0, NULL }; | |
512 * conf->upstream.location = NULL; | |
513 */ | |
514 | |
515 conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; | |
516 conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; | |
517 conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; | |
518 | |
519 conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; | |
520 | |
884 | 521 /* the hardcoded values */ |
581 | 522 conf->upstream.cyclic_temp_file = 0; |
629 | 523 conf->upstream.buffering = 0; |
524 conf->upstream.ignore_client_abort = 0; | |
581 | 525 conf->upstream.send_lowat = 0; |
526 conf->upstream.bufs.num = 0; | |
527 conf->upstream.busy_buffers_size = 0; | |
528 conf->upstream.max_temp_file_size = 0; | |
529 conf->upstream.temp_file_write_size = 0; | |
657 | 530 conf->upstream.intercept_errors = 1; |
675 | 531 conf->upstream.intercept_404 = 1; |
581 | 532 conf->upstream.pass_request_headers = 0; |
533 conf->upstream.pass_request_body = 0; | |
534 | |
1787
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
535 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
|
536 |
581 | 537 return conf; |
538 } | |
539 | |
540 | |
541 static char * | |
542 ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
543 { | |
544 ngx_http_memcached_loc_conf_t *prev = parent; | |
545 ngx_http_memcached_loc_conf_t *conf = child; | |
546 | |
547 ngx_conf_merge_msec_value(conf->upstream.connect_timeout, | |
548 prev->upstream.connect_timeout, 60000); | |
549 | |
550 ngx_conf_merge_msec_value(conf->upstream.send_timeout, | |
551 prev->upstream.send_timeout, 60000); | |
552 | |
553 ngx_conf_merge_msec_value(conf->upstream.read_timeout, | |
554 prev->upstream.read_timeout, 60000); | |
555 | |
556 ngx_conf_merge_size_value(conf->upstream.buffer_size, | |
557 prev->upstream.buffer_size, | |
558 (size_t) ngx_pagesize); | |
559 | |
560 ngx_conf_merge_bitmask_value(conf->upstream.next_upstream, | |
561 prev->upstream.next_upstream, | |
562 (NGX_CONF_BITMASK_SET | |
563 |NGX_HTTP_UPSTREAM_FT_ERROR | |
564 |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); | |
565 | |
665 | 566 if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) { |
567 conf->upstream.next_upstream = NGX_CONF_BITMASK_SET | |
568 |NGX_HTTP_UPSTREAM_FT_OFF; | |
569 } | |
570 | |
1787
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
571 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
|
572 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
|
573 } |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
574 |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
575 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
|
576 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
|
577 } |
a37fe5ceacc4
inherit $memached_key index and memcached_pass upstream inside "if" block
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
578 |
581 | 579 return NGX_CONF_OK; |
580 } | |
581 | |
582 | |
583 static char * | |
584 ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
585 { | |
2392 | 586 ngx_http_memcached_loc_conf_t *mlcf = conf; |
581 | 587 |
588 ngx_str_t *value; | |
807
3095bf59059b
now the "memcached_pass" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
675
diff
changeset
|
589 ngx_url_t u; |
581 | 590 ngx_http_core_loc_conf_t *clcf; |
591 | |
2392 | 592 if (mlcf->upstream.upstream) { |
581 | 593 return "is duplicate"; |
594 } | |
595 | |
596 value = cf->args->elts; | |
597 | |
807
3095bf59059b
now the "memcached_pass" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
675
diff
changeset
|
598 ngx_memzero(&u, sizeof(ngx_url_t)); |
581 | 599 |
807
3095bf59059b
now the "memcached_pass" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
675
diff
changeset
|
600 u.url = value[1]; |
884 | 601 u.no_resolve = 1; |
815
b630109560b7
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
807
diff
changeset
|
602 |
2392 | 603 mlcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); |
604 if (mlcf->upstream.upstream == NULL) { | |
884 | 605 return NGX_CONF_ERROR; |
581 | 606 } |
607 | |
608 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
609 | |
610 clcf->handler = ngx_http_memcached_handler; | |
611 | |
612 if (clcf->name.data[clcf->name.len - 1] == '/') { | |
613 clcf->auto_redirect = 1; | |
614 } | |
615 | |
2392 | 616 mlcf->index = ngx_http_get_variable_index(cf, &ngx_http_memcached_key); |
1076 | 617 |
2392 | 618 if (mlcf->index == NGX_ERROR) { |
1076 | 619 return NGX_CONF_ERROR; |
620 } | |
621 | |
581 | 622 return NGX_CONF_OK; |
623 } |