Mercurial > hg > nginx-quic
comparison src/http/ngx_http_request.c @ 5091:d3e256c67d6d
SSL: do not treat SSL handshake as request.
The request object will not be created until SSL handshake is complete.
This simplifies adding another connection handler that does not need
request object right after handshake (e.g., SPDY).
There are also a few more intentional effects:
- the "client_header_buffer_size" directive will be taken from the
server configuration that was negotiated by SNI;
- SSL handshake errors and timeouts are not logged into access log
as bad requests;
- ngx_ssl_create_connection() is not called until the first byte of
ClientHello message was received. This also decreases memory
consumption if plain HTTP request is sent to SSL socket.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Wed, 27 Feb 2013 17:21:21 +0000 |
parents | 9db95b275755 |
children | c4d3310574e0 |
comparison
equal
deleted
inserted
replaced
5090:9db95b275755 | 5091:d3e256c67d6d |
---|---|
314 | 314 |
315 rev = c->read; | 315 rev = c->read; |
316 rev->handler = ngx_http_init_request; | 316 rev->handler = ngx_http_init_request; |
317 c->write->handler = ngx_http_empty_handler; | 317 c->write->handler = ngx_http_empty_handler; |
318 | 318 |
319 #if (NGX_HTTP_SSL) | |
320 { | |
321 ngx_http_ssl_srv_conf_t *sscf; | |
322 | |
323 sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); | |
324 | |
325 if (sscf->enable || hc->addr_conf->ssl) { | |
326 | |
327 c->log->action = "SSL handshaking"; | |
328 | |
329 if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) { | |
330 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
331 "no \"ssl_certificate\" is defined " | |
332 "in server listening on SSL port"); | |
333 ngx_http_close_connection(c); | |
334 return; | |
335 } | |
336 | |
337 hc->ssl = 1; | |
338 | |
339 rev->handler = ngx_http_ssl_handshake; | |
340 } | |
341 } | |
342 #endif | |
343 | |
319 if (rev->ready) { | 344 if (rev->ready) { |
320 /* the deferred accept(), rtsig, aio, iocp */ | 345 /* the deferred accept(), rtsig, aio, iocp */ |
321 | 346 |
322 if (ngx_use_accept_mutex) { | 347 if (ngx_use_accept_mutex) { |
323 ngx_post_event(rev, &ngx_posted_events); | 348 ngx_post_event(rev, &ngx_posted_events); |
324 return; | 349 return; |
325 } | 350 } |
326 | 351 |
327 ngx_http_init_request(rev); | 352 rev->handler(rev); |
328 return; | 353 return; |
329 } | 354 } |
330 | 355 |
331 ngx_add_timer(rev, c->listening->post_accept_timeout); | 356 ngx_add_timer(rev, c->listening->post_accept_timeout); |
332 | 357 |
393 | 418 |
394 r->main_conf = hc->conf_ctx->main_conf; | 419 r->main_conf = hc->conf_ctx->main_conf; |
395 r->srv_conf = hc->conf_ctx->srv_conf; | 420 r->srv_conf = hc->conf_ctx->srv_conf; |
396 r->loc_conf = hc->conf_ctx->loc_conf; | 421 r->loc_conf = hc->conf_ctx->loc_conf; |
397 | 422 |
398 rev->handler = ngx_http_process_request_line; | |
399 r->read_event_handler = ngx_http_block_reading; | 423 r->read_event_handler = ngx_http_block_reading; |
400 | |
401 #if (NGX_HTTP_SSL) | |
402 | |
403 { | |
404 ngx_http_ssl_srv_conf_t *sscf; | |
405 | |
406 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); | |
407 if (sscf->enable || hc->addr_conf->ssl) { | |
408 | |
409 if (c->ssl == NULL) { | |
410 | |
411 c->log->action = "SSL handshaking"; | |
412 | |
413 if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) { | |
414 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
415 "no \"ssl_certificate\" is defined " | |
416 "in server listening on SSL port"); | |
417 ngx_http_close_connection(c); | |
418 return; | |
419 } | |
420 | |
421 if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER) | |
422 != NGX_OK) | |
423 { | |
424 ngx_http_close_connection(c); | |
425 return; | |
426 } | |
427 | |
428 rev->handler = ngx_http_ssl_handshake; | |
429 } | |
430 | |
431 r->main_filter_need_in_memory = 1; | |
432 } | |
433 } | |
434 | |
435 #endif | |
436 | 424 |
437 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 425 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
438 | 426 |
439 ngx_http_set_connection_log(r->connection, clcf->error_log); | 427 ngx_http_set_connection_log(r->connection, clcf->error_log); |
440 | 428 |
487 } | 475 } |
488 | 476 |
489 c->single_connection = 1; | 477 c->single_connection = 1; |
490 c->destroyed = 0; | 478 c->destroyed = 0; |
491 | 479 |
480 #if (NGX_HTTP_SSL) | |
481 if (c->ssl) { | |
482 r->main_filter_need_in_memory = 1; | |
483 } | |
484 #endif | |
485 | |
492 r->main = r; | 486 r->main = r; |
493 r->count = 1; | 487 r->count = 1; |
494 | 488 |
495 tp = ngx_timeofday(); | 489 tp = ngx_timeofday(); |
496 r->start_sec = tp->sec; | 490 r->start_sec = tp->sec; |
517 (void) ngx_atomic_fetch_add(ngx_stat_reading, 1); | 511 (void) ngx_atomic_fetch_add(ngx_stat_reading, 1); |
518 r->stat_reading = 1; | 512 r->stat_reading = 1; |
519 (void) ngx_atomic_fetch_add(ngx_stat_requests, 1); | 513 (void) ngx_atomic_fetch_add(ngx_stat_requests, 1); |
520 #endif | 514 #endif |
521 | 515 |
522 rev->handler(rev); | 516 rev->handler = ngx_http_process_request_line; |
517 ngx_http_process_request_line(rev); | |
523 } | 518 } |
524 | 519 |
525 | 520 |
526 #if (NGX_HTTP_SSL) | 521 #if (NGX_HTTP_SSL) |
527 | 522 |
528 static void | 523 static void |
529 ngx_http_ssl_handshake(ngx_event_t *rev) | 524 ngx_http_ssl_handshake(ngx_event_t *rev) |
530 { | 525 { |
531 u_char buf[1]; | 526 u_char buf[1]; |
532 ssize_t n; | 527 ssize_t n; |
533 ngx_int_t rc; | 528 ngx_err_t err; |
534 ngx_connection_t *c; | 529 ngx_int_t rc; |
535 ngx_http_request_t *r; | 530 ngx_connection_t *c; |
531 ngx_http_connection_t *hc; | |
532 ngx_http_ssl_srv_conf_t *sscf; | |
536 | 533 |
537 c = rev->data; | 534 c = rev->data; |
538 r = c->data; | |
539 | 535 |
540 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 536 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
541 "http check ssl handshake"); | 537 "http check ssl handshake"); |
542 | 538 |
543 if (rev->timedout) { | 539 if (rev->timedout) { |
544 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | 540 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
545 c->timedout = 1; | 541 ngx_http_close_connection(c); |
546 ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); | |
547 return; | 542 return; |
548 } | 543 } |
549 | 544 |
550 n = recv(c->fd, (char *) buf, 1, MSG_PEEK); | 545 n = recv(c->fd, (char *) buf, 1, MSG_PEEK); |
551 | 546 |
552 if (n == -1 && ngx_socket_errno == NGX_EAGAIN) { | 547 err = ngx_socket_errno; |
553 | 548 |
554 if (!rev->timer_set) { | 549 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n); |
555 ngx_add_timer(rev, c->listening->post_accept_timeout); | 550 |
556 } | 551 if (n == -1) { |
557 | 552 if (err == NGX_EAGAIN) { |
558 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | 553 |
559 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 554 if (!rev->timer_set) { |
560 } | 555 ngx_add_timer(rev, c->listening->post_accept_timeout); |
556 } | |
557 | |
558 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | |
559 ngx_http_close_connection(c); | |
560 } | |
561 | |
562 return; | |
563 } | |
564 | |
565 ngx_connection_error(c, err, "recv() failed"); | |
566 ngx_http_close_connection(c); | |
561 | 567 |
562 return; | 568 return; |
563 } | 569 } |
564 | 570 |
565 if (n == 1) { | 571 if (n == 1) { |
566 if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { | 572 if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { |
567 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 573 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
568 "https ssl handshake: 0x%02Xd", buf[0]); | 574 "https ssl handshake: 0x%02Xd", buf[0]); |
569 | 575 |
576 hc = c->data; | |
577 sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, | |
578 ngx_http_ssl_module); | |
579 | |
580 if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER) | |
581 != NGX_OK) | |
582 { | |
583 ngx_http_close_connection(c); | |
584 return; | |
585 } | |
586 | |
570 rc = ngx_ssl_handshake(c); | 587 rc = ngx_ssl_handshake(c); |
571 | 588 |
572 if (rc == NGX_AGAIN) { | 589 if (rc == NGX_AGAIN) { |
573 | 590 |
574 if (!rev->timer_set) { | 591 if (!rev->timer_set) { |
580 } | 597 } |
581 | 598 |
582 ngx_http_ssl_handshake_handler(c); | 599 ngx_http_ssl_handshake_handler(c); |
583 | 600 |
584 return; | 601 return; |
585 | 602 } |
586 } else { | 603 |
587 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 604 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http"); |
588 "plain http"); | 605 |
589 | 606 c->log->action = "reading client request line"; |
590 r->plain_http = 1; | 607 |
591 } | 608 rev->handler = ngx_http_init_request; |
592 } | 609 ngx_http_init_request(rev); |
593 | 610 |
594 c->log->action = "reading client request line"; | 611 return; |
595 | 612 } |
596 rev->handler = ngx_http_process_request_line; | 613 |
597 ngx_http_process_request_line(rev); | 614 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection"); |
615 ngx_http_close_connection(c); | |
598 } | 616 } |
599 | 617 |
600 | 618 |
601 static void | 619 static void |
602 ngx_http_ssl_handshake_handler(ngx_connection_t *c) | 620 ngx_http_ssl_handshake_handler(ngx_connection_t *c) |
603 { | 621 { |
604 ngx_http_request_t *r; | |
605 | |
606 if (c->ssl->handshaked) { | 622 if (c->ssl->handshaked) { |
607 | 623 |
608 /* | 624 /* |
609 * The majority of browsers do not send the "close notify" alert. | 625 * The majority of browsers do not send the "close notify" alert. |
610 * Among them are MSIE, old Mozilla, Netscape 4, Konqueror, | 626 * Among them are MSIE, old Mozilla, Netscape 4, Konqueror, |
615 | 631 |
616 c->ssl->no_wait_shutdown = 1; | 632 c->ssl->no_wait_shutdown = 1; |
617 | 633 |
618 c->log->action = "reading client request line"; | 634 c->log->action = "reading client request line"; |
619 | 635 |
620 c->read->handler = ngx_http_process_request_line; | 636 c->read->handler = ngx_http_init_request; |
621 /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler; | 637 /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler; |
622 | 638 |
623 ngx_http_process_request_line(c->read); | 639 ngx_http_init_request(c->read); |
624 | 640 |
625 return; | 641 return; |
626 } | 642 } |
627 | 643 |
628 r = c->data; | 644 if (c->read->timedout) { |
629 | 645 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
630 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); | 646 } |
631 | 647 |
632 return; | 648 ngx_http_close_connection(c); |
633 } | 649 } |
634 | 650 |
635 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME | 651 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME |
636 | 652 |
637 int | 653 int |
638 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) | 654 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) |
639 { | 655 { |
640 ngx_str_t host; | 656 ngx_str_t host; |
641 const char *servername; | 657 const char *servername; |
642 ngx_connection_t *c; | 658 ngx_connection_t *c; |
643 ngx_http_request_t *r; | |
644 ngx_http_connection_t *hc; | 659 ngx_http_connection_t *hc; |
645 ngx_http_ssl_srv_conf_t *sscf; | 660 ngx_http_ssl_srv_conf_t *sscf; |
646 ngx_http_core_loc_conf_t *clcf; | 661 ngx_http_core_loc_conf_t *clcf; |
647 ngx_http_core_srv_conf_t *cscf; | 662 ngx_http_core_srv_conf_t *cscf; |
648 | 663 |
661 | 676 |
662 if (host.len == 0) { | 677 if (host.len == 0) { |
663 return SSL_TLSEXT_ERR_NOACK; | 678 return SSL_TLSEXT_ERR_NOACK; |
664 } | 679 } |
665 | 680 |
666 r = c->data; | |
667 | |
668 host.data = (u_char *) servername; | 681 host.data = (u_char *) servername; |
669 | 682 |
670 if (ngx_http_validate_host(&host, r->pool, 1) != NGX_OK) { | 683 if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) { |
671 return SSL_TLSEXT_ERR_NOACK; | 684 return SSL_TLSEXT_ERR_NOACK; |
672 } | 685 } |
673 | 686 |
674 hc = r->http_connection; | 687 hc = c->data; |
675 | 688 |
676 if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host, | 689 if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host, |
677 NULL, &cscf) | 690 NULL, &cscf) |
678 != NGX_OK) | 691 != NGX_OK) |
679 { | 692 { |
680 return SSL_TLSEXT_ERR_NOACK; | 693 return SSL_TLSEXT_ERR_NOACK; |
681 } | 694 } |
682 | 695 |
683 hc->conf_ctx = cscf->ctx; | 696 hc->conf_ctx = cscf->ctx; |
684 | 697 |
685 r->srv_conf = cscf->ctx->srv_conf; | 698 clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module); |
686 r->loc_conf = cscf->ctx->loc_conf; | |
687 | |
688 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
689 | 699 |
690 ngx_http_set_connection_log(c, clcf->error_log); | 700 ngx_http_set_connection_log(c, clcf->error_log); |
691 | 701 |
692 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); | 702 sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); |
693 | 703 |
694 if (sscf->ssl.ctx) { | 704 if (sscf->ssl.ctx) { |
695 SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx); | 705 SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx); |
696 | 706 |
697 /* | 707 /* |
1629 { | 1639 { |
1630 ngx_connection_t *c; | 1640 ngx_connection_t *c; |
1631 | 1641 |
1632 c = r->connection; | 1642 c = r->connection; |
1633 | 1643 |
1634 if (r->plain_http) { | |
1635 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1636 "client sent plain HTTP request to HTTPS port"); | |
1637 ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); | |
1638 return; | |
1639 } | |
1640 | |
1641 #if (NGX_HTTP_SSL) | 1644 #if (NGX_HTTP_SSL) |
1642 | 1645 |
1643 if (c->ssl) { | 1646 if (r->http_connection->ssl) { |
1644 long rc; | 1647 long rc; |
1645 X509 *cert; | 1648 X509 *cert; |
1646 ngx_http_ssl_srv_conf_t *sscf; | 1649 ngx_http_ssl_srv_conf_t *sscf; |
1650 | |
1651 if (c->ssl == NULL) { | |
1652 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1653 "client sent plain HTTP request to HTTPS port"); | |
1654 ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); | |
1655 return; | |
1656 } | |
1647 | 1657 |
1648 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); | 1658 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); |
1649 | 1659 |
1650 if (sscf->verify) { | 1660 if (sscf->verify) { |
1651 rc = SSL_get_verify_result(c->ssl->connection); | 1661 rc = SSL_get_verify_result(c->ssl->connection); |