comparison src/http/modules/proxy/ngx_http_proxy_handler.c @ 166:389d7ee9fa60

nginx-0.0.1-2003-10-30-11:51:06 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 30 Oct 2003 08:51:06 +0000
parents 894a01c6aea3
children ba5dbb949603
comparison
equal deleted inserted replaced
165:894a01c6aea3 166:389d7ee9fa60
36 void *conf); 36 void *conf);
37 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, 37 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
38 ngx_http_proxy_upstream_t *u); 38 ngx_http_proxy_upstream_t *u);
39 39
40 40
41 static ngx_command_t ngx_http_proxy_commands[] = { 41 static ngx_conf_bitmask_t next_upstream_masks[] = {
42 42 { ngx_string("error"), NGX_HTTP_PROXY_FT_ERROR },
43 {ngx_string("proxy_pass"), 43 { ngx_string("timeout"), NGX_HTTP_PROXY_FT_TIMEOUT },
44 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 44 { ngx_string("http_header"), NGX_HTTP_PROXY_FT_HTTP_HEADER },
45 ngx_http_proxy_set_pass, 45 { ngx_string("http_500"), NGX_HTTP_PROXY_FT_HTTP_500 },
46 NGX_HTTP_LOC_CONF_OFFSET, 46 { ngx_null_string, 0 }
47 0, 47 };
48 NULL}, 48
49 49 static ngx_command_t ngx_http_proxy_commands[] = {
50 {ngx_string("proxy_request_buffer_size"), 50
51 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 51 { ngx_string("proxy_pass"),
52 ngx_conf_set_size_slot, 52 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
53 NGX_HTTP_LOC_CONF_OFFSET, 53 ngx_http_proxy_set_pass,
54 offsetof(ngx_http_proxy_loc_conf_t, request_buffer_size), 54 NGX_HTTP_LOC_CONF_OFFSET,
55 NULL}, 55 0,
56 56 NULL },
57 {ngx_string("proxy_connect_timeout"), 57
58 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 58 { ngx_string("proxy_request_buffer_size"),
59 ngx_conf_set_msec_slot, 59 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
60 NGX_HTTP_LOC_CONF_OFFSET, 60 ngx_conf_set_size_slot,
61 offsetof(ngx_http_proxy_loc_conf_t, connect_timeout), 61 NGX_HTTP_LOC_CONF_OFFSET,
62 NULL}, 62 offsetof(ngx_http_proxy_loc_conf_t, request_buffer_size),
63 63 NULL },
64 {ngx_string("proxy_send_timeout"), 64
65 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 65 { ngx_string("proxy_connect_timeout"),
66 ngx_conf_set_msec_slot, 66 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
67 NGX_HTTP_LOC_CONF_OFFSET, 67 ngx_conf_set_msec_slot,
68 offsetof(ngx_http_proxy_loc_conf_t, send_timeout), 68 NGX_HTTP_LOC_CONF_OFFSET,
69 NULL}, 69 offsetof(ngx_http_proxy_loc_conf_t, connect_timeout),
70 70 NULL },
71 {ngx_string("proxy_header_buffer_size"), 71
72 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 72 { ngx_string("proxy_send_timeout"),
73 ngx_conf_set_size_slot, 73 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
74 NGX_HTTP_LOC_CONF_OFFSET, 74 ngx_conf_set_msec_slot,
75 offsetof(ngx_http_proxy_loc_conf_t, header_buffer_size), 75 NGX_HTTP_LOC_CONF_OFFSET,
76 NULL}, 76 offsetof(ngx_http_proxy_loc_conf_t, send_timeout),
77 77 NULL },
78 {ngx_string("proxy_read_timeout"), 78
79 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 79 { ngx_string("proxy_header_buffer_size"),
80 ngx_conf_set_msec_slot, 80 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
81 NGX_HTTP_LOC_CONF_OFFSET, 81 ngx_conf_set_size_slot,
82 offsetof(ngx_http_proxy_loc_conf_t, read_timeout), 82 NGX_HTTP_LOC_CONF_OFFSET,
83 NULL}, 83 offsetof(ngx_http_proxy_loc_conf_t, header_buffer_size),
84 84 NULL },
85 {ngx_string("proxy_buffers"), 85
86 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, 86 { ngx_string("proxy_read_timeout"),
87 ngx_conf_set_bufs_slot, 87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
88 NGX_HTTP_LOC_CONF_OFFSET, 88 ngx_conf_set_msec_slot,
89 offsetof(ngx_http_proxy_loc_conf_t, bufs), 89 NGX_HTTP_LOC_CONF_OFFSET,
90 NULL}, 90 offsetof(ngx_http_proxy_loc_conf_t, read_timeout),
91 91 NULL },
92 {ngx_string("proxy_busy_buffers_size"), 92
93 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 93 { ngx_string("proxy_buffers"),
94 ngx_conf_set_size_slot, 94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
95 NGX_HTTP_LOC_CONF_OFFSET, 95 ngx_conf_set_bufs_slot,
96 offsetof(ngx_http_proxy_loc_conf_t, busy_buffers_size), 96 NGX_HTTP_LOC_CONF_OFFSET,
97 NULL}, 97 offsetof(ngx_http_proxy_loc_conf_t, bufs),
98 98 NULL },
99 {ngx_string("proxy_temp_path"), 99
100 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, 100 { ngx_string("proxy_busy_buffers_size"),
101 ngx_conf_set_path_slot, 101 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
102 NGX_HTTP_LOC_CONF_OFFSET, 102 ngx_conf_set_size_slot,
103 offsetof(ngx_http_proxy_loc_conf_t, temp_path), 103 NGX_HTTP_LOC_CONF_OFFSET,
104 NULL}, 104 offsetof(ngx_http_proxy_loc_conf_t, busy_buffers_size),
105 105 NULL },
106 {ngx_string("proxy_temp_file_write_size"), 106
107 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 107 { ngx_string("proxy_temp_path"),
108 ngx_conf_set_size_slot, 108 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
109 NGX_HTTP_LOC_CONF_OFFSET, 109 ngx_conf_set_path_slot,
110 offsetof(ngx_http_proxy_loc_conf_t, temp_file_write_size), 110 NGX_HTTP_LOC_CONF_OFFSET,
111 NULL}, 111 offsetof(ngx_http_proxy_loc_conf_t, temp_path),
112 112 NULL },
113 {ngx_string("proxy_pass_server"), 113
114 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, 114 { ngx_string("proxy_temp_file_write_size"),
115 ngx_conf_set_flag_slot, 115 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
116 NGX_HTTP_LOC_CONF_OFFSET, 116 ngx_conf_set_size_slot,
117 offsetof(ngx_http_proxy_loc_conf_t, pass_server), 117 NGX_HTTP_LOC_CONF_OFFSET,
118 NULL}, 118 offsetof(ngx_http_proxy_loc_conf_t, temp_file_write_size),
119 119 NULL },
120 ngx_null_command 120
121 { ngx_string("proxy_pass_server"),
122 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
123 ngx_conf_set_flag_slot,
124 NGX_HTTP_LOC_CONF_OFFSET,
125 offsetof(ngx_http_proxy_loc_conf_t, pass_server),
126 NULL },
127
128 { ngx_string("proxy_next_upstream"),
129 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY,
130 ngx_conf_set_bitmask_slot,
131 NGX_HTTP_LOC_CONF_OFFSET,
132 offsetof(ngx_http_proxy_loc_conf_t, next_upstream),
133 &next_upstream_masks },
134
135 ngx_null_command
121 }; 136 };
122 137
123 138
124 ngx_http_module_t ngx_http_proxy_module_ctx = { 139 ngx_http_module_t ngx_http_proxy_module_ctx = {
125 NULL, /* create main configuration */ 140 NULL, /* create main configuration */
229 { 244 {
230 ngx_http_proxy_ctx_t *p = data; 245 ngx_http_proxy_ctx_t *p = data;
231 246
232 ngx_chain_t *cl; 247 ngx_chain_t *cl;
233 ngx_http_request_t *r; 248 ngx_http_request_t *r;
234 ngx_output_chain_ctx_t *out_ctx; 249 ngx_output_chain_ctx_t *octx;
235 ngx_chain_write_ctx_t *write_ctx; 250 ngx_chain_writer_ctx_t *wctx;
236 251
237 252
238 r = p->request; 253 r = p->request;
239 254
240 ngx_log_debug(r->connection->log, "timer_set: %d" _ 255 ngx_log_debug(r->connection->log, "timer_set: %d" _
260 p->saved_handler = r->connection->log->handler; 275 p->saved_handler = r->connection->log->handler;
261 r->connection->log->data = p; 276 r->connection->log->data = p;
262 r->connection->log->handler = ngx_http_proxy_log_error; 277 r->connection->log->handler = ngx_http_proxy_log_error;
263 p->action = "connecting to upstream"; 278 p->action = "connecting to upstream";
264 279
265 out_ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); 280 octx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
266 if (out_ctx == NULL) { 281 if (octx == NULL) {
267 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); 282 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
268 return; 283 return;
269 } 284 }
270 285
271 p->output_chain_ctx = out_ctx; 286 p->output_chain_ctx = octx;
272 287
273 if (r->request_body_hunk) { 288 if (r->request_body_hunk) {
274 out_ctx->free = ngx_alloc_chain_link(r->pool); 289 octx->free = ngx_alloc_chain_link(r->pool);
275 if (out_ctx->free == NULL) { 290 if (octx->free == NULL) {
276 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); 291 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
277 } 292 }
278 out_ctx->free->hunk = r->request_body_hunk; 293 octx->free->hunk = r->request_body_hunk;
279 out_ctx->free->next = NULL; 294 octx->free->next = NULL;
280 } 295 }
281 296
282 out_ctx->sendfile = r->sendfile; 297 octx->sendfile = r->sendfile;
283 out_ctx->pool = r->pool; 298 octx->pool = r->pool;
284 out_ctx->bufs.num = 1; 299 octx->bufs.num = 1;
285 out_ctx->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; 300 octx->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
286 out_ctx->output_filter = (ngx_output_chain_filter_pt) ngx_chain_write; 301 octx->output_filter = (ngx_output_chain_filter_pt) ngx_chain_writer;
287 302
288 write_ctx = ngx_pcalloc(r->pool, sizeof(ngx_chain_write_ctx_t)); 303 wctx = ngx_pcalloc(r->pool, sizeof(ngx_chain_writer_ctx_t));
289 if (write_ctx == NULL) { 304 if (wctx == NULL) {
290 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); 305 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
291 return; 306 return;
292 } 307 }
293 308
294 out_ctx->output_ctx = write_ctx; 309 octx->output_ctx = wctx;
295 write_ctx->pool = r->pool; 310 wctx->pool = r->pool;
296 write_ctx->last = &write_ctx->out; 311 wctx->last = &wctx->out;
297 312
298 ngx_http_proxy_send_request(p); 313 ngx_http_proxy_send_request(p);
299 } 314 }
300 315
301 316
337 len += header[i].key.len + 2 + header[i].value.len + 2; 352 len += header[i].key.len + 2 + header[i].value.len + 2;
338 } 353 }
339 354
340 /* STUB */ len++; 355 /* STUB */ len++;
341 356
342 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL); 357 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len), NULL);
343 ngx_alloc_link_and_set_hunk(chain, h, r->pool, NULL); 358 ngx_alloc_link_and_set_hunk(chain, h, r->pool, NULL);
344 359
345 360
346 /* the request line */ 361 /* the request line */
347 362
437 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) 452 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
438 { 453 {
439 int rc; 454 int rc;
440 ngx_chain_t *cl; 455 ngx_chain_t *cl;
441 ngx_connection_t *c; 456 ngx_connection_t *c;
442 ngx_chain_write_ctx_t *ctx; 457 ngx_chain_writer_ctx_t *wctx;
443 458
444 c = p->upstream.connection; 459 c = p->upstream.connection;
445 460
446 for ( ;; ) { 461 for ( ;; ) {
447 462
448 if (c) { 463 if (c) {
449 p->action = "sending request to upstream"; 464 p->action = "sending request to upstream";
450 ctx = p->output_chain_ctx->output_ctx; 465 wctx = p->output_chain_ctx->output_ctx;
451 ctx->connection = c; 466 wctx->connection = c;
452 rc = ngx_output_chain(p->output_chain_ctx, 467 rc = ngx_output_chain(p->output_chain_ctx,
453 !p->request_sent ? p->request->request_hunks: 468 !p->request_sent ? p->request->request_hunks:
454 NULL); 469 NULL);
455 470
456 if (rc != NGX_ERROR) { 471 if (rc != NGX_ERROR) {
502 return; 517 return;
503 } 518 }
504 519
505 ngx_event_connect_peer_failed(&p->upstream); 520 ngx_event_connect_peer_failed(&p->upstream);
506 ngx_http_proxy_close_connection(c); 521 ngx_http_proxy_close_connection(c);
522
523 if (p->upstream.tries == 0
524 || !(p->lcf->next_upstream & NGX_HTTP_PROXY_FT_ERROR))
525 {
526 ngx_http_proxy_finalize_request(p,
527 p->timedout ? NGX_HTTP_GATEWAY_TIME_OUT:
528 NGX_HTTP_BAD_GATEWAY);
529 return;
530 }
531
532 if (!p->fatal_error) {
533 ngx_http_proxy_send_request(p);
534 return;
535 }
507 } 536 }
508 537
509 for ( ;; ) { 538 for ( ;; ) {
510 p->action = "connecting to upstream"; 539 p->action = "connecting to upstream";
511 540
584 return; 613 return;
585 } 614 }
586 615
587 if (p->header_in == NULL) { 616 if (p->header_in == NULL) {
588 p->header_in = ngx_create_temp_hunk(p->request->pool, 617 p->header_in = ngx_create_temp_hunk(p->request->pool,
589 p->lcf->header_buffer_size, 618 p->lcf->header_buffer_size);
590 0, 0);
591 if (p->header_in == NULL) { 619 if (p->header_in == NULL) {
592 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); 620 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
593 return; 621 return;
594 } 622 }
595 p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; 623 p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
744 ((char *) &p->headers_in + headers_in[i].offset)) = h; 772 ((char *) &p->headers_in + headers_in[i].offset)) = h;
745 break; 773 break;
746 } 774 }
747 } 775 }
748 776
749 ngx_log_debug(c->log, "HTTP proxy header: %08X '%s: %s'" _ 777 ngx_log_debug(c->log, "HTTP proxy header: '%s: %s'" _
750 h _ h->key.data _ h->value.data); 778 h->key.data _ h->value.data);
751 779
752 continue; 780 continue;
753 781
754 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { 782 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
755 783
949 } 977 }
950 ep->preread_hunks->hunk = p->header_in; 978 ep->preread_hunks->hunk = p->header_in;
951 ep->preread_hunks->next = NULL; 979 ep->preread_hunks->next = NULL;
952 980
953 ep->preread_size = p->header_in->last - p->header_in->pos; 981 ep->preread_size = p->header_in->last - p->header_in->pos;
982
983 if (ngx_event_flags & NGX_USE_AIO_EVENT) {
984
985 /* the posted aio operation can currupt shadow buf */
986 ep->single_buf = 1;
987 }
954 988
955 /* 989 /*
956 * event_pipe would do p->header_in->last += ep->preread_size 990 * event_pipe would do p->header_in->last += ep->preread_size
957 * as though these bytes were read. 991 * as though these bytes were read.
958 */ 992 */
1403 1437
1404 conf->bufs.num = 0; 1438 conf->bufs.num = 0;
1405 1439
1406 conf->path = NULL; 1440 conf->path = NULL;
1407 1441
1442 conf->next_upstream = 0;
1443
1408 conf->upstreams = NULL; 1444 conf->upstreams = NULL;
1409 conf->peers = NULL; 1445 conf->peers = NULL;
1410 1446
1411 */ 1447 */
1412 1448
1425 1461
1426 conf->temp_file_write_size = NGX_CONF_UNSET; 1462 conf->temp_file_write_size = NGX_CONF_UNSET;
1427 1463
1428 /* "proxy_cyclic_temp_file" is disabled */ 1464 /* "proxy_cyclic_temp_file" is disabled */
1429 conf->cyclic_temp_file = 0; 1465 conf->cyclic_temp_file = 0;
1430
1431 conf->next_upstream = NGX_CONF_UNSET;
1432 1466
1433 conf->pass_server = NGX_CONF_UNSET; 1467 conf->pass_server = NGX_CONF_UNSET;
1434 1468
1435 return conf; 1469 return conf;
1436 } 1470 }
1462 #endif 1496 #endif
1463 1497
1464 ngx_conf_merge_size_value(conf->temp_file_write_size, 1498 ngx_conf_merge_size_value(conf->temp_file_write_size,
1465 prev->temp_file_write_size, 16384); 1499 prev->temp_file_write_size, 16384);
1466 1500
1467 ngx_conf_merge_value(conf->next_upstream, prev->next_upstream, 1501 ngx_conf_merge_bitmask_value(conf->next_upstream, prev->next_upstream,
1468 (NGX_HTTP_PROXY_FT_ERROR|NGX_HTTP_PROXY_FT_TIMEOUT)); 1502 (NGX_HTTP_PROXY_FT_ERROR|NGX_HTTP_PROXY_FT_TIMEOUT));
1469 1503
1470 ngx_conf_merge_path_value(conf->temp_path, prev->temp_path, 1504 ngx_conf_merge_path_value(conf->temp_path, prev->temp_path,
1471 "temp", 1, 2, 0, cf->pool); 1505 "temp", 1, 2, 0, cf->pool);
1472 1506
1473 ngx_conf_merge_value(conf->pass_server, prev->pass_server, 0); 1507 ngx_conf_merge_value(conf->pass_server, prev->pass_server, 0);