comparison src/http/modules/proxy/ngx_http_proxy_handler.c @ 159:981e4af2a425

nginx-0.0.1-2003-10-24-20:10:38 import
author Igor Sysoev <igor@sysoev.ru>
date Fri, 24 Oct 2003 16:10:38 +0000
parents d377ee423603
children e7e094d34162
comparison
equal deleted inserted replaced
158:d377ee423603 159:981e4af2a425
21 21
22 static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p); 22 static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p);
23 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p); 23 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p);
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
27 static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len);
26 28
27 static int ngx_http_proxy_init(ngx_cycle_t *cycle); 29 static int ngx_http_proxy_init(ngx_cycle_t *cycle);
28 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); 30 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, 31 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
30 void *parent, void *child); 32 void *parent, void *child);
179 p->upstream.tries = p->lcf->peers->number; 181 p->upstream.tries = p->lcf->peers->number;
180 182
181 p->request = r; 183 p->request = r;
182 p->method = r->method; 184 p->method = r->method;
183 185
184 /* TODO: from lcf->upstream */ 186 /* TODO: we currently support reverse proxy only */
185 p->uri.data = "/"; 187 p->accel = 1;
186 p->uri.len = 1;
187 p->location_len = 1;
188
189 /* STUB */ p->accel = 1;
190 188
191 ngx_test_null(p->request_hunks, ngx_http_proxy_create_request(p), 189 ngx_test_null(p->request_hunks, ngx_http_proxy_create_request(p),
192 NGX_HTTP_INTERNAL_SERVER_ERROR); 190 NGX_HTTP_INTERNAL_SERVER_ERROR);
193 191
192 /* TODO: read request body */
193
194 p->upstream.log = r->connection->log;
195 p->saved_ctx = r->connection->log->data;
196 r->connection->log->data = p;;
197 r->connection->log->handler = ngx_http_proxy_log_error;
194 p->action = "connecting to upstream"; 198 p->action = "connecting to upstream";
195 199
196 /* TODO: log->data would be changed, how to restore log->data ? */
197 p->upstream.log = r->connection->log;
198
199 ngx_http_proxy_send_request(p); 200 ngx_http_proxy_send_request(p);
200 201
201 return NGX_DONE; 202 return NGX_DONE;
202 } 203 }
203 204
204 205
205 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) 206 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
206 { 207 {
207 int i; 208 int i;
208 size_t len; 209 size_t len;
209 ngx_hunk_t *h; 210 ngx_hunk_t *h;
210 ngx_chain_t *chain; 211 ngx_chain_t *chain;
211 ngx_table_elt_t *header; 212 ngx_table_elt_t *header;
212 ngx_http_request_t *r; 213 ngx_http_request_t *r;
214 ngx_http_proxy_upstream_t *u;
213 215
214 r = p->request; 216 r = p->request;
217 u = p->lcf->upstream;
215 218
216 len = http_methods[p->method - 1].len 219 len = http_methods[p->method - 1].len
217 + p->uri.len 220 + u->uri.len
218 + r->uri.len - p->location_len 221 + r->uri.len - u->location->len
219 + 1 + r->args.len /* 1 is for "?" */ 222 + 1 + r->args.len /* 1 is for "?" */
220 + sizeof(http_version) - 1 223 + sizeof(http_version) - 1
221 + sizeof(host_header) - 1 + p->lcf->upstream->host_header.len + 2 224 + sizeof(host_header) - 1 + u->host_header.len + 2
222 /* 2 is for "\r\n" */ 225 /* 2 is for "\r\n" */
223 + sizeof(connection_close_header) - 1 226 + sizeof(connection_close_header) - 1
224 + 2; /* 2 is for "\r\n" at the header end */ 227 + 2; /* 2 is for "\r\n" at the header end */
225 228
226 header = (ngx_table_elt_t *) r->headers_in.headers->elts; 229 header = (ngx_table_elt_t *) r->headers_in.headers->elts;
247 /* the request line */ 250 /* the request line */
248 251
249 h->last = ngx_cpymem(h->last, http_methods[p->method - 1].data, 252 h->last = ngx_cpymem(h->last, http_methods[p->method - 1].data,
250 http_methods[p->method - 1].len); 253 http_methods[p->method - 1].len);
251 254
252 h->last = ngx_cpymem(h->last, p->uri.data, p->uri.len); 255 h->last = ngx_cpymem(h->last, u->uri.data, u->uri.len);
253 256
254 h->last = ngx_cpymem(h->last, 257 h->last = ngx_cpymem(h->last,
255 r->uri.data + p->location_len, 258 r->uri.data + u->location->len,
256 r->uri.len - p->location_len); 259 r->uri.len - u->location->len);
257 260
258 if (r->args.len > 0) { 261 if (r->args.len > 0) {
259 *(h->last++) = '?'; 262 *(h->last++) = '?';
260 h->last = ngx_cpymem(h->last, r->args.data, r->args.len); 263 h->last = ngx_cpymem(h->last, r->args.data, r->args.len);
261 } 264 }
262 265
263 h->last = ngx_cpymem(h->last, http_version, sizeof(http_version) - 1); 266 h->last = ngx_cpymem(h->last, http_version, sizeof(http_version) - 1);
264 267
265 268
266 /* the "Host" header */ 269 /* "Host" header */
267 270
268 h->last = ngx_cpymem(h->last, host_header, sizeof(host_header) - 1); 271 h->last = ngx_cpymem(h->last, host_header, sizeof(host_header) - 1);
269 h->last = ngx_cpymem(h->last, p->lcf->upstream->host_header.data, 272 h->last = ngx_cpymem(h->last, u->host_header.data, u->host_header.len);
270 p->lcf->upstream->host_header.len);
271 *(h->last++) = CR; *(h->last++) = LF; 273 *(h->last++) = CR; *(h->last++) = LF;
272 274
273 275
274 /* the "Connection: close" header */ 276 /* "Connection: close" header */
275 277
276 h->last = ngx_cpymem(h->last, connection_close_header, 278 h->last = ngx_cpymem(h->last, connection_close_header,
277 sizeof(connection_close_header) - 1); 279 sizeof(connection_close_header) - 1);
278 280
279 281
305 } 307 }
306 308
307 /* add "\r\n" at the header end */ 309 /* add "\r\n" at the header end */
308 *(h->last++) = CR; *(h->last++) = LF; 310 *(h->last++) = CR; *(h->last++) = LF;
309 311
310 /* STUB */ *(h->last++) = '\0'; 312 /* STUB */ *(h->last) = '\0';
311 ngx_log_debug(r->connection->log, "PROXY:\n'%s'" _ h->pos); 313 ngx_log_debug(r->connection->log, "PROXY:\n'%s'" _ h->pos);
312 314
313 return chain; 315 return chain;
314 } 316 }
315 317
320 ngx_http_proxy_ctx_t *p; 322 ngx_http_proxy_ctx_t *p;
321 323
322 c = wev->data; 324 c = wev->data;
323 p = c->data; 325 p = c->data;
324 326
327 if (wev->timedout) {
328 p->timedout = 1;
329 ngx_http_proxy_next_upstream(p);
330 return;
331 }
332
325 ngx_http_proxy_send_request(p); 333 ngx_http_proxy_send_request(p);
326 334
327 return; 335 return;
328 } 336 }
329 337
330 338
331 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) 339 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
332 { 340 {
333 int rc; 341 int rc;
334 ngx_chain_t *chain, *ce, *te, **le; 342 ngx_chain_t *chain, *cl, *tl, **ll;
335 ngx_connection_t *c; 343 ngx_connection_t *c;
336 344
337 c = p->upstream.connection; 345 c = p->upstream.connection;
338 346
339 for ( ;; ) { 347 for ( ;; ) {
348
340 if (c) { 349 if (c) {
341 chain = ngx_write_chain(c, p->work_request_hunks); 350 chain = ngx_write_chain(c, p->work_request_hunks);
342 351
343 if (chain != NGX_CHAIN_ERROR) { 352 if (chain != NGX_CHAIN_ERROR) {
344 p->work_request_hunks = chain; 353 p->work_request_hunks = chain;
354 p->request_sent = 1;
345 355
346 if (c->write->timer_set) { 356 if (c->write->timer_set) {
347 ngx_del_timer(c->write); 357 ngx_del_timer(c->write);
348 } 358 }
349 359
388 398
389 c = p->upstream.connection; 399 c = p->upstream.connection;
390 c->pool = p->request->pool; 400 c->pool = p->request->pool;
391 c->read->log = c->write->log = c->log = p->request->connection->log; 401 c->read->log = c->write->log = c->log = p->request->connection->log;
392 402
393 if (p->upstream.tries > 1) { 403 if (p->upstream.tries > 1 && p->request_sent) {
394 #if (NGX_SUPPRESS_WARN) 404
395 le = NULL; 405 /* reinit the request chain */
396 #endif 406
397 p->work_request_hunks = ngx_alloc_chain_link(p->request->pool); 407 p->work_request_hunks = ngx_alloc_chain_link(p->request->pool);
398 if (p->work_request_hunks == NULL) { 408 if (p->work_request_hunks == NULL) {
399 ngx_http_proxy_finalize_request(p, 409 ngx_http_proxy_finalize_request(p,
400 NGX_HTTP_INTERNAL_SERVER_ERROR); 410 NGX_HTTP_INTERNAL_SERVER_ERROR);
401 return; 411 return;
402 } 412 }
403 413
404 te = p->work_request_hunks; 414 tl = p->work_request_hunks;
405 415 ll = &p->work_request_hunks;
406 for (ce = p->request_hunks; ce; ce = ce->next) { 416
407 te->hunk = ce->hunk; 417 for (cl = p->request_hunks; cl; cl = cl->next) {
408 *le = te; 418 tl->hunk = cl->hunk;
409 le = &te->next; 419 *ll = tl;
410 ce->hunk->pos = ce->hunk->start; 420 ll = &tl->next;
411 421 cl->hunk->pos = cl->hunk->start;
412 te = ngx_alloc_chain_link(p->request->pool); 422
413 if (te == NULL) { 423 tl = ngx_alloc_chain_link(p->request->pool);
424 if (tl == NULL) {
414 ngx_http_proxy_finalize_request(p, 425 ngx_http_proxy_finalize_request(p,
415 NGX_HTTP_INTERNAL_SERVER_ERROR); 426 NGX_HTTP_INTERNAL_SERVER_ERROR);
416 return; 427 return;
417 } 428 }
418 } 429 }
419 430
420 *le = NULL; 431 *ll = NULL;
421 432
422 } else { 433 } else {
423 p->work_request_hunks = p->request_hunks; 434 p->work_request_hunks = p->request_hunks;
424 } 435 }
436
437 p->request_sent = 0;
438 p->timedout = 0;
425 439
426 if (rc == NGX_OK) { 440 if (rc == NGX_OK) {
427 break; 441 break;
428 } 442 }
429 443
448 p = c->data; 462 p = c->data;
449 463
450 ngx_log_debug(rev->log, "http proxy process status line"); 464 ngx_log_debug(rev->log, "http proxy process status line");
451 465
452 if (rev->timedout) { 466 if (rev->timedout) {
467 p->timedout = 1;
453 ngx_http_proxy_next_upstream(p); 468 ngx_http_proxy_next_upstream(p);
454 return; 469 return;
455 } 470 }
456 471
457 if (p->header_in == NULL) { 472 if (p->header_in == NULL) {
535 r = p->request; 550 r = p->request;
536 551
537 ngx_log_debug(rev->log, "http proxy process header line"); 552 ngx_log_debug(rev->log, "http proxy process header line");
538 553
539 if (rev->timedout) { 554 if (rev->timedout) {
555 p->timedout = 1;
540 ngx_http_proxy_next_upstream(p); 556 ngx_http_proxy_next_upstream(p);
541 return; 557 return;
542 } 558 }
543 559
544 rc = NGX_AGAIN; 560 rc = NGX_AGAIN;
855 ep = p->event_pipe; 871 ep = p->event_pipe;
856 872
857 if (ev->timedout) { 873 if (ev->timedout) {
858 if (ev->write) { 874 if (ev->write) {
859 ep->downstream_error = 1; 875 ep->downstream_error = 1;
876 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
877 "client timed out");
860 878
861 } else { 879 } else {
862 ep->upstream_error = 1; 880 ep->upstream_error = 1;
881 ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
882 "upstream timed out");
863 } 883 }
864 884
865 } else { 885 } else {
866 if (ngx_event_pipe(ep, ev->write) == NGX_ABORT) { 886 if (ngx_event_pipe(ep, ev->write) == NGX_ABORT) {
867 ngx_http_proxy_finalize_request(p, 0); 887 ngx_http_proxy_finalize_request(p, 0);
1103 } 1123 }
1104 1124
1105 1125
1106 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p) 1126 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p)
1107 { 1127 {
1128 ngx_event_connect_peer_failed(&p->upstream);
1129
1130 if (p->timedout) {
1131 ngx_log_error(NGX_LOG_ERR, p->request->connection->log, NGX_ETIMEDOUT,
1132 "upstream timed out");
1133 }
1134
1108 if (p->upstream.connection) { 1135 if (p->upstream.connection) {
1109 ngx_http_proxy_close_connection(p->upstream.connection); 1136 ngx_http_proxy_close_connection(p->upstream.connection);
1110 p->upstream.connection = NULL; 1137 p->upstream.connection = NULL;
1138 }
1139
1140 if (p->upstream.tries == 0) {
1141 ngx_http_proxy_finalize_request(p,
1142 p->timedout ? NGX_HTTP_GATEWAY_TIME_OUT:
1143 NGX_HTTP_BAD_GATEWAY);
1144 return;
1111 } 1145 }
1112 1146
1113 if (!p->fatal_error) { 1147 if (!p->fatal_error) {
1114 ngx_http_proxy_send_request(p); 1148 ngx_http_proxy_send_request(p);
1115 } 1149 }