comparison src/http/modules/proxy/ngx_http_proxy_handler.c @ 155:46eb23d9471d

nginx-0.0.1-2003-10-22-20:38:26 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 22 Oct 2003 16:38:26 +0000
parents eac26585476e
children afc333135a6b
comparison
equal deleted inserted replaced
154:eac26585476e 155:46eb23d9471d
24 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc); 24 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc);
25 static void ngx_http_proxy_close_connection(ngx_connection_t *c); 25 static void ngx_http_proxy_close_connection(ngx_connection_t *c);
26 26
27 static int ngx_http_proxy_init(ngx_cycle_t *cycle); 27 static int ngx_http_proxy_init(ngx_cycle_t *cycle);
28 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); 28 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf);
29 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
30 void *parent, void *child);
29 31
30 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, 32 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
31 void *conf); 33 void *conf);
32 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, 34 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
33 ngx_http_proxy_upstream_t *u); 35 ngx_http_proxy_upstream_t *u);
40 ngx_http_proxy_set_pass, 42 ngx_http_proxy_set_pass,
41 NGX_HTTP_LOC_CONF_OFFSET, 43 NGX_HTTP_LOC_CONF_OFFSET,
42 0, 44 0,
43 NULL}, 45 NULL},
44 46
47 {ngx_string("proxy_connect_timeout"),
48 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
49 ngx_conf_set_msec_slot,
50 NGX_HTTP_LOC_CONF_OFFSET,
51 offsetof(ngx_http_proxy_loc_conf_t, connect_timeout),
52 NULL},
53
54 {ngx_string("proxy_send_timeout"),
55 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
56 ngx_conf_set_msec_slot,
57 NGX_HTTP_LOC_CONF_OFFSET,
58 offsetof(ngx_http_proxy_loc_conf_t, send_timeout),
59 NULL},
60
61 {ngx_string("proxy_header_buffer_size"),
62 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
63 ngx_conf_set_size_slot,
64 NGX_HTTP_LOC_CONF_OFFSET,
65 offsetof(ngx_http_proxy_loc_conf_t, header_buffer_size),
66 NULL},
67
68 {ngx_string("proxy_read_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_proxy_loc_conf_t, read_timeout),
73 NULL},
74
75 {ngx_string("proxy_buffers"),
76 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
77 ngx_conf_set_bufs_slot,
78 NGX_HTTP_LOC_CONF_OFFSET,
79 offsetof(ngx_http_proxy_loc_conf_t, bufs),
80 NULL},
81
82 {ngx_string("proxy_busy_buffers_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_proxy_loc_conf_t, busy_buffers_size),
87 NULL},
88
89 {ngx_string("proxy_temp_path"),
90 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
91 ngx_conf_set_path_slot,
92 NGX_HTTP_LOC_CONF_OFFSET,
93 offsetof(ngx_http_proxy_loc_conf_t, temp_path),
94 NULL},
95
96 {ngx_string("proxy_temp_file_write_size"),
97 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
98 ngx_conf_set_size_slot,
99 NGX_HTTP_LOC_CONF_OFFSET,
100 offsetof(ngx_http_proxy_loc_conf_t, temp_file_write_size),
101 NULL},
102
45 ngx_null_command 103 ngx_null_command
46 }; 104 };
47 105
48 106
49 ngx_http_module_t ngx_http_proxy_module_ctx = { 107 ngx_http_module_t ngx_http_proxy_module_ctx = {
52 110
53 NULL, /* create server configuration */ 111 NULL, /* create server configuration */
54 NULL, /* merge server configuration */ 112 NULL, /* merge server configuration */
55 113
56 ngx_http_proxy_create_loc_conf, /* create location configration */ 114 ngx_http_proxy_create_loc_conf, /* create location configration */
57 #if 0 115 ngx_http_proxy_merge_loc_conf /* merge location configration */
58 ngx_http_proxy_merge_conf /* merge location configration */
59 #endif
60
61 NULL
62 }; 116 };
63 117
64 118
65 ngx_module_t ngx_http_proxy_module = { 119 ngx_module_t ngx_http_proxy_module = {
66 NGX_MODULE, 120 NGX_MODULE,
106 }; 160 };
107 161
108 162
109 static char http_version[] = " HTTP/1.0" CRLF; 163 static char http_version[] = " HTTP/1.0" CRLF;
110 static char host_header[] = "Host: "; 164 static char host_header[] = "Host: ";
111 static char conn_close_header[] = "Connection: close" CRLF; 165 static char connection_close_header[] = "Connection: close" CRLF;
112 166
113 167
114 168
115 static int ngx_http_proxy_handler(ngx_http_request_t *r) 169 static int ngx_http_proxy_handler(ngx_http_request_t *r)
116 { 170 {
166 + r->uri.len - p->location_len 220 + r->uri.len - p->location_len
167 + 1 + r->args.len /* 1 is for "?" */ 221 + 1 + r->args.len /* 1 is for "?" */
168 + sizeof(http_version) - 1 222 + sizeof(http_version) - 1
169 + sizeof(host_header) - 1 + p->host_header.len + 2 223 + sizeof(host_header) - 1 + p->host_header.len + 2
170 /* 2 is for "\r\n" */ 224 /* 2 is for "\r\n" */
171 + sizeof(conn_close_header) - 1 225 + sizeof(connection_close_header) - 1
172 + 2; /* 2 is for "\r\n" at the header end */ 226 + 2; /* 2 is for "\r\n" at the header end */
173 227
174 header = (ngx_table_elt_t *) r->headers_in.headers->elts; 228 header = (ngx_table_elt_t *) r->headers_in.headers->elts;
175 for (i = 0; i < r->headers_in.headers->nelts; i++) { 229 for (i = 0; i < r->headers_in.headers->nelts; i++) {
176 230
187 } 241 }
188 242
189 /* STUB */ len++; 243 /* STUB */ len++;
190 244
191 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL); 245 ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL);
192 ngx_add_hunk_to_chain(chain, h, r->pool, NULL); 246 ngx_alloc_link_and_set_hunk(chain, h, r->pool, NULL);
193 247
194 248
195 /* the request line */ 249 /* the request line */
196 250
197 h->last = ngx_cpymem(h->last, http_methods[p->method - 1].data, 251 h->last = ngx_cpymem(h->last, http_methods[p->method - 1].data,
218 *(h->last++) = CR; *(h->last++) = LF; 272 *(h->last++) = CR; *(h->last++) = LF;
219 273
220 274
221 /* the "Connection: close" header */ 275 /* the "Connection: close" header */
222 276
223 h->last = ngx_cpymem(h->last, conn_close_header, 277 h->last = ngx_cpymem(h->last, connection_close_header,
224 sizeof(conn_close_header) - 1); 278 sizeof(connection_close_header) - 1);
225 279
226 280
227 for (i = 0; i < r->headers_in.headers->nelts; i++) { 281 for (i = 0; i < r->headers_in.headers->nelts; i++) {
228 282
229 if (&header[i] == r->headers_in.host) { 283 if (&header[i] == r->headers_in.host) {
339 393
340 if (p->upstream.tries > 1) { 394 if (p->upstream.tries > 1) {
341 #if (NGX_SUPPRESS_WARN) 395 #if (NGX_SUPPRESS_WARN)
342 le = NULL; 396 le = NULL;
343 #endif 397 #endif
344 p->work_request_hunks = 398 p->work_request_hunks = ngx_alloc_chain_link(p->request->pool);
345 ngx_alloc_chain_entry(p->request->pool);
346 if (p->work_request_hunks == NULL) { 399 if (p->work_request_hunks == NULL) {
347 ngx_http_proxy_finalize_request(p, 400 ngx_http_proxy_finalize_request(p,
348 NGX_HTTP_INTERNAL_SERVER_ERROR); 401 NGX_HTTP_INTERNAL_SERVER_ERROR);
349 return; 402 return;
350 } 403 }
355 te->hunk = ce->hunk; 408 te->hunk = ce->hunk;
356 *le = te; 409 *le = te;
357 le = &te->next; 410 le = &te->next;
358 ce->hunk->pos = ce->hunk->start; 411 ce->hunk->pos = ce->hunk->start;
359 412
360 te = ngx_alloc_chain_entry(p->request->pool); 413 te = ngx_alloc_chain_link(p->request->pool);
361 if (te == NULL) { 414 if (te == NULL) {
362 ngx_http_proxy_finalize_request(p, 415 ngx_http_proxy_finalize_request(p,
363 NGX_HTTP_INTERNAL_SERVER_ERROR); 416 NGX_HTTP_INTERNAL_SERVER_ERROR);
364 return; 417 return;
365 } 418 }
402 return; 455 return;
403 } 456 }
404 457
405 if (p->header_in == NULL) { 458 if (p->header_in == NULL) {
406 p->header_in = ngx_create_temp_hunk(p->request->pool, 459 p->header_in = ngx_create_temp_hunk(p->request->pool,
407 p->lcf->header_size, 460 p->lcf->header_buffer_size,
408 0, 0); 461 0, 0);
409 if (p->header_in == NULL) { 462 if (p->header_in == NULL) {
410 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); 463 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
411 return; 464 return;
412 } 465 }
561 614
562 } else if (rc != NGX_AGAIN) { 615 } else if (rc != NGX_AGAIN) {
563 616
564 /* there was error while a header line parsing */ 617 /* there was error while a header line parsing */
565 618
566 #if 0
567 ngx_http_header_parse_error(r, rc);
568 ngx_http_proxy_next_upstream(p);
569 #endif
570 ngx_http_proxy_finalize_request(p, NGX_HTTP_BAD_GATEWAY); 619 ngx_http_proxy_finalize_request(p, NGX_HTTP_BAD_GATEWAY);
571 return; 620 return;
572 } 621 }
573 622
574 /* NGX_AGAIN: a header line parsing is still not complete */ 623 /* NGX_AGAIN: a header line parsing is still not complete */
690 r->headers_out.date = p->headers_in.date; 739 r->headers_out.date = p->headers_in.date;
691 } 740 }
692 741
693 /* */ 742 /* */
694 743
695 #if 0 744
696 /* TODO: look "Content-Length" */ 745 /* TODO: preallocate event_pipe hunks, look "Content-Length" */
697 p->block_size = p->lcf->block_size;
698 #endif
699 746
700 r->headers_out.status = p->status; 747 r->headers_out.status = p->status;
701 748
702 rc = ngx_http_send_header(r); 749 rc = ngx_http_send_header(r);
703 750
713 ep->output_filter = (ngx_event_pipe_output_filter_pt) 760 ep->output_filter = (ngx_event_pipe_output_filter_pt)
714 ngx_http_output_filter; 761 ngx_http_output_filter;
715 ep->output_ctx = r; 762 ep->output_ctx = r;
716 ep->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; 763 ep->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
717 ep->bufs = p->lcf->bufs; 764 ep->bufs = p->lcf->bufs;
718 ep->max_busy_len = p->lcf->max_busy_len; 765 ep->busy_size = p->lcf->busy_buffers_size;
719 ep->upstream = p->upstream.connection; 766 ep->upstream = p->upstream.connection;
720 ep->downstream = r->connection; 767 ep->downstream = r->connection;
721 ep->pool = r->pool; 768 ep->pool = r->pool;
722 ep->log = r->connection->log; 769 ep->log = r->connection->log;
723 ep->temp_path = p->lcf->temp_path; 770 ep->temp_path = p->lcf->temp_path;
734 ep->max_temp_file_size = p->lcf->max_temp_file_size; 781 ep->max_temp_file_size = p->lcf->max_temp_file_size;
735 ep->temp_file_write_size = p->lcf->temp_file_write_size; 782 ep->temp_file_write_size = p->lcf->temp_file_write_size;
736 ep->temp_file_warn = "an upstream response is buffered " 783 ep->temp_file_warn = "an upstream response is buffered "
737 "to a temporary file"; 784 "to a temporary file";
738 785
739 ep->preread_hunks = ngx_alloc_chain_entry(r->pool); 786 ep->preread_hunks = ngx_alloc_chain_link(r->pool);
740 if (ep->preread_hunks == NULL) { 787 if (ep->preread_hunks == NULL) {
741 ngx_http_proxy_finalize_request(p, 0); 788 ngx_http_proxy_finalize_request(p, 0);
742 return; 789 return;
743 } 790 }
744 ep->preread_hunks->hunk = p->header_in; 791 ep->preread_hunks->hunk = p->header_in;
756 803
757 if (p->lcf->cyclic_temp_file) { 804 if (p->lcf->cyclic_temp_file) {
758 805
759 /* 806 /*
760 * we need to disable the use of sendfile() if we use cyclic temp file 807 * we need to disable the use of sendfile() if we use cyclic temp file
761 * because the writing a new data can interfere with sendfile 808 * because the writing a new data can interfere with sendfile()
762 * that uses the same kernel file pages 809 * that uses the same kernel file pages (at least on FreeBSD)
763 */ 810 */
764 811
765 ep->cyclic_temp_file = 1; 812 ep->cyclic_temp_file = 1;
766 r->sendfile = 0; 813 r->sendfile = 0;
767 814
1158 1205
1159 ngx_test_null(conf, 1206 ngx_test_null(conf,
1160 ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)), 1207 ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)),
1161 NGX_CONF_ERROR); 1208 NGX_CONF_ERROR);
1162 1209
1163 /* STUB */ 1210 /* set by ngx_pcalloc():
1164 ngx_test_null(conf->peers, ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)), 1211
1165 NGX_CONF_ERROR); 1212 conf->bufs.num = 0;
1166 1213
1167 conf->peers->number = 1; 1214 conf->path = NULL;
1168 conf->peers->peers[0].addr = inet_addr("127.0.0.1"); 1215
1169 conf->peers->peers[0].host.data = "localhost"; 1216 conf->upstreams = NULL;
1170 conf->peers->peers[0].host.len = sizeof("localhost") - 1; 1217 conf->peers = NULL;
1171 conf->peers->peers[0].port = htons(9000); 1218
1172 conf->peers->peers[0].addr_port_text.data = "127.0.0.1:9000"; 1219 */
1173 conf->peers->peers[0].addr_port_text.len = sizeof("127.0.0.1:9000") - 1; 1220
1174 1221 conf->connect_timeout = NGX_CONF_UNSET;
1175 conf->connect_timeout = 30000; 1222 conf->send_timeout = NGX_CONF_UNSET;
1176 conf->send_timeout = 30000; 1223 conf->header_buffer_size = NGX_CONF_UNSET;
1177 conf->header_size = 4096; 1224 conf->read_timeout = NGX_CONF_UNSET;
1178 conf->read_timeout = 30000; 1225 conf->busy_buffers_size = NGX_CONF_UNSET;
1179 1226
1180 conf->bufs.num = 5; 1227 /*
1181 conf->bufs.size = 4096; 1228 * "proxy_max_temp_file_size" is hardcoded to 1G for reverse proxy,
1182 conf->max_busy_len = 8192; 1229 * it should be configurable in the generic proxy
1183 1230 */
1184 1231 conf->max_temp_file_size = 1024 * 1024 * 1024;
1185 /* CHECK in _init conf->max_temp_size >= conf->bufs.size !!! */ 1232
1186 conf->max_temp_file_size = 4096 * 3; 1233 conf->temp_file_write_size = NGX_CONF_UNSET;
1187 1234
1188 1235 /* "proxy_cyclic_temp_file" is disabled */
1189 conf->temp_file_write_size = 4096 * 2; 1236 conf->cyclic_temp_file = 0;
1190 conf->cyclic_temp_file= 1;
1191
1192 ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)),
1193 NULL);
1194
1195 conf->temp_path->name.data = "temp";
1196 conf->temp_path->name.len = 4;
1197 conf->temp_path->level[0] = 1;
1198 conf->temp_path->level[1] = 2;
1199 conf->temp_path->level[2] = 3;
1200 conf->temp_path->len = 0;
1201
1202 for (i = 0; i < 3; i++) {
1203 if (conf->temp_path->level[i] == 0) {
1204 break;
1205 }
1206 conf->temp_path->len += conf->temp_path->level[i] + 1;
1207 }
1208
1209 /* */
1210 1237
1211 return conf; 1238 return conf;
1212 } 1239 }
1240
1241
1242 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
1243 void *parent, void *child)
1244 {
1245 ngx_http_proxy_loc_conf_t *prev = parent;
1246 ngx_http_proxy_loc_conf_t *conf = child;
1247
1248 ngx_conf_merge_msec_value(conf->connect_timeout,
1249 prev->connect_timeout, 60000);
1250 ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 30000);
1251 ngx_conf_merge_size_value(conf->header_buffer_size,
1252 prev->header_buffer_size, 4096);
1253 ngx_conf_merge_msec_value(conf->read_timeout, prev->read_timeout, 30000);
1254 ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 8, 4096);
1255 ngx_conf_merge_size_value(conf->busy_buffers_size,
1256 prev->busy_buffers_size, 8192);
1257
1258 #if 0
1259 if (conf->max_temp_file_size > conf->bufs.size) {
1260 return "\"proxy_max_temp_file\" must be greater "
1261 "than one of the \"proxy_buffers\"";
1262 }
1263 #endif
1264
1265 ngx_conf_merge_size_value(conf->temp_file_write_size,
1266 prev->temp_file_write_size, 16384);
1267
1268 ngx_conf_merge_path_value(conf->temp_path, prev->temp_path,
1269 "temp", 1, 2, 0, cf->pool);
1270
1271 return NULL;
1272 }
1273
1213 1274
1214 1275
1215 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, 1276 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
1216 void *conf) 1277 void *conf)
1217 { 1278 {
1335 clcf->handler = ngx_http_proxy_handler; 1396 clcf->handler = ngx_http_proxy_handler;
1336 1397
1337 return NULL; 1398 return NULL;
1338 } 1399 }
1339 1400
1401
1340 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, 1402 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
1341 ngx_http_proxy_upstream_t *u) 1403 ngx_http_proxy_upstream_t *u)
1342 { 1404 {
1343 size_t i; 1405 size_t i;
1344 1406