Mercurial > hg > nginx
comparison src/http/modules/ngx_http_event_proxy_handler.c @ 59:e8cdc2989cee
nginx-0.0.1-2003-02-06-20:21:13 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 06 Feb 2003 17:21:13 +0000 |
parents | 0e81ac0bb3e2 |
children | 50186b49f2ad |
comparison
equal
deleted
inserted
replaced
58:6b13b1cadabe | 59:e8cdc2989cee |
---|---|
4 #include <ngx_string.h> | 4 #include <ngx_string.h> |
5 #include <ngx_file.h> | 5 #include <ngx_file.h> |
6 #include <ngx_hunk.h> | 6 #include <ngx_hunk.h> |
7 #include <ngx_event_write.h> | 7 #include <ngx_event_write.h> |
8 #include <ngx_http.h> | 8 #include <ngx_http.h> |
9 #include <ngx_http_output_filter.h> | |
9 #include <ngx_http_event_proxy_handler.h> | 10 #include <ngx_http_event_proxy_handler.h> |
10 | 11 |
11 ngx_http_module_t ngx_http_proxy_module_ctx; | 12 ngx_http_module_t ngx_http_proxy_module_ctx; |
12 | 13 |
13 | 14 |
28 | 29 |
29 | 30 |
30 static char conn_close[] = "Connection: close" CRLF; | 31 static char conn_close[] = "Connection: close" CRLF; |
31 | 32 |
32 | 33 |
34 /* AF_INET only */ | |
35 | |
36 | |
33 int ngx_http_proxy_handler(ngx_http_request_t *r) | 37 int ngx_http_proxy_handler(ngx_http_request_t *r) |
34 { | 38 { |
35 struct sockaddr_in addr; | 39 struct sockaddr_in addr; |
36 ngx_chain_t *chain; | 40 ngx_chain_t *chain; |
37 ngx_http_proxy_ctx_t *p; | 41 ngx_http_proxy_ctx_t *p; |
54 ngx_memzero(&addr, sizeof(struct sockaddr_in)); | 58 ngx_memzero(&addr, sizeof(struct sockaddr_in)); |
55 addr.sin_family = AF_INET; | 59 addr.sin_family = AF_INET; |
56 addr.sin_addr.s_addr = inet_addr("127.0.0.1"); | 60 addr.sin_addr.s_addr = inet_addr("127.0.0.1"); |
57 addr.sin_port = htons(9000); | 61 addr.sin_port = htons(9000); |
58 | 62 |
59 ngx_http_proxy_connect(r, &addr, "connecting to 127.0.0.1:9000"); | 63 return ngx_http_proxy_connect(r, &addr, "connecting to 127.0.0.1:9000"); |
60 } | 64 } |
61 | 65 |
62 | 66 |
63 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r) | 67 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r) |
64 { | 68 { |
149 ctx = c->log->data; | 153 ctx = c->log->data; |
150 ctx->action = addr_text; | 154 ctx->action = addr_text; |
151 | 155 |
152 s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0); | 156 s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0); |
153 if (s == -1) { | 157 if (s == -1) { |
154 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, | 158 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
155 ngx_socket_n " failed"); | 159 ngx_socket_n " failed"); |
156 return NGX_ERROR; | 160 return NGX_ERROR; |
157 } | 161 } |
158 | 162 |
159 #if 0 | 163 #if 0 |
162 (const void *) &rcvbuf, sizeof(int)) == -1) { | 166 (const void *) &rcvbuf, sizeof(int)) == -1) { |
163 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, | 167 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
164 "setsockopt(SO_RCVBUF) failed"); | 168 "setsockopt(SO_RCVBUF) failed"); |
165 | 169 |
166 if (ngx_close_socket(s) == -1) { | 170 if (ngx_close_socket(s) == -1) { |
167 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, | 171 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
168 ngx_close_socket_n " failed"); | 172 ngx_close_socket_n " failed"); |
169 } | 173 } |
170 | 174 |
171 return NGX_ERROR; | 175 return NGX_ERROR; |
172 } | 176 } |
176 if (ngx_nonblocking(s) == -1) { | 180 if (ngx_nonblocking(s) == -1) { |
177 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, | 181 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
178 ngx_nonblocking_n " failed"); | 182 ngx_nonblocking_n " failed"); |
179 | 183 |
180 if (ngx_close_socket(s) == -1) { | 184 if (ngx_close_socket(s) == -1) { |
181 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, | 185 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
182 ngx_close_socket_n " failed"); | 186 ngx_close_socket_n " failed"); |
183 } | 187 } |
184 | 188 |
185 return NGX_ERROR; | 189 return NGX_ERROR; |
186 } | 190 } |
188 rc = connect(s, (struct sockaddr *) addr, sizeof(struct sockaddr_in)); | 192 rc = connect(s, (struct sockaddr *) addr, sizeof(struct sockaddr_in)); |
189 | 193 |
190 if (rc == -1) { | 194 if (rc == -1) { |
191 err = ngx_socket_errno; | 195 err = ngx_socket_errno; |
192 if (err != NGX_EINPROGRESS) { | 196 if (err != NGX_EINPROGRESS) { |
193 ngx_log_error(NGX_LOG_ERR, c->log, err, "connect() failed"); | 197 ngx_log_error(NGX_LOG_CRIT, c->log, err, "connect() failed"); |
194 | 198 |
195 if (ngx_close_socket(s) == -1) { | 199 if (ngx_close_socket(s) == -1) { |
196 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, | 200 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
197 ngx_close_socket_n " failed"); | 201 ngx_close_socket_n " failed"); |
198 } | 202 } |
199 | 203 |
200 return NGX_ERROR; | 204 return NGX_ERROR; |
201 } | 205 } |
269 } | 273 } |
270 | 274 |
271 | 275 |
272 static int ngx_http_proxy_read_response_header(ngx_event_t *ev) | 276 static int ngx_http_proxy_read_response_header(ngx_event_t *ev) |
273 { | 277 { |
274 int n, rc; | 278 int n; |
275 ngx_hunk_t **ph; | 279 ngx_hunk_t **ph; |
276 ngx_connection_t *c; | 280 ngx_connection_t *c; |
277 ngx_http_request_t *r; | 281 ngx_http_request_t *r; |
278 ngx_http_proxy_ctx_t *p; | 282 ngx_http_proxy_ctx_t *p; |
279 | 283 |
296 | 300 |
297 ngx_test_null(p->headers_in, | 301 ngx_test_null(p->headers_in, |
298 ngx_palloc(r->pool, sizeof(ngx_http_proxy_headers_in_t)), | 302 ngx_palloc(r->pool, sizeof(ngx_http_proxy_headers_in_t)), |
299 NGX_ERROR); | 303 NGX_ERROR); |
300 | 304 |
301 ngx_test_null(p->hunks, | 305 ngx_init_array(p->hunks, r->pool, |
302 ngx_create_array(r->pool, | 306 /* STUB */ 10 /**/, |
303 /* STUB */ 10 /**/, | 307 sizeof(ngx_hunk_t *), |
304 sizeof(ngx_hunk_t *)), | 308 NGX_ERROR); |
305 NGX_ERROR); | 309 |
306 | 310 ngx_test_null(ph, ngx_push_array(&p->hunks), NGX_ERROR); |
307 ngx_test_null(ph, ngx_push_array(p->hunks), NGX_ERROR); | |
308 *ph = p->header_in; | 311 *ph = p->header_in; |
309 | 312 |
310 p->state_handler = ngx_http_proxy_process_status_line; | 313 p->state_handler = ngx_http_proxy_process_status_line; |
311 } | 314 } |
312 | 315 |
385 } | 388 } |
386 | 389 |
387 /* STUB */ return NGX_ERROR; | 390 /* STUB */ return NGX_ERROR; |
388 } | 391 } |
389 | 392 |
393 #if 0 | |
390 static int ngx_http_proxy_process_response_header(ngx_http_request_t *r, | 394 static int ngx_http_proxy_process_response_header(ngx_http_request_t *r, |
391 ngx_http_proxy_ctx_t *p) | 395 ngx_http_proxy_ctx_t *p) |
392 { | 396 { |
393 } | 397 return NGX_OK; |
398 } | |
399 #endif | |
394 | 400 |
395 static int ngx_http_proxy_read_response_body(ngx_event_t *ev) | 401 static int ngx_http_proxy_read_response_body(ngx_event_t *ev) |
396 { | 402 { |
397 int n; | 403 int n; |
398 size_t left; | 404 char *buf; |
405 size_t left, size; | |
399 ngx_hunk_t *h, **ph; | 406 ngx_hunk_t *h, **ph; |
400 ngx_connection_t *c; | 407 ngx_connection_t *c; |
401 ngx_http_request_t *r; | 408 ngx_http_request_t *r; |
402 ngx_http_proxy_ctx_t *p; | 409 ngx_http_proxy_ctx_t *p; |
403 | 410 |
404 if (ev->timedout) | 411 if (ev->timedout) { |
405 return NGX_ERROR; | 412 return NGX_ERROR; |
413 } | |
406 | 414 |
407 c = (ngx_connection_t *) ev->data; | 415 c = (ngx_connection_t *) ev->data; |
408 r = (ngx_http_request_t *) c->data; | 416 r = (ngx_http_request_t *) c->data; |
409 p = (ngx_http_proxy_ctx_t *) | 417 p = (ngx_http_proxy_ctx_t *) |
410 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); | 418 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); |
411 | 419 |
412 left = 0; | 420 if (p->hunks.nelts > 0) { |
413 | 421 h = ((ngx_hunk_t **) p->hunks.elts)[p->hunks.nelts - 1]; |
414 if (p->hunks->nelts > 0) { | |
415 h = ((ngx_hunk_t **) p->hunks->elts)[p->hunks->nelts - 1]; | |
416 left = h->end - h->last.mem; | 422 left = h->end - h->last.mem; |
423 | |
424 } else { | |
425 h = NULL; | |
426 left = 0; | |
417 } | 427 } |
418 | 428 |
419 do { | 429 do { |
420 | 430 |
421 #if (HAVE_KQUEUE) | 431 #if (USE_KQUEUE) |
422 #if !(USE_KQUEUE) | 432 |
433 /* do not allocate new block if there is EOF */ | |
434 if (ev->eof && ev->available == 0) { | |
435 left = 1; | |
436 } | |
437 | |
438 #elif (HAVE_KQUEUE) | |
439 | |
423 if (ngx_event_type == NGX_KQUEUE_EVENT) { | 440 if (ngx_event_type == NGX_KQUEUE_EVENT) { |
424 #endif | |
425 /* do not allocate new block if there is EOF */ | 441 /* do not allocate new block if there is EOF */ |
426 if (ev->eof && ev->available == 0) { | 442 if (ev->eof && ev->available == 0) { |
427 left = 1; | 443 left = 1; |
428 } | 444 } |
429 #if !(USE_KQUEUE) | 445 } |
430 } | 446 |
431 #endif | 447 #endif |
432 #endif | 448 |
433 if (left == 0) { | 449 if (left == 0) { |
434 ngx_test_null(ph, ngx_push_array(p->hunks), NGX_ERROR); | 450 ngx_test_null(ph, ngx_push_array(&p->hunks), NGX_ERROR); |
435 ngx_test_null(h, | 451 ngx_test_null(h, |
436 ngx_create_temp_hunk(r->pool, | 452 ngx_create_temp_hunk(r->pool, |
437 /* STUB */ 4096 /**/, 0, 0), | 453 /* STUB */ 4096 /**/, 0, 0), |
438 NGX_ERROR); | 454 NGX_ERROR); |
439 | 455 |
440 h->type = NGX_HUNK_MEMORY; | 456 h->type = NGX_HUNK_MEMORY; |
441 *ph = h; | 457 *ph = h; |
442 } | 458 } |
443 | 459 |
444 n = ngx_event_recv(c, h->last.mem, h->end - h->last.mem); | 460 if (h != NULL) { |
461 buf = h->last.mem; | |
462 size = h->end - h->last.mem; | |
463 | |
464 } else { | |
465 buf = (char *) &buf; | |
466 size = 0; | |
467 } | |
468 | |
469 n = ngx_event_recv(c, buf, size); | |
445 | 470 |
446 ngx_log_debug(c->log, "READ:%d" _ n); | 471 ngx_log_debug(c->log, "READ:%d" _ n); |
447 | 472 |
448 if (n == NGX_AGAIN) { | 473 if (n == NGX_AGAIN) { |
449 return NGX_WAITING; | 474 return NGX_WAITING; |
490 r = (ngx_http_request_t *) c->data; | 515 r = (ngx_http_request_t *) c->data; |
491 p = (ngx_http_proxy_ctx_t *) | 516 p = (ngx_http_proxy_ctx_t *) |
492 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); | 517 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); |
493 | 518 |
494 do { | 519 do { |
495 h = ((ngx_hunk_t **) p->hunks->elts)[p->hunk_n]; | 520 h = ((ngx_hunk_t **) p->hunks.elts)[p->hunk_n]; |
496 | 521 |
497 rc = ngx_http_output_filter(r, h); | 522 rc = ngx_http_output_filter(r, h); |
498 if (rc != NGX_OK) { | 523 if (rc != NGX_OK) { |
499 return rc; | 524 return rc; |
500 } | 525 } |
501 | 526 |
502 if (p->hunk_n >= p->hunks->nelts) { | 527 if (p->hunk_n >= p->hunks.nelts) { |
503 break; | 528 break; |
504 } | 529 } |
505 | 530 |
506 p->hunk_n++; | 531 p->hunk_n++; |
507 | 532 |
532 p = ctx->header_in->pos.mem; | 557 p = ctx->header_in->pos.mem; |
533 | 558 |
534 while (p < ctx->header_in->last.mem && state < sw_done) { | 559 while (p < ctx->header_in->last.mem && state < sw_done) { |
535 ch = *p++; | 560 ch = *p++; |
536 | 561 |
562 #if 0 | |
537 fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n", | 563 fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n", |
538 state, p, ctx->header_in->last.mem, ch, ctx->status); | 564 state, p, ctx->header_in->last.mem, ch, ctx->status); |
565 #endif | |
539 | 566 |
540 switch (state) { | 567 switch (state) { |
541 | 568 |
542 /* "HTTP/" */ | 569 /* "HTTP/" */ |
543 case sw_start: | 570 case sw_start: |