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 }