2 * nghttp2 - HTTP/2 C Library
4 * Copyright (c) 2012 Tatsuhiro Tsujikawa
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #include "shrpx_client_handler.h"
30 #include "shrpx_upstream.h"
31 #include "shrpx_http2_upstream.h"
32 #include "shrpx_https_upstream.h"
33 #include "shrpx_config.h"
34 #include "shrpx_http_downstream_connection.h"
35 #include "shrpx_http2_downstream_connection.h"
36 #include "shrpx_ssl.h"
37 #include "shrpx_worker.h"
38 #include "shrpx_worker_config.h"
39 #include "shrpx_downstream_connection_pool.h"
40 #include "shrpx_downstream.h"
42 #include "shrpx_spdy_upstream.h"
43 #endif // HAVE_SPDYLAY
47 using namespace nghttp2;
52 void timeoutcb(struct ev_loop *loop, ev_timer *w, int revents) {
53 auto conn = static_cast<Connection *>(w->data);
54 auto handler = static_cast<ClientHandler *>(conn->data);
56 if (LOG_ENABLED(INFO)) {
57 CLOG(INFO, handler) << "Time out";
65 void shutdowncb(struct ev_loop *loop, ev_timer *w, int revents) {
66 auto handler = static_cast<ClientHandler *>(w->data);
68 if (LOG_ENABLED(INFO)) {
69 CLOG(INFO, handler) << "Close connection due to TLS renegotiation";
77 void readcb(struct ev_loop *loop, ev_io *w, int revents) {
78 auto conn = static_cast<Connection *>(w->data);
79 auto handler = static_cast<ClientHandler *>(conn->data);
81 if (handler->do_read() != 0) {
89 void writecb(struct ev_loop *loop, ev_io *w, int revents) {
90 auto conn = static_cast<Connection *>(w->data);
91 auto handler = static_cast<ClientHandler *>(conn->data);
93 if (handler->do_write() != 0) {
100 int ClientHandler::read_clear() {
101 ev_timer_again(conn_.loop, &conn_.rt);
104 // we should process buffered data first before we read EOF.
105 if (rb_.rleft() && on_read() != 0) {
113 auto nread = conn_.read_clear(rb_.last, rb_.wleft());
127 int ClientHandler::write_clear() {
128 ev_timer_again(conn_.loop, &conn_.rt);
131 if (wb_.rleft() > 0) {
132 auto nwrite = conn_.write_clear(wb_.pos, wb_.rleft());
143 if (on_write() != 0) {
146 if (wb_.rleft() == 0) {
151 conn_.wlimit.stopw();
152 ev_timer_stop(conn_.loop, &conn_.wt);
157 int ClientHandler::tls_handshake() {
158 ev_timer_again(conn_.loop, &conn_.rt);
162 auto rv = conn_.tls_handshake();
164 if (rv == SHRPX_ERR_INPROGRESS) {
172 if (LOG_ENABLED(INFO)) {
173 CLOG(INFO, this) << "SSL/TLS handshake completed";
176 if (validate_next_proto() != 0) {
180 read_ = &ClientHandler::read_tls;
181 write_ = &ClientHandler::write_tls;
186 int ClientHandler::read_tls() {
187 ev_timer_again(conn_.loop, &conn_.rt);
192 // we should process buffered data first before we read EOF.
193 if (rb_.rleft() && on_read() != 0) {
201 auto nread = conn_.read_tls(rb_.last, rb_.wleft());
215 int ClientHandler::write_tls() {
216 ev_timer_again(conn_.loop, &conn_.rt);
221 if (wb_.rleft() > 0) {
222 auto nwrite = conn_.write_tls(wb_.pos, wb_.rleft());
237 if (on_write() != 0) {
240 if (wb_.rleft() == 0) {
245 conn_.wlimit.stopw();
246 ev_timer_stop(conn_.loop, &conn_.wt);
251 int ClientHandler::upstream_noop() { return 0; }
253 int ClientHandler::upstream_read() {
255 if (upstream_->on_read() != 0) {
261 int ClientHandler::upstream_write() {
263 if (upstream_->on_write() != 0) {
267 if (get_should_close_after_write() && wb_.rleft() == 0) {
274 int ClientHandler::upstream_http2_connhd_read() {
275 auto nread = std::min(left_connhd_len_, rb_.rleft());
276 if (memcmp(NGHTTP2_CLIENT_CONNECTION_PREFACE +
277 NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN - left_connhd_len_,
278 rb_.pos, nread) != 0) {
279 // There is no downgrade path here. Just drop the connection.
280 if (LOG_ENABLED(INFO)) {
281 CLOG(INFO, this) << "invalid client connection header";
287 left_connhd_len_ -= nread;
290 if (left_connhd_len_ == 0) {
291 on_read_ = &ClientHandler::upstream_read;
292 // Run on_read to process data left in buffer since they are not
294 if (on_read() != 0) {
303 int ClientHandler::upstream_http1_connhd_read() {
304 auto nread = std::min(left_connhd_len_, rb_.rleft());
305 if (memcmp(NGHTTP2_CLIENT_CONNECTION_PREFACE +
306 NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN - left_connhd_len_,
307 rb_.pos, nread) != 0) {
308 if (LOG_ENABLED(INFO)) {
309 CLOG(INFO, this) << "This is HTTP/1.1 connection, "
310 << "but may be upgraded to HTTP/2 later.";
313 // Reset header length for later HTTP/2 upgrade
314 left_connhd_len_ = NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN;
315 on_read_ = &ClientHandler::upstream_read;
316 on_write_ = &ClientHandler::upstream_write;
318 if (on_read() != 0) {
325 left_connhd_len_ -= nread;
328 if (left_connhd_len_ == 0) {
329 if (LOG_ENABLED(INFO)) {
330 CLOG(INFO, this) << "direct HTTP/2 connection";
333 direct_http2_upgrade();
334 on_read_ = &ClientHandler::upstream_read;
335 on_write_ = &ClientHandler::upstream_write;
337 // Run on_read to process data left in buffer since they are not
339 if (on_read() != 0) {
349 ClientHandler::ClientHandler(struct ev_loop *loop, int fd, SSL *ssl,
350 const char *ipaddr, const char *port,
351 WorkerStat *worker_stat,
352 DownstreamConnectionPool *dconn_pool)
353 : conn_(loop, fd, ssl, get_config()->upstream_write_timeout,
354 get_config()->upstream_read_timeout, get_config()->write_rate,
355 get_config()->write_burst, get_config()->read_rate,
356 get_config()->read_burst, writecb, readcb, timeoutcb, this),
357 ipaddr_(ipaddr), port_(port), dconn_pool_(dconn_pool),
358 http2session_(nullptr), http1_connect_blocker_(nullptr),
359 worker_stat_(worker_stat),
360 left_connhd_len_(NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN),
361 should_close_after_write_(false) {
363 ++worker_stat->num_connections;
365 ev_timer_init(&reneg_shutdown_timer_, shutdowncb, 0., 0.);
367 reneg_shutdown_timer_.data = this;
369 conn_.rlimit.startw();
370 ev_timer_again(conn_.loop, &conn_.rt);
373 SSL_set_app_data(conn_.tls.ssl, &conn_);
374 read_ = write_ = &ClientHandler::tls_handshake;
375 on_read_ = &ClientHandler::upstream_noop;
376 on_write_ = &ClientHandler::upstream_write;
378 // For non-TLS version, first create HttpsUpstream. It may be
379 // upgraded to HTTP/2 through HTTP Upgrade or direct HTTP/2
381 upstream_ = make_unique<HttpsUpstream>(this);
383 read_ = &ClientHandler::read_clear;
384 write_ = &ClientHandler::write_clear;
385 on_read_ = &ClientHandler::upstream_http1_connhd_read;
386 on_write_ = &ClientHandler::upstream_noop;
390 ClientHandler::~ClientHandler() {
391 if (LOG_ENABLED(INFO)) {
392 CLOG(INFO, this) << "Deleting";
396 upstream_->on_handler_delete();
399 --worker_stat_->num_connections;
401 ev_timer_stop(conn_.loop, &reneg_shutdown_timer_);
403 // TODO If backend is http/2, and it is in CONNECTED state, signal
404 // it and make it loopbreak when output is zero.
405 if (worker_config->graceful_shutdown && worker_stat_->num_connections == 0) {
406 ev_break(conn_.loop);
409 if (LOG_ENABLED(INFO)) {
410 CLOG(INFO, this) << "Deleted";
414 Upstream *ClientHandler::get_upstream() { return upstream_.get(); }
416 struct ev_loop *ClientHandler::get_loop() const {
420 void ClientHandler::reset_upstream_read_timeout(ev_tstamp t) {
422 if (ev_is_active(&conn_.rt)) {
423 ev_timer_again(conn_.loop, &conn_.rt);
427 void ClientHandler::reset_upstream_write_timeout(ev_tstamp t) {
429 if (ev_is_active(&conn_.wt)) {
430 ev_timer_again(conn_.loop, &conn_.wt);
434 int ClientHandler::validate_next_proto() {
435 const unsigned char *next_proto = nullptr;
436 unsigned int next_proto_len;
439 // First set callback for catch all cases
440 on_read_ = &ClientHandler::upstream_read;
442 SSL_get0_next_proto_negotiated(conn_.tls.ssl, &next_proto, &next_proto_len);
443 for (int i = 0; i < 2; ++i) {
445 if (LOG_ENABLED(INFO)) {
446 std::string proto(next_proto, next_proto + next_proto_len);
447 CLOG(INFO, this) << "The negotiated next protocol: " << proto;
449 if (!ssl::in_proto_list(get_config()->npn_list, next_proto,
453 if (util::check_h2_is_selected(next_proto, next_proto_len) ||
454 (next_proto_len == sizeof("h2-16") - 1 &&
455 memcmp("h2-16", next_proto, next_proto_len) == 0)) {
457 on_read_ = &ClientHandler::upstream_http2_connhd_read;
459 auto http2_upstream = make_unique<Http2Upstream>(this);
461 if (!ssl::check_http2_requirement(conn_.tls.ssl)) {
462 rv = http2_upstream->terminate_session(NGHTTP2_INADEQUATE_SECURITY);
469 upstream_ = std::move(http2_upstream);
470 alpn_.assign(next_proto, next_proto + next_proto_len);
472 // At this point, input buffer is already filled with some
473 // bytes. The read callback is not called until new data
474 // come. So consume input buffer here.
475 if (on_read() != 0) {
482 uint16_t version = spdylay_npn_get_version(next_proto, next_proto_len);
484 upstream_ = make_unique<SpdyUpstream>(version, this);
487 case SPDYLAY_PROTO_SPDY2:
490 case SPDYLAY_PROTO_SPDY3:
493 case SPDYLAY_PROTO_SPDY3_1:
497 alpn_ = "spdy/unknown";
500 // At this point, input buffer is already filled with some
501 // bytes. The read callback is not called until new data
502 // come. So consume input buffer here.
503 if (on_read() != 0) {
509 #endif // HAVE_SPDYLAY
510 if (next_proto_len == 8 && memcmp("http/1.1", next_proto, 8) == 0) {
511 upstream_ = make_unique<HttpsUpstream>(this);
514 // At this point, input buffer is already filled with some
515 // bytes. The read callback is not called until new data
516 // come. So consume input buffer here.
517 if (on_read() != 0) {
526 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
527 SSL_get0_alpn_selected(conn_.tls.ssl, &next_proto, &next_proto_len);
528 #else // OPENSSL_VERSION_NUMBER < 0x10002000L
530 #endif // OPENSSL_VERSION_NUMBER < 0x10002000L
533 if (LOG_ENABLED(INFO)) {
534 CLOG(INFO, this) << "No protocol negotiated. Fallback to HTTP/1.1";
536 upstream_ = make_unique<HttpsUpstream>(this);
539 // At this point, input buffer is already filled with some bytes.
540 // The read callback is not called until new data come. So consume
541 // input buffer here.
542 if (on_read() != 0) {
548 if (LOG_ENABLED(INFO)) {
549 CLOG(INFO, this) << "The negotiated protocol is not supported";
554 int ClientHandler::do_read() { return read_(*this); }
555 int ClientHandler::do_write() { return write_(*this); }
557 int ClientHandler::on_read() { return on_read_(*this); }
558 int ClientHandler::on_write() { return on_write_(*this); }
560 const std::string &ClientHandler::get_ipaddr() const { return ipaddr_; }
562 bool ClientHandler::get_should_close_after_write() const {
563 return should_close_after_write_;
566 void ClientHandler::set_should_close_after_write(bool f) {
567 should_close_after_write_ = f;
570 void ClientHandler::pool_downstream_connection(
571 std::unique_ptr<DownstreamConnection> dconn) {
572 if (LOG_ENABLED(INFO)) {
573 CLOG(INFO, this) << "Pooling downstream connection DCONN:" << dconn.get();
575 dconn->set_client_handler(nullptr);
576 dconn_pool_->add_downstream_connection(std::move(dconn));
579 void ClientHandler::remove_downstream_connection(DownstreamConnection *dconn) {
580 if (LOG_ENABLED(INFO)) {
581 CLOG(INFO, this) << "Removing downstream connection DCONN:" << dconn
584 dconn_pool_->remove_downstream_connection(dconn);
587 std::unique_ptr<DownstreamConnection>
588 ClientHandler::get_downstream_connection() {
589 auto dconn = dconn_pool_->pop_downstream_connection();
592 if (LOG_ENABLED(INFO)) {
593 CLOG(INFO, this) << "Downstream connection pool is empty."
594 << " Create new one";
599 make_unique<Http2DownstreamConnection>(dconn_pool_, http2session_);
601 dconn = make_unique<HttpDownstreamConnection>(dconn_pool_, conn_.loop);
603 dconn->set_client_handler(this);
607 dconn->set_client_handler(this);
609 if (LOG_ENABLED(INFO)) {
610 CLOG(INFO, this) << "Reuse downstream connection DCONN:" << dconn.get()
617 SSL *ClientHandler::get_ssl() const { return conn_.tls.ssl; }
619 void ClientHandler::set_http2_session(Http2Session *http2session) {
620 http2session_ = http2session;
623 Http2Session *ClientHandler::get_http2_session() const { return http2session_; }
625 void ClientHandler::set_http1_connect_blocker(
626 ConnectBlocker *http1_connect_blocker) {
627 http1_connect_blocker_ = http1_connect_blocker;
630 ConnectBlocker *ClientHandler::get_http1_connect_blocker() const {
631 return http1_connect_blocker_;
634 void ClientHandler::direct_http2_upgrade() {
635 upstream_ = make_unique<Http2Upstream>(this);
636 // TODO We don't know exact h2 draft version in direct upgrade. We
637 // just use library default for now.
638 alpn_ = NGHTTP2_CLEARTEXT_PROTO_VERSION_ID;
639 on_read_ = &ClientHandler::upstream_read;
642 int ClientHandler::perform_http2_upgrade(HttpsUpstream *http) {
643 auto upstream = make_unique<Http2Upstream>(this);
644 if (upstream->upgrade_upstream(http) != 0) {
647 // http pointer is now owned by upstream.
649 upstream_ = std::move(upstream);
650 // TODO We might get other version id in HTTP2-settings, if we
651 // support aliasing for h2, but we just use library default for now.
652 alpn_ = NGHTTP2_CLEARTEXT_PROTO_VERSION_ID;
653 on_read_ = &ClientHandler::upstream_http2_connhd_read;
655 static char res[] = "HTTP/1.1 101 Switching Protocols\r\n"
656 "Connection: Upgrade\r\n"
657 "Upgrade: " NGHTTP2_CLEARTEXT_PROTO_VERSION_ID "\r\n"
659 wb_.write(res, sizeof(res) - 1);
663 bool ClientHandler::get_http2_upgrade_allowed() const { return !conn_.tls.ssl; }
665 std::string ClientHandler::get_upstream_scheme() const {
673 void ClientHandler::start_immediate_shutdown() {
674 ev_timer_start(conn_.loop, &reneg_shutdown_timer_);
677 void ClientHandler::write_accesslog(Downstream *downstream) {
679 downstream, ipaddr_.c_str(), downstream->get_request_method().c_str(),
681 downstream->get_request_path().empty()
682 ? downstream->get_request_http2_authority().c_str()
683 : downstream->get_request_path().c_str(),
687 std::chrono::system_clock::now(), // time_now
688 downstream->get_request_start_time(), // request_start_time
689 std::chrono::high_resolution_clock::now(), // request_end_time
691 downstream->get_request_major(), downstream->get_request_minor(),
692 downstream->get_response_http_status(),
693 downstream->get_response_sent_bodylen(), port_.c_str(),
694 get_config()->port, get_config()->pid,
697 upstream_accesslog(get_config()->accesslog_format, &lgsp);
700 void ClientHandler::write_accesslog(int major, int minor, unsigned int status,
701 int64_t body_bytes_sent) {
702 auto time_now = std::chrono::system_clock::now();
703 auto highres_now = std::chrono::high_resolution_clock::now();
706 nullptr, ipaddr_.c_str(),
709 alpn_.c_str(), time_now,
710 highres_now, // request_start_time TODO is
711 // there a better value?
712 highres_now, // request_end_time
713 major, minor, // major, minor
714 status, body_bytes_sent, port_.c_str(),
715 get_config()->port, get_config()->pid,
718 upstream_accesslog(get_config()->accesslog_format, &lgsp);
721 WorkerStat *ClientHandler::get_worker_stat() const { return worker_stat_; }
723 ClientHandler::WriteBuf *ClientHandler::get_wb() { return &wb_; }
725 ClientHandler::ReadBuf *ClientHandler::get_rb() { return &rb_; }
727 void ClientHandler::signal_write() { conn_.wlimit.startw(); }
729 RateLimit *ClientHandler::get_rlimit() { return &conn_.rlimit; }
730 RateLimit *ClientHandler::get_wlimit() { return &conn_.wlimit; }