Mercurial > hg > nginx
comparison src/http/modules/ngx_http_event_proxy_handler.c @ 44:0e81ac0bb3e2
nginx-0.0.1-2003-01-09-08:36:00 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 09 Jan 2003 05:36:00 +0000 |
parents | 59e7c7f30d49 |
children | e8cdc2989cee |
comparison
equal
deleted
inserted
replaced
43:53cd05892261 | 44:0e81ac0bb3e2 |
---|---|
37 ngx_http_proxy_ctx_t *p; | 37 ngx_http_proxy_ctx_t *p; |
38 | 38 |
39 p = (ngx_http_proxy_ctx_t *) | 39 p = (ngx_http_proxy_ctx_t *) |
40 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); | 40 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); |
41 | 41 |
42 if (p == NULL) | 42 if (p == NULL) { |
43 ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx, | 43 ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx, |
44 sizeof(ngx_http_proxy_ctx_t)); | 44 sizeof(ngx_http_proxy_ctx_t)); |
45 } | |
45 | 46 |
46 chain = ngx_http_proxy_create_request(r); | 47 chain = ngx_http_proxy_create_request(r); |
47 if (chain == NULL) | 48 if (chain == NULL) { |
48 return NGX_ERROR; | 49 return NGX_ERROR; |
50 } | |
49 | 51 |
50 p->out = chain; | 52 p->out = chain; |
51 | 53 |
52 ngx_memzero(&addr, sizeof(struct sockaddr_in)); | 54 ngx_memzero(&addr, sizeof(struct sockaddr_in)); |
53 addr.sin_family = AF_INET; | 55 addr.sin_family = AF_INET; |
73 /* "Connection: close\r\n" */ | 75 /* "Connection: close\r\n" */ |
74 len += sizeof(conn_close) - 1; | 76 len += sizeof(conn_close) - 1; |
75 | 77 |
76 header = (ngx_table_elt_t *) r->headers_in.headers->elts; | 78 header = (ngx_table_elt_t *) r->headers_in.headers->elts; |
77 for (i = 0; i < r->headers_in.headers->nelts; i++) { | 79 for (i = 0; i < r->headers_in.headers->nelts; i++) { |
78 if (&header[i] == r->headers_in.host) | 80 if (&header[i] == r->headers_in.host) { |
79 continue; | 81 continue; |
80 | 82 } |
81 if (&header[i] == r->headers_in.connection) | 83 |
84 if (&header[i] == r->headers_in.connection) { | |
82 continue; | 85 continue; |
86 } | |
83 | 87 |
84 /* 2 is for ": " and 2 is for "\r\n" */ | 88 /* 2 is for ": " and 2 is for "\r\n" */ |
85 len += header[i].key.len + 2 + header[i].value.len + 2; | 89 len += header[i].key.len + 2 + header[i].value.len + 2; |
86 } | 90 } |
87 | 91 |
96 | 100 |
97 ngx_memcpy(hunk->last.mem, conn_close, sizeof(conn_close) - 1); | 101 ngx_memcpy(hunk->last.mem, conn_close, sizeof(conn_close) - 1); |
98 hunk->last.mem += sizeof(conn_close) - 1; | 102 hunk->last.mem += sizeof(conn_close) - 1; |
99 | 103 |
100 for (i = 0; i < r->headers_in.headers->nelts; i++) { | 104 for (i = 0; i < r->headers_in.headers->nelts; i++) { |
101 if (&header[i] == r->headers_in.host) | 105 if (&header[i] == r->headers_in.host) { |
102 continue; | 106 continue; |
103 | 107 } |
104 if (&header[i] == r->headers_in.connection) | 108 |
109 if (&header[i] == r->headers_in.connection) { | |
105 continue; | 110 continue; |
111 } | |
106 | 112 |
107 ngx_memcpy(hunk->last.mem, header[i].key.data, header[i].key.len); | 113 ngx_memcpy(hunk->last.mem, header[i].key.data, header[i].key.len); |
108 hunk->last.mem += header[i].key.len; | 114 hunk->last.mem += header[i].key.len; |
109 | 115 |
110 *(hunk->last.mem++) = ':'; *(hunk->last.mem++) = ' '; | 116 *(hunk->last.mem++) = ':'; *(hunk->last.mem++) = ' '; |
113 hunk->last.mem += header[i].value.len; | 119 hunk->last.mem += header[i].value.len; |
114 | 120 |
115 *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; | 121 *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; |
116 | 122 |
117 ngx_log_debug(r->connection->log, "proxy: '%s: %s'" _ | 123 ngx_log_debug(r->connection->log, "proxy: '%s: %s'" _ |
118 header[i].key.data _ header[i].value.data); | 124 header[i].key.data _ header[i].value.data); |
119 } | 125 } |
120 | 126 |
121 /* add "\r\n" at the header end */ | 127 /* add "\r\n" at the header end */ |
122 *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; | 128 *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; |
123 | 129 |
155 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, | 161 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, |
156 (const void *) &rcvbuf, sizeof(int)) == -1) { | 162 (const void *) &rcvbuf, sizeof(int)) == -1) { |
157 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, | 163 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
158 "setsockopt(SO_RCVBUF) failed"); | 164 "setsockopt(SO_RCVBUF) failed"); |
159 | 165 |
160 if (ngx_close_socket(s) == -1) | 166 if (ngx_close_socket(s) == -1) { |
161 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, | 167 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, |
162 ngx_close_socket_n " failed"); | 168 ngx_close_socket_n " failed"); |
169 } | |
163 | 170 |
164 return NGX_ERROR; | 171 return NGX_ERROR; |
165 } | 172 } |
166 } | 173 } |
167 #endif | 174 #endif |
168 | 175 |
169 if (ngx_nonblocking(s) == -1) { | 176 if (ngx_nonblocking(s) == -1) { |
170 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, | 177 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
171 ngx_nonblocking_n " failed"); | 178 ngx_nonblocking_n " failed"); |
172 | 179 |
173 if (ngx_close_socket(s) == -1) | 180 if (ngx_close_socket(s) == -1) { |
174 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, | 181 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, |
175 ngx_close_socket_n " failed"); | 182 ngx_close_socket_n " failed"); |
183 } | |
176 | 184 |
177 return NGX_ERROR; | 185 return NGX_ERROR; |
178 } | 186 } |
179 | 187 |
180 rc = connect(s, (struct sockaddr *) addr, sizeof(struct sockaddr_in)); | 188 rc = connect(s, (struct sockaddr *) addr, sizeof(struct sockaddr_in)); |
182 if (rc == -1) { | 190 if (rc == -1) { |
183 err = ngx_socket_errno; | 191 err = ngx_socket_errno; |
184 if (err != NGX_EINPROGRESS) { | 192 if (err != NGX_EINPROGRESS) { |
185 ngx_log_error(NGX_LOG_ERR, c->log, err, "connect() failed"); | 193 ngx_log_error(NGX_LOG_ERR, c->log, err, "connect() failed"); |
186 | 194 |
187 if (ngx_close_socket(s) == -1) | 195 if (ngx_close_socket(s) == -1) { |
188 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, | 196 ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, |
189 ngx_close_socket_n " failed"); | 197 ngx_close_socket_n " failed"); |
198 } | |
190 | 199 |
191 return NGX_ERROR; | 200 return NGX_ERROR; |
192 } | 201 } |
193 } | 202 } |
194 | 203 |
205 pc->write = wev; | 214 pc->write = wev; |
206 | 215 |
207 pc->data = r; | 216 pc->data = r; |
208 | 217 |
209 pc->fd = s; | 218 pc->fd = s; |
210 pc->server = c->server; | |
211 pc->servers = c->servers; | 219 pc->servers = c->servers; |
212 | 220 |
213 pc->log = rev->log = wev->log = c->log; | 221 pc->log = rev->log = wev->log = c->log; |
214 | 222 |
215 ngx_test_null(pc->pool, | 223 ngx_test_null(pc->pool, |
218 | 226 |
219 wev->event_handler = ngx_http_proxy_send_request; | 227 wev->event_handler = ngx_http_proxy_send_request; |
220 rev->event_handler = ngx_http_proxy_read_response_header; | 228 rev->event_handler = ngx_http_proxy_read_response_header; |
221 | 229 |
222 #if (HAVE_CLEAR_EVENT) | 230 #if (HAVE_CLEAR_EVENT) |
223 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) | 231 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) { |
224 #else | 232 #else |
225 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) | 233 if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) { |
226 #endif | 234 #endif |
227 return NGX_ERROR; | 235 return NGX_ERROR; |
228 | 236 } |
229 if (rc == -1) | 237 |
238 if (rc == -1) { | |
230 return ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT); | 239 return ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT); |
240 } | |
231 | 241 |
232 wev->write = 1; | 242 wev->write = 1; |
233 wev->ready = 1; | 243 wev->ready = 1; |
234 | 244 |
235 return ngx_http_proxy_send_request(wev); | 245 return ngx_http_proxy_send_request(wev); |
247 r = (ngx_http_request_t *) c->data; | 257 r = (ngx_http_request_t *) c->data; |
248 p = (ngx_http_proxy_ctx_t *) | 258 p = (ngx_http_proxy_ctx_t *) |
249 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); | 259 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); |
250 | 260 |
251 chain = ngx_event_write(c, p->out, 0); | 261 chain = ngx_event_write(c, p->out, 0); |
252 if (chain == (ngx_chain_t *) -1) | 262 if (chain == (ngx_chain_t *) -1) { |
253 return NGX_ERROR; | 263 return NGX_ERROR; |
264 } | |
254 | 265 |
255 p->out = chain; | 266 p->out = chain; |
256 | 267 |
257 return NGX_WAITING; | 268 return NGX_WAITING; |
258 } | 269 } |
264 ngx_hunk_t **ph; | 275 ngx_hunk_t **ph; |
265 ngx_connection_t *c; | 276 ngx_connection_t *c; |
266 ngx_http_request_t *r; | 277 ngx_http_request_t *r; |
267 ngx_http_proxy_ctx_t *p; | 278 ngx_http_proxy_ctx_t *p; |
268 | 279 |
269 if (ev->timedout) | 280 if (ev->timedout) { |
270 return NGX_ERROR; | 281 return NGX_ERROR; |
282 } | |
271 | 283 |
272 c = (ngx_connection_t *) ev->data; | 284 c = (ngx_connection_t *) ev->data; |
273 r = (ngx_http_request_t *) c->data; | 285 r = (ngx_http_request_t *) c->data; |
274 p = (ngx_http_proxy_ctx_t *) | 286 p = (ngx_http_proxy_ctx_t *) |
275 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); | 287 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); |
328 | 340 |
329 #if 0 | 341 #if 0 |
330 do { | 342 do { |
331 rc = (p->state_handler)(r, p); | 343 rc = (p->state_handler)(r, p); |
332 | 344 |
333 if (rc == NGX_ERROR) | 345 if (rc == NGX_ERROR) { |
334 return rc; | 346 return rc; |
347 } | |
335 | 348 |
336 /* rc == NGX_OK || rc == NGX_AGAIN */ | 349 /* rc == NGX_OK || rc == NGX_AGAIN */ |
337 | 350 |
338 } while (p->header_in->pos.mem < p->header_in->last.mem); | 351 } while (p->header_in->pos.mem < p->header_in->last.mem); |
339 #endif | 352 #endif |
340 | 353 |
341 ev->event_handler = ngx_http_proxy_read_response_body; | 354 ev->event_handler = ngx_http_proxy_read_response_body; |
342 if (p->header_in->end - p->header_in->last.mem == 0) | 355 if (p->header_in->end - p->header_in->last.mem == 0) { |
343 return ngx_http_proxy_read_response_body(ev); | 356 return ngx_http_proxy_read_response_body(ev); |
357 } | |
344 | 358 |
345 return NGX_WAITING; | 359 return NGX_WAITING; |
346 } | 360 } |
347 | 361 |
348 static int ngx_http_proxy_process_status_line(ngx_http_request_t *r, | 362 static int ngx_http_proxy_process_status_line(ngx_http_request_t *r, |
404 | 418 |
405 do { | 419 do { |
406 | 420 |
407 #if (HAVE_KQUEUE) | 421 #if (HAVE_KQUEUE) |
408 #if !(USE_KQUEUE) | 422 #if !(USE_KQUEUE) |
409 if (ngx_event_type == NGX_KQUEUE_EVENT) | 423 if (ngx_event_type == NGX_KQUEUE_EVENT) { |
410 #endif | 424 #endif |
411 /* do not allocate new block if there is EOF */ | 425 /* do not allocate new block if there is EOF */ |
412 if (ev->eof && ev->available == 0) | 426 if (ev->eof && ev->available == 0) { |
413 left = 1; | 427 left = 1; |
428 } | |
429 #if !(USE_KQUEUE) | |
430 } | |
431 #endif | |
414 #endif | 432 #endif |
415 if (left == 0) { | 433 if (left == 0) { |
416 ngx_test_null(ph, ngx_push_array(p->hunks), NGX_ERROR); | 434 ngx_test_null(ph, ngx_push_array(p->hunks), NGX_ERROR); |
417 ngx_test_null(h, | 435 ngx_test_null(h, |
418 ngx_create_temp_hunk(r->pool, | 436 ngx_create_temp_hunk(r->pool, |
425 | 443 |
426 n = ngx_event_recv(c, h->last.mem, h->end - h->last.mem); | 444 n = ngx_event_recv(c, h->last.mem, h->end - h->last.mem); |
427 | 445 |
428 ngx_log_debug(c->log, "READ:%d" _ n); | 446 ngx_log_debug(c->log, "READ:%d" _ n); |
429 | 447 |
430 if (n == NGX_AGAIN) | 448 if (n == NGX_AGAIN) { |
431 return NGX_WAITING; | 449 return NGX_WAITING; |
432 | 450 } |
433 if (n == NGX_ERROR) | 451 |
452 if (n == NGX_ERROR) { | |
434 return NGX_ERROR; | 453 return NGX_ERROR; |
454 } | |
435 | 455 |
436 h->last.mem += n; | 456 h->last.mem += n; |
437 left = h->end - h->last.mem; | 457 left = h->end - h->last.mem; |
438 | 458 |
439 /* STUB */ | 459 /* STUB */ |
473 | 493 |
474 do { | 494 do { |
475 h = ((ngx_hunk_t **) p->hunks->elts)[p->hunk_n]; | 495 h = ((ngx_hunk_t **) p->hunks->elts)[p->hunk_n]; |
476 | 496 |
477 rc = ngx_http_output_filter(r, h); | 497 rc = ngx_http_output_filter(r, h); |
478 if (rc != NGX_OK) | 498 if (rc != NGX_OK) { |
479 return rc; | 499 return rc; |
480 | 500 } |
481 if (p->hunk_n >= p->hunks->nelts) | 501 |
482 break; | 502 if (p->hunk_n >= p->hunks->nelts) { |
503 break; | |
504 } | |
483 | 505 |
484 p->hunk_n++; | 506 p->hunk_n++; |
485 | 507 |
486 } while (rc == NGX_OK); | 508 } while (rc == NGX_OK); |
487 | 509 |
517 | 539 |
518 switch (state) { | 540 switch (state) { |
519 | 541 |
520 /* "HTTP/" */ | 542 /* "HTTP/" */ |
521 case sw_start: | 543 case sw_start: |
522 if (p + 3 >= ctx->header_in->last.mem) | 544 if (p + 3 >= ctx->header_in->last.mem) { |
523 return NGX_AGAIN; | 545 return NGX_AGAIN; |
546 } | |
524 | 547 |
525 if (ch != 'H' || *p != 'T' || *(p + 1) != 'T' || *(p + 2) != 'P' | 548 if (ch != 'H' || *p != 'T' || *(p + 1) != 'T' || *(p + 2) != 'P' |
526 || *(p + 3) != '/') | 549 || *(p + 3) != '/') |
527 return NGX_HTTP_PROXY_PARSE_NO_HEADER; | 550 { |
551 return NGX_HTTP_PROXY_PARSE_NO_HEADER; | |
552 } | |
528 | 553 |
529 p += 4; | 554 p += 4; |
530 state = sw_first_major_digit; | 555 state = sw_first_major_digit; |
531 break; | 556 break; |
532 | 557 |
533 /* first digit of major HTTP version */ | 558 /* first digit of major HTTP version */ |
534 case sw_first_major_digit: | 559 case sw_first_major_digit: |
535 if (ch < '1' || ch > '9') | 560 if (ch < '1' || ch > '9') { |
536 return NGX_HTTP_PROXY_PARSE_NO_HEADER; | 561 return NGX_HTTP_PROXY_PARSE_NO_HEADER; |
562 } | |
537 | 563 |
538 state = sw_major_digit; | 564 state = sw_major_digit; |
539 break; | 565 break; |
540 | 566 |
541 /* major HTTP version or dot */ | 567 /* major HTTP version or dot */ |
543 if (ch == '.') { | 569 if (ch == '.') { |
544 state = sw_first_minor_digit; | 570 state = sw_first_minor_digit; |
545 break; | 571 break; |
546 } | 572 } |
547 | 573 |
548 if (ch < '0' || ch > '9') | 574 if (ch < '0' || ch > '9') { |
549 return NGX_HTTP_PROXY_PARSE_NO_HEADER; | 575 return NGX_HTTP_PROXY_PARSE_NO_HEADER; |
576 } | |
550 | 577 |
551 break; | 578 break; |
552 | 579 |
553 /* first digit of minor HTTP version */ | 580 /* first digit of minor HTTP version */ |
554 case sw_first_minor_digit: | 581 case sw_first_minor_digit: |
555 if (ch < '0' || ch > '9') | 582 if (ch < '0' || ch > '9') { |
556 return NGX_HTTP_PROXY_PARSE_NO_HEADER; | 583 return NGX_HTTP_PROXY_PARSE_NO_HEADER; |
584 } | |
557 | 585 |
558 state = sw_minor_digit; | 586 state = sw_minor_digit; |
559 break; | 587 break; |
560 | 588 |
561 /* minor HTTP version or end of request line */ | 589 /* minor HTTP version or end of request line */ |
563 if (ch == ' ') { | 591 if (ch == ' ') { |
564 state = sw_status; | 592 state = sw_status; |
565 break; | 593 break; |
566 } | 594 } |
567 | 595 |
568 if (ch < '0' || ch > '9') | 596 if (ch < '0' || ch > '9') { |
569 return NGX_HTTP_PROXY_PARSE_NO_HEADER; | 597 return NGX_HTTP_PROXY_PARSE_NO_HEADER; |
598 } | |
570 | 599 |
571 break; | 600 break; |
572 | 601 |
573 /* HTTP status code */ | 602 /* HTTP status code */ |
574 case sw_status: | 603 case sw_status: |
575 if (ch < '0' || ch > '9') | 604 if (ch < '0' || ch > '9') { |
576 return NGX_HTTP_PROXY_PARSE_NO_HEADER; | 605 return NGX_HTTP_PROXY_PARSE_NO_HEADER; |
606 } | |
577 | 607 |
578 ctx->status = ctx->status * 10 + ch - '0'; | 608 ctx->status = ctx->status * 10 + ch - '0'; |
579 | 609 |
580 if (++ctx->status_count == 3) { | 610 if (++ctx->status_count == 3) { |
581 state = sw_space_after_status; | 611 state = sw_space_after_status; |
628 } | 658 } |
629 | 659 |
630 ctx->header_in->pos.mem = p; | 660 ctx->header_in->pos.mem = p; |
631 | 661 |
632 if (state == sw_done) { | 662 if (state == sw_done) { |
633 if (ctx->request_end == NULL) | 663 if (ctx->request_end == NULL) { |
634 ctx->request_end = p - 1; | 664 ctx->request_end = p - 1; |
665 } | |
666 | |
635 ctx->state = sw_start; | 667 ctx->state = sw_start; |
636 return NGX_OK; | 668 return NGX_OK; |
669 | |
637 } else { | 670 } else { |
638 ctx->state = state; | 671 ctx->state = state; |
639 return NGX_AGAIN; | 672 return NGX_AGAIN; |
640 } | 673 } |
641 } | 674 } |