Imported Upstream version 1.0.0
[platform/upstream/nghttp2.git] / src / shrpx_http2_session.cc
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2012 Tatsuhiro Tsujikawa
5  *
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:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
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.
24  */
25 #include "shrpx_http2_session.h"
26
27 #include <netinet/tcp.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif // HAVE_UNISTD_H
31
32 #include <vector>
33
34 #include <openssl/err.h>
35
36 #include "shrpx_upstream.h"
37 #include "shrpx_downstream.h"
38 #include "shrpx_config.h"
39 #include "shrpx_error.h"
40 #include "shrpx_http2_downstream_connection.h"
41 #include "shrpx_client_handler.h"
42 #include "shrpx_ssl.h"
43 #include "shrpx_http.h"
44 #include "shrpx_worker.h"
45 #include "shrpx_connect_blocker.h"
46 #include "http2.h"
47 #include "util.h"
48 #include "base64.h"
49
50 using namespace nghttp2;
51
52 namespace shrpx {
53
54 namespace {
55 const ev_tstamp CONNCHK_TIMEOUT = 5.;
56 const ev_tstamp CONNCHK_PING_TIMEOUT = 1.;
57 } // namespace
58
59 namespace {
60 void connchk_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
61   auto http2session = static_cast<Http2Session *>(w->data);
62
63   ev_timer_stop(loop, w);
64
65   switch (http2session->get_connection_check_state()) {
66   case Http2Session::CONNECTION_CHECK_STARTED:
67     // ping timeout; disconnect
68     if (LOG_ENABLED(INFO)) {
69       SSLOG(INFO, http2session) << "ping timeout";
70     }
71     http2session->disconnect();
72     return;
73   default:
74     if (LOG_ENABLED(INFO)) {
75       SSLOG(INFO, http2session) << "connection check required";
76     }
77     http2session->set_connection_check_state(
78         Http2Session::CONNECTION_CHECK_REQUIRED);
79   }
80 }
81 } // namespace
82
83 namespace {
84 void settings_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
85   auto http2session = static_cast<Http2Session *>(w->data);
86   http2session->stop_settings_timer();
87   SSLOG(INFO, http2session) << "SETTINGS timeout";
88   if (http2session->terminate_session(NGHTTP2_SETTINGS_TIMEOUT) != 0) {
89     http2session->disconnect();
90     return;
91   }
92   http2session->signal_write();
93 }
94 } // namespace
95
96 namespace {
97 void timeoutcb(struct ev_loop *loop, ev_timer *w, int revents) {
98   auto conn = static_cast<Connection *>(w->data);
99   auto http2session = static_cast<Http2Session *>(conn->data);
100
101   if (LOG_ENABLED(INFO)) {
102     SSLOG(INFO, http2session) << "Timeout";
103   }
104
105   http2session->disconnect(http2session->get_state() ==
106                            Http2Session::CONNECTING);
107 }
108 } // namespace
109
110 namespace {
111 void readcb(struct ev_loop *loop, ev_io *w, int revents) {
112   int rv;
113   auto conn = static_cast<Connection *>(w->data);
114   auto http2session = static_cast<Http2Session *>(conn->data);
115   rv = http2session->do_read();
116   if (rv != 0) {
117     http2session->disconnect(http2session->should_hard_fail());
118     return;
119   }
120   http2session->connection_alive();
121
122   rv = http2session->do_write();
123   if (rv != 0) {
124     http2session->disconnect(http2session->should_hard_fail());
125     return;
126   }
127 }
128 } // namespace
129
130 namespace {
131 void writecb(struct ev_loop *loop, ev_io *w, int revents) {
132   int rv;
133   auto conn = static_cast<Connection *>(w->data);
134   auto http2session = static_cast<Http2Session *>(conn->data);
135   rv = http2session->do_write();
136   if (rv != 0) {
137     http2session->disconnect(http2session->should_hard_fail());
138     return;
139   }
140   http2session->reset_connection_check_timer_if_not_checking();
141 }
142 } // namespace
143
144 Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
145                            ConnectBlocker *connect_blocker, Worker *worker)
146     : conn_(loop, -1, nullptr, get_config()->downstream_write_timeout,
147             get_config()->downstream_read_timeout, 0, 0, 0, 0, writecb, readcb,
148             timeoutcb, this),
149       worker_(worker), connect_blocker_(connect_blocker), ssl_ctx_(ssl_ctx),
150       session_(nullptr), data_pending_(nullptr), data_pendinglen_(0),
151       addr_idx_(0), state_(DISCONNECTED),
152       connection_check_state_(CONNECTION_CHECK_NONE), flow_control_(false) {
153
154   read_ = write_ = &Http2Session::noop;
155   on_read_ = on_write_ = &Http2Session::noop;
156
157   // We will resuse this many times, so use repeat timeout value.  The
158   // timeout value is set later.
159   ev_timer_init(&connchk_timer_, connchk_timeout_cb, 0., 0.);
160
161   connchk_timer_.data = this;
162
163   // SETTINGS ACK timeout is 10 seconds for now.  We will resuse this
164   // many times, so use repeat timeout value.
165   ev_timer_init(&settings_timer_, settings_timeout_cb, 0., 10.);
166
167   settings_timer_.data = this;
168 }
169
170 Http2Session::~Http2Session() { disconnect(); }
171
172 int Http2Session::disconnect(bool hard) {
173   if (LOG_ENABLED(INFO)) {
174     SSLOG(INFO, this) << "Disconnecting";
175   }
176   nghttp2_session_del(session_);
177   session_ = nullptr;
178
179   rb_.reset();
180   wb_.reset();
181
182   conn_.rlimit.stopw();
183   conn_.wlimit.stopw();
184
185   ev_timer_stop(conn_.loop, &settings_timer_);
186   ev_timer_stop(conn_.loop, &connchk_timer_);
187
188   read_ = write_ = &Http2Session::noop;
189   on_read_ = on_write_ = &Http2Session::noop;
190
191   conn_.disconnect();
192
193   addr_idx_ = 0;
194
195   if (proxy_htp_) {
196     proxy_htp_.reset();
197   }
198
199   connection_check_state_ = CONNECTION_CHECK_NONE;
200   state_ = DISCONNECTED;
201
202   // Delete all client handler associated to Downstream. When deleting
203   // Http2DownstreamConnection, it calls this object's
204   // remove_downstream_connection(). The multiple
205   // Http2DownstreamConnection objects belong to the same
206   // ClientHandler object. So first dump ClientHandler objects.  We
207   // want to allow creating new pending Http2DownstreamConnection with
208   // this object.  In order to achieve this, we first swap dconns_ and
209   // streams_.  Upstream::on_downstream_reset() may add
210   // Http2DownstreamConnection.
211   auto dconns = std::move(dconns_);
212   auto streams = std::move(streams_);
213
214   std::set<ClientHandler *> handlers;
215   for (auto dc = dconns.head; dc; dc = dc->dlnext) {
216     if (!dc->get_client_handler()) {
217       continue;
218     }
219     handlers.insert(dc->get_client_handler());
220   }
221   for (auto h : handlers) {
222     if (h->get_upstream()->on_downstream_reset(hard) != 0) {
223       delete h;
224     }
225   }
226
227   for (auto s = streams.head; s;) {
228     auto next = s->dlnext;
229     delete s;
230     s = next;
231   }
232
233   return 0;
234 }
235
236 int Http2Session::check_cert() { return ssl::check_cert(conn_.tls.ssl); }
237
238 int Http2Session::initiate_connection() {
239   int rv = 0;
240
241   if (state_ == DISCONNECTED) {
242     if (connect_blocker_->blocked()) {
243       if (LOG_ENABLED(INFO)) {
244         DCLOG(INFO, this)
245             << "Downstream connection was blocked by connect_blocker";
246       }
247       return -1;
248     }
249
250     auto worker_stat = worker_->get_worker_stat();
251     addr_idx_ = worker_stat->next_downstream;
252     ++worker_stat->next_downstream;
253     worker_stat->next_downstream %= get_config()->downstream_addrs.size();
254
255     if (LOG_ENABLED(INFO)) {
256       SSLOG(INFO, this) << "Using downstream address idx=" << addr_idx_
257                         << " out of " << get_config()->downstream_addrs.size();
258     }
259   }
260
261   auto &downstream_addr = get_config()->downstream_addrs[addr_idx_];
262
263   if (get_config()->downstream_http_proxy_host && state_ == DISCONNECTED) {
264     if (LOG_ENABLED(INFO)) {
265       SSLOG(INFO, this) << "Connecting to the proxy "
266                         << get_config()->downstream_http_proxy_host.get() << ":"
267                         << get_config()->downstream_http_proxy_port;
268     }
269
270     conn_.fd = util::create_nonblock_socket(
271         get_config()->downstream_http_proxy_addr.storage.ss_family);
272
273     if (conn_.fd == -1) {
274       connect_blocker_->on_failure();
275       return -1;
276     }
277
278     rv = connect(conn_.fd, &get_config()->downstream_http_proxy_addr.sa,
279                  get_config()->downstream_http_proxy_addrlen);
280     if (rv != 0 && errno != EINPROGRESS) {
281       SSLOG(ERROR, this) << "Failed to connect to the proxy "
282                          << get_config()->downstream_http_proxy_host.get()
283                          << ":" << get_config()->downstream_http_proxy_port;
284       connect_blocker_->on_failure();
285       return -1;
286     }
287
288     ev_io_set(&conn_.rev, conn_.fd, EV_READ);
289     ev_io_set(&conn_.wev, conn_.fd, EV_WRITE);
290
291     conn_.wlimit.startw();
292
293     // TODO we should have timeout for connection establishment
294     ev_timer_again(conn_.loop, &conn_.wt);
295
296     write_ = &Http2Session::connected;
297
298     on_read_ = &Http2Session::downstream_read_proxy;
299     on_write_ = &Http2Session::downstream_connect_proxy;
300
301     proxy_htp_ = make_unique<http_parser>();
302     http_parser_init(proxy_htp_.get(), HTTP_RESPONSE);
303     proxy_htp_->data = this;
304
305     state_ = PROXY_CONNECTING;
306
307     return 0;
308   }
309
310   if (state_ == DISCONNECTED || state_ == PROXY_CONNECTED) {
311     if (LOG_ENABLED(INFO)) {
312       SSLOG(INFO, this) << "Connecting to downstream server";
313     }
314     if (ssl_ctx_) {
315       // We are establishing TLS connection.
316       conn_.tls.ssl = SSL_new(ssl_ctx_);
317       if (!conn_.tls.ssl) {
318         SSLOG(ERROR, this) << "SSL_new() failed: "
319                            << ERR_error_string(ERR_get_error(), NULL);
320         return -1;
321       }
322
323       const char *sni_name = nullptr;
324       if (get_config()->backend_tls_sni_name) {
325         sni_name = get_config()->backend_tls_sni_name.get();
326       } else {
327         sni_name = downstream_addr.host.get();
328       }
329
330       if (sni_name && !util::numeric_host(sni_name)) {
331         // TLS extensions: SNI. There is no documentation about the return
332         // code for this function (actually this is macro wrapping SSL_ctrl
333         // at the time of this writing).
334         SSL_set_tlsext_host_name(conn_.tls.ssl, sni_name);
335       }
336       // If state_ == PROXY_CONNECTED, we has connected to the proxy
337       // using conn_.fd and tunnel has been established.
338       if (state_ == DISCONNECTED) {
339         assert(conn_.fd == -1);
340
341         conn_.fd = util::create_nonblock_socket(
342             downstream_addr.addr.storage.ss_family);
343         if (conn_.fd == -1) {
344           connect_blocker_->on_failure();
345           return -1;
346         }
347
348         rv = connect(conn_.fd,
349                      // TODO maybe not thread-safe?
350                      const_cast<sockaddr *>(&downstream_addr.addr.sa),
351                      downstream_addr.addrlen);
352         if (rv != 0 && errno != EINPROGRESS) {
353           connect_blocker_->on_failure();
354           return -1;
355         }
356
357         ev_io_set(&conn_.rev, conn_.fd, EV_READ);
358         ev_io_set(&conn_.wev, conn_.fd, EV_WRITE);
359       }
360
361       if (SSL_set_fd(conn_.tls.ssl, conn_.fd) == 0) {
362         return -1;
363       }
364
365       SSL_set_connect_state(conn_.tls.ssl);
366     } else {
367       if (state_ == DISCONNECTED) {
368         // Without TLS and proxy.
369         assert(conn_.fd == -1);
370
371         conn_.fd = util::create_nonblock_socket(
372             downstream_addr.addr.storage.ss_family);
373
374         if (conn_.fd == -1) {
375           connect_blocker_->on_failure();
376           return -1;
377         }
378
379         rv = connect(conn_.fd, const_cast<sockaddr *>(&downstream_addr.addr.sa),
380                      downstream_addr.addrlen);
381         if (rv != 0 && errno != EINPROGRESS) {
382           connect_blocker_->on_failure();
383           return -1;
384         }
385
386         ev_io_set(&conn_.rev, conn_.fd, EV_READ);
387         ev_io_set(&conn_.wev, conn_.fd, EV_WRITE);
388       }
389     }
390
391     write_ = &Http2Session::connected;
392
393     on_write_ = &Http2Session::downstream_write;
394     on_read_ = &Http2Session::downstream_read;
395
396     // We have been already connected when no TLS and proxy is used.
397     if (state_ != CONNECTED) {
398       state_ = CONNECTING;
399       conn_.wlimit.startw();
400       // TODO we should have timeout for connection establishment
401       ev_timer_again(conn_.loop, &conn_.wt);
402     } else {
403       conn_.rlimit.startw();
404       ev_timer_again(conn_.loop, &conn_.rt);
405     }
406
407     return 0;
408   }
409
410   // Unreachable
411   DIE();
412   return 0;
413 }
414
415 namespace {
416 int htp_hdrs_completecb(http_parser *htp) {
417   auto http2session = static_cast<Http2Session *>(htp->data);
418
419   // We only read HTTP header part.  If tunneling succeeds, response
420   // body is a different protocol (HTTP/2 in this case), we don't read
421   // them here.
422   //
423   // Here is a caveat: http-parser returns 1 less bytes if we pause
424   // here.  The reason why they do this is probably they want to eat
425   // last 1 byte in s_headers_done state, on the other hand, this
426   // callback is called its previous state s_headers_almost_done.  We
427   // will do "+ 1" to the return value to workaround this.
428   http_parser_pause(htp, 1);
429
430   // We just check status code here
431   if (htp->status_code == 200) {
432     if (LOG_ENABLED(INFO)) {
433       SSLOG(INFO, http2session) << "Tunneling success";
434     }
435     http2session->set_state(Http2Session::PROXY_CONNECTED);
436
437     return 0;
438   }
439
440   SSLOG(WARN, http2session) << "Tunneling failed: " << htp->status_code;
441   http2session->set_state(Http2Session::PROXY_FAILED);
442
443   return 0;
444 }
445 } // namespace
446
447 namespace {
448 http_parser_settings htp_hooks = {
449     nullptr,             // http_cb      on_message_begin;
450     nullptr,             // http_data_cb on_url;
451     nullptr,             // http_data_cb on_status;
452     nullptr,             // http_data_cb on_header_field;
453     nullptr,             // http_data_cb on_header_value;
454     htp_hdrs_completecb, // http_cb      on_headers_complete;
455     nullptr,             // http_data_cb on_body;
456     nullptr              // http_cb      on_message_complete;
457 };
458 } // namespace
459
460 int Http2Session::downstream_read_proxy() {
461   if (rb_.rleft() == 0) {
462     return 0;
463   }
464
465   size_t nread =
466       http_parser_execute(proxy_htp_.get(), &htp_hooks,
467                           reinterpret_cast<const char *>(rb_.pos), rb_.rleft());
468
469   rb_.drain(nread);
470
471   auto htperr = HTTP_PARSER_ERRNO(proxy_htp_.get());
472
473   if (htperr == HPE_PAUSED) {
474     switch (state_) {
475     case Http2Session::PROXY_CONNECTED:
476       // we need to increment nread by 1 since http_parser_execute()
477       // returns 1 less value we expect.  This means taht
478       // rb_.pos[nread] points to \x0a (LF), which is last byte of
479       // empty line to terminate headers.  We want to eat that byte
480       // here.
481       rb_.drain(1);
482
483       // Initiate SSL/TLS handshake through established tunnel.
484       if (initiate_connection() != 0) {
485         return -1;
486       }
487       return 0;
488     case Http2Session::PROXY_FAILED:
489       return -1;
490     }
491     // should not be here
492     assert(0);
493   }
494
495   if (htperr != HPE_OK) {
496     return -1;
497   }
498
499   return 0;
500 }
501
502 int Http2Session::downstream_connect_proxy() {
503   if (LOG_ENABLED(INFO)) {
504     SSLOG(INFO, this) << "Connected to the proxy";
505   }
506   auto &downstream_addr = get_config()->downstream_addrs[addr_idx_];
507
508   std::string req = "CONNECT ";
509   req += downstream_addr.hostport.get();
510   if (downstream_addr.port == 80 || downstream_addr.port == 443) {
511     req += ":";
512     req += util::utos(downstream_addr.port);
513   }
514   req += " HTTP/1.1\r\nHost: ";
515   req += downstream_addr.host.get();
516   req += "\r\n";
517   if (get_config()->downstream_http_proxy_userinfo) {
518     req += "Proxy-Authorization: Basic ";
519     size_t len = strlen(get_config()->downstream_http_proxy_userinfo.get());
520     req += base64::encode(get_config()->downstream_http_proxy_userinfo.get(),
521                           get_config()->downstream_http_proxy_userinfo.get() +
522                               len);
523     req += "\r\n";
524   }
525   req += "\r\n";
526   if (LOG_ENABLED(INFO)) {
527     SSLOG(INFO, this) << "HTTP proxy request headers\n" << req;
528   }
529   auto nwrite = wb_.write(req.c_str(), req.size());
530   if (nwrite != req.size()) {
531     SSLOG(WARN, this) << "HTTP proxy request is too large";
532     return -1;
533   }
534   on_write_ = &Http2Session::noop;
535
536   signal_write();
537   return 0;
538 }
539
540 void Http2Session::add_downstream_connection(Http2DownstreamConnection *dconn) {
541   dconns_.append(dconn);
542 }
543
544 void
545 Http2Session::remove_downstream_connection(Http2DownstreamConnection *dconn) {
546   dconns_.remove(dconn);
547   dconn->detach_stream_data();
548 }
549
550 void Http2Session::remove_stream_data(StreamData *sd) {
551   streams_.remove(sd);
552   if (sd->dconn) {
553     sd->dconn->detach_stream_data();
554   }
555   delete sd;
556 }
557
558 int Http2Session::submit_request(Http2DownstreamConnection *dconn, int32_t pri,
559                                  const nghttp2_nv *nva, size_t nvlen,
560                                  const nghttp2_data_provider *data_prd) {
561   assert(state_ == CONNECTED);
562   auto sd = make_unique<StreamData>();
563   sd->dlnext = sd->dlprev = nullptr;
564   // TODO Specify nullptr to pri_spec for now
565   auto stream_id =
566       nghttp2_submit_request(session_, nullptr, nva, nvlen, data_prd, sd.get());
567   if (stream_id < 0) {
568     SSLOG(FATAL, this) << "nghttp2_submit_request() failed: "
569                        << nghttp2_strerror(stream_id);
570     return -1;
571   }
572
573   dconn->attach_stream_data(sd.get());
574   dconn->get_downstream()->set_downstream_stream_id(stream_id);
575   streams_.append(sd.release());
576
577   return 0;
578 }
579
580 int Http2Session::submit_rst_stream(int32_t stream_id, uint32_t error_code) {
581   assert(state_ == CONNECTED);
582   if (LOG_ENABLED(INFO)) {
583     SSLOG(INFO, this) << "RST_STREAM stream_id=" << stream_id
584                       << " with error_code=" << error_code;
585   }
586   int rv = nghttp2_submit_rst_stream(session_, NGHTTP2_FLAG_NONE, stream_id,
587                                      error_code);
588   if (rv != 0) {
589     SSLOG(FATAL, this) << "nghttp2_submit_rst_stream() failed: "
590                        << nghttp2_strerror(rv);
591     return -1;
592   }
593   return 0;
594 }
595
596 int Http2Session::submit_priority(Http2DownstreamConnection *dconn,
597                                   int32_t pri) {
598   assert(state_ == CONNECTED);
599   if (!dconn) {
600     return 0;
601   }
602   int rv;
603
604   // TODO Disabled temporarily
605
606   // rv = nghttp2_submit_priority(session_, NGHTTP2_FLAG_NONE,
607   //                              dconn->get_downstream()->
608   //                              get_downstream_stream_id(), pri);
609
610   rv = 0;
611
612   if (rv < NGHTTP2_ERR_FATAL) {
613     SSLOG(FATAL, this) << "nghttp2_submit_priority() failed: "
614                        << nghttp2_strerror(rv);
615     return -1;
616   }
617   return 0;
618 }
619
620 nghttp2_session *Http2Session::get_session() const { return session_; }
621
622 bool Http2Session::get_flow_control() const { return flow_control_; }
623
624 int Http2Session::resume_data(Http2DownstreamConnection *dconn) {
625   assert(state_ == CONNECTED);
626   auto downstream = dconn->get_downstream();
627   int rv = nghttp2_session_resume_data(session_,
628                                        downstream->get_downstream_stream_id());
629   switch (rv) {
630   case 0:
631   case NGHTTP2_ERR_INVALID_ARGUMENT:
632     return 0;
633   default:
634     SSLOG(FATAL, this) << "nghttp2_resume_session() failed: "
635                        << nghttp2_strerror(rv);
636     return -1;
637   }
638 }
639
640 namespace {
641 void call_downstream_readcb(Http2Session *http2session,
642                             Downstream *downstream) {
643   auto upstream = downstream->get_upstream();
644   if (!upstream) {
645     return;
646   }
647   if (upstream->downstream_read(downstream->get_downstream_connection()) != 0) {
648     delete upstream->get_client_handler();
649   }
650 }
651 } // namespace
652
653 namespace {
654 int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
655                              uint32_t error_code, void *user_data) {
656   auto http2session = static_cast<Http2Session *>(user_data);
657   if (LOG_ENABLED(INFO)) {
658     SSLOG(INFO, http2session) << "Stream stream_id=" << stream_id
659                               << " is being closed with error code "
660                               << error_code;
661   }
662   auto sd = static_cast<StreamData *>(
663       nghttp2_session_get_stream_user_data(session, stream_id));
664   if (sd == 0) {
665     // We might get this close callback when pushed streams are
666     // closed.
667     return 0;
668   }
669   auto dconn = sd->dconn;
670   if (dconn) {
671     auto downstream = dconn->get_downstream();
672     if (downstream && downstream->get_downstream_stream_id() == stream_id) {
673
674       if (downstream->get_upgraded() &&
675           downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
676         // For tunneled connection, we have to submit RST_STREAM to
677         // upstream *after* whole response body is sent. We just set
678         // MSG_COMPLETE here. Upstream will take care of that.
679         downstream->get_upstream()->on_downstream_body_complete(downstream);
680         downstream->set_response_state(Downstream::MSG_COMPLETE);
681       } else if (error_code == NGHTTP2_NO_ERROR) {
682         switch (downstream->get_response_state()) {
683         case Downstream::MSG_COMPLETE:
684         case Downstream::MSG_BAD_HEADER:
685           break;
686         default:
687           downstream->set_response_state(Downstream::MSG_RESET);
688         }
689       } else if (downstream->get_response_state() !=
690                  Downstream::MSG_BAD_HEADER) {
691         downstream->set_response_state(Downstream::MSG_RESET);
692       }
693       if (downstream->get_response_state() == Downstream::MSG_RESET &&
694           downstream->get_response_rst_stream_error_code() ==
695               NGHTTP2_NO_ERROR) {
696         downstream->set_response_rst_stream_error_code(error_code);
697       }
698       call_downstream_readcb(http2session, downstream);
699       // dconn may be deleted
700     }
701   }
702   // The life time of StreamData ends here
703   http2session->remove_stream_data(sd);
704   return 0;
705 }
706 } // namespace
707
708 void Http2Session::start_settings_timer() {
709   ev_timer_again(conn_.loop, &settings_timer_);
710 }
711
712 void Http2Session::stop_settings_timer() {
713   ev_timer_stop(conn_.loop, &settings_timer_);
714 }
715
716 namespace {
717 int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
718                        const uint8_t *name, size_t namelen,
719                        const uint8_t *value, size_t valuelen, uint8_t flags,
720                        void *user_data) {
721   auto sd = static_cast<StreamData *>(
722       nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
723   if (!sd || !sd->dconn) {
724     return 0;
725   }
726   auto downstream = sd->dconn->get_downstream();
727   if (!downstream) {
728     return 0;
729   }
730
731   if (frame->hd.type != NGHTTP2_HEADERS) {
732     return 0;
733   }
734
735   auto trailer = frame->headers.cat != NGHTTP2_HCAT_RESPONSE &&
736                  !downstream->get_expect_final_response();
737
738   if (downstream->get_response_headers_sum() + namelen + valuelen >
739           get_config()->header_field_buffer ||
740       downstream->get_response_headers().size() >=
741           get_config()->max_header_fields) {
742     if (LOG_ENABLED(INFO)) {
743       DLOG(INFO, downstream)
744           << "Too large or many header field size="
745           << downstream->get_response_headers_sum() + namelen + valuelen
746           << ", num=" << downstream->get_response_headers().size() + 1;
747     }
748
749     if (trailer) {
750       // we don't care trailer part exceeds header size limit; just
751       // discard it.
752       return 0;
753     }
754
755     return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
756   }
757
758   if (trailer) {
759     // just store header fields for trailer part
760     downstream->add_response_trailer(name, namelen, value, valuelen,
761                                      flags & NGHTTP2_NV_FLAG_NO_INDEX, -1);
762     return 0;
763   }
764
765   auto token = http2::lookup_token(name, namelen);
766
767   downstream->add_response_header(name, namelen, value, valuelen,
768                                   flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
769   return 0;
770 }
771 } // namespace
772
773 namespace {
774 int on_begin_headers_callback(nghttp2_session *session,
775                               const nghttp2_frame *frame, void *user_data) {
776   auto http2session = static_cast<Http2Session *>(user_data);
777   if (frame->hd.type != NGHTTP2_HEADERS ||
778       frame->headers.cat != NGHTTP2_HCAT_RESPONSE) {
779     return 0;
780   }
781   auto sd = static_cast<StreamData *>(
782       nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
783   if (!sd || !sd->dconn) {
784     http2session->submit_rst_stream(frame->hd.stream_id,
785                                     NGHTTP2_INTERNAL_ERROR);
786     return 0;
787   }
788   auto downstream = sd->dconn->get_downstream();
789   if (!downstream ||
790       downstream->get_downstream_stream_id() != frame->hd.stream_id) {
791     http2session->submit_rst_stream(frame->hd.stream_id,
792                                     NGHTTP2_INTERNAL_ERROR);
793     return 0;
794   }
795   return 0;
796 }
797 } // namespace
798
799 namespace {
800 int on_response_headers(Http2Session *http2session, Downstream *downstream,
801                         nghttp2_session *session, const nghttp2_frame *frame) {
802   int rv;
803
804   auto upstream = downstream->get_upstream();
805
806   auto &nva = downstream->get_response_headers();
807
808   downstream->set_expect_final_response(false);
809
810   auto status = downstream->get_response_header(http2::HD__STATUS);
811   // libnghttp2 guarantees this exists and can be parsed
812   auto status_code = http2::parse_http_status_code(status->value);
813
814   downstream->set_response_http_status(status_code);
815   downstream->set_response_major(2);
816   downstream->set_response_minor(0);
817
818   if (LOG_ENABLED(INFO)) {
819     std::stringstream ss;
820     for (auto &nv : nva) {
821       ss << TTY_HTTP_HD << nv.name << TTY_RST << ": " << nv.value << "\n";
822     }
823     SSLOG(INFO, http2session)
824         << "HTTP response headers. stream_id=" << frame->hd.stream_id << "\n"
825         << ss.str();
826   }
827
828   if (downstream->get_non_final_response()) {
829
830     if (LOG_ENABLED(INFO)) {
831       SSLOG(INFO, http2session) << "This is non-final response.";
832     }
833
834     downstream->set_expect_final_response(true);
835     rv = upstream->on_downstream_header_complete(downstream);
836
837     // Now Dowstream's response headers are erased.
838
839     if (rv != 0) {
840       http2session->submit_rst_stream(frame->hd.stream_id,
841                                       NGHTTP2_PROTOCOL_ERROR);
842       downstream->set_response_state(Downstream::MSG_RESET);
843     }
844
845     return 0;
846   }
847
848   downstream->set_response_state(Downstream::HEADER_COMPLETE);
849   downstream->check_upgrade_fulfilled();
850
851   if (downstream->get_upgraded()) {
852     downstream->set_response_connection_close(true);
853     // On upgrade sucess, both ends can send data
854     if (upstream->resume_read(SHRPX_NO_BUFFER, downstream, 0) != 0) {
855       // If resume_read fails, just drop connection. Not ideal.
856       delete upstream->get_client_handler();
857       return -1;
858     }
859     downstream->set_request_state(Downstream::HEADER_COMPLETE);
860     if (LOG_ENABLED(INFO)) {
861       SSLOG(INFO, http2session)
862           << "HTTP upgrade success. stream_id=" << frame->hd.stream_id;
863     }
864   } else {
865     auto content_length =
866         downstream->get_response_header(http2::HD_CONTENT_LENGTH);
867     if (content_length) {
868       // libnghttp2 guarantees this can be parsed
869       auto len = util::parse_uint(content_length->value);
870       downstream->set_response_content_length(len);
871     }
872
873     if (downstream->get_response_content_length() == -1 &&
874         downstream->expect_response_body()) {
875       // Here we have response body but Content-Length is not known in
876       // advance.
877       if (downstream->get_request_major() <= 0 ||
878           (downstream->get_request_major() == 1 &&
879            downstream->get_request_minor() == 0)) {
880         // We simply close connection for pre-HTTP/1.1 in this case.
881         downstream->set_response_connection_close(true);
882       } else {
883         // Otherwise, use chunked encoding to keep upstream connection
884         // open.  In HTTP2, we are supporsed not to receive
885         // transfer-encoding.
886         downstream->add_response_header("transfer-encoding", "chunked",
887                                         http2::HD_TRANSFER_ENCODING);
888         downstream->set_chunked_response(true);
889       }
890     }
891   }
892
893   rv = upstream->on_downstream_header_complete(downstream);
894   if (rv != 0) {
895     http2session->submit_rst_stream(frame->hd.stream_id,
896                                     NGHTTP2_PROTOCOL_ERROR);
897     downstream->set_response_state(Downstream::MSG_RESET);
898   }
899
900   return 0;
901 }
902 } // namespace
903
904 namespace {
905 int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
906                            void *user_data) {
907   int rv;
908   auto http2session = static_cast<Http2Session *>(user_data);
909
910   switch (frame->hd.type) {
911   case NGHTTP2_DATA: {
912     auto sd = static_cast<StreamData *>(
913         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
914     if (!sd || !sd->dconn) {
915       return 0;
916     }
917     auto downstream = sd->dconn->get_downstream();
918     if (!downstream ||
919         downstream->get_downstream_stream_id() != frame->hd.stream_id) {
920       return 0;
921     }
922
923     auto upstream = downstream->get_upstream();
924     rv = upstream->on_downstream_body(downstream, nullptr, 0, true);
925     if (rv != 0) {
926       http2session->submit_rst_stream(frame->hd.stream_id,
927                                       NGHTTP2_INTERNAL_ERROR);
928       downstream->set_response_state(Downstream::MSG_RESET);
929
930     } else if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
931
932       downstream->disable_downstream_rtimer();
933
934       if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
935
936         downstream->set_response_state(Downstream::MSG_COMPLETE);
937
938         rv = upstream->on_downstream_body_complete(downstream);
939
940         if (rv != 0) {
941           downstream->set_response_state(Downstream::MSG_RESET);
942         }
943       }
944     }
945
946     call_downstream_readcb(http2session, downstream);
947     return 0;
948   }
949   case NGHTTP2_HEADERS: {
950     auto sd = static_cast<StreamData *>(
951         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
952     if (!sd || !sd->dconn) {
953       return 0;
954     }
955     auto downstream = sd->dconn->get_downstream();
956
957     if (!downstream) {
958       return 0;
959     }
960
961     if (frame->headers.cat == NGHTTP2_HCAT_RESPONSE) {
962       rv = on_response_headers(http2session, downstream, session, frame);
963
964       if (rv != 0) {
965         return 0;
966       }
967     } else if (frame->headers.cat == NGHTTP2_HCAT_HEADERS) {
968       if (downstream->get_expect_final_response()) {
969         rv = on_response_headers(http2session, downstream, session, frame);
970
971         if (rv != 0) {
972           return 0;
973         }
974       }
975     }
976
977     if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
978       downstream->disable_downstream_rtimer();
979
980       if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
981         downstream->set_response_state(Downstream::MSG_COMPLETE);
982
983         auto upstream = downstream->get_upstream();
984
985         rv = upstream->on_downstream_body_complete(downstream);
986
987         if (rv != 0) {
988           downstream->set_response_state(Downstream::MSG_RESET);
989         }
990       }
991     } else {
992       downstream->reset_downstream_rtimer();
993     }
994
995     // This may delete downstream
996     call_downstream_readcb(http2session, downstream);
997
998     return 0;
999   }
1000   case NGHTTP2_RST_STREAM: {
1001     auto sd = static_cast<StreamData *>(
1002         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
1003     if (sd && sd->dconn) {
1004       auto downstream = sd->dconn->get_downstream();
1005       if (downstream &&
1006           downstream->get_downstream_stream_id() == frame->hd.stream_id) {
1007
1008         downstream->set_response_rst_stream_error_code(
1009             frame->rst_stream.error_code);
1010         call_downstream_readcb(http2session, downstream);
1011       }
1012     }
1013     return 0;
1014   }
1015   case NGHTTP2_SETTINGS:
1016     if ((frame->hd.flags & NGHTTP2_FLAG_ACK) == 0) {
1017       return 0;
1018     }
1019     http2session->stop_settings_timer();
1020     return 0;
1021   case NGHTTP2_PING:
1022     if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
1023       if (LOG_ENABLED(INFO)) {
1024         LOG(INFO) << "PING ACK received";
1025       }
1026       http2session->connection_alive();
1027     }
1028     return 0;
1029   case NGHTTP2_PUSH_PROMISE:
1030     if (LOG_ENABLED(INFO)) {
1031       SSLOG(INFO, http2session)
1032           << "Received downstream PUSH_PROMISE stream_id="
1033           << frame->hd.stream_id
1034           << ", promised_stream_id=" << frame->push_promise.promised_stream_id;
1035     }
1036     // We just respond with RST_STREAM.
1037     http2session->submit_rst_stream(frame->push_promise.promised_stream_id,
1038                                     NGHTTP2_REFUSED_STREAM);
1039     return 0;
1040   default:
1041     return 0;
1042   }
1043 }
1044 } // namespace
1045
1046 namespace {
1047 int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
1048                                 int32_t stream_id, const uint8_t *data,
1049                                 size_t len, void *user_data) {
1050   int rv;
1051   auto http2session = static_cast<Http2Session *>(user_data);
1052   auto sd = static_cast<StreamData *>(
1053       nghttp2_session_get_stream_user_data(session, stream_id));
1054   if (!sd || !sd->dconn) {
1055     http2session->submit_rst_stream(stream_id, NGHTTP2_INTERNAL_ERROR);
1056
1057     if (http2session->consume(stream_id, len) != 0) {
1058       return NGHTTP2_ERR_CALLBACK_FAILURE;
1059     }
1060
1061     return 0;
1062   }
1063   auto downstream = sd->dconn->get_downstream();
1064   if (!downstream || downstream->get_downstream_stream_id() != stream_id ||
1065       !downstream->expect_response_body()) {
1066
1067     http2session->submit_rst_stream(stream_id, NGHTTP2_INTERNAL_ERROR);
1068
1069     if (http2session->consume(stream_id, len) != 0) {
1070       return NGHTTP2_ERR_CALLBACK_FAILURE;
1071     }
1072
1073     return 0;
1074   }
1075
1076   // We don't want DATA after non-final response, which is illegal in
1077   // HTTP.
1078   if (downstream->get_non_final_response()) {
1079     http2session->submit_rst_stream(stream_id, NGHTTP2_PROTOCOL_ERROR);
1080
1081     if (http2session->consume(stream_id, len) != 0) {
1082       return NGHTTP2_ERR_CALLBACK_FAILURE;
1083     }
1084
1085     return 0;
1086   }
1087
1088   downstream->reset_downstream_rtimer();
1089
1090   downstream->add_response_bodylen(len);
1091
1092   auto upstream = downstream->get_upstream();
1093   rv = upstream->on_downstream_body(downstream, data, len, false);
1094   if (rv != 0) {
1095     http2session->submit_rst_stream(stream_id, NGHTTP2_INTERNAL_ERROR);
1096
1097     if (http2session->consume(stream_id, len) != 0) {
1098       return NGHTTP2_ERR_CALLBACK_FAILURE;
1099     }
1100
1101     downstream->set_response_state(Downstream::MSG_RESET);
1102   }
1103
1104   downstream->add_response_datalen(len);
1105
1106   call_downstream_readcb(http2session, downstream);
1107   return 0;
1108 }
1109 } // namespace
1110
1111 namespace {
1112 int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
1113                            void *user_data) {
1114   auto http2session = static_cast<Http2Session *>(user_data);
1115
1116   if (frame->hd.type == NGHTTP2_DATA || frame->hd.type == NGHTTP2_HEADERS) {
1117     if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
1118       return 0;
1119     }
1120
1121     auto sd = static_cast<StreamData *>(
1122         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
1123
1124     if (!sd || !sd->dconn) {
1125       return 0;
1126     }
1127
1128     auto downstream = sd->dconn->get_downstream();
1129
1130     if (!downstream ||
1131         downstream->get_downstream_stream_id() != frame->hd.stream_id) {
1132       return 0;
1133     }
1134
1135     downstream->reset_downstream_rtimer();
1136
1137     return 0;
1138   }
1139
1140   if (frame->hd.type == NGHTTP2_SETTINGS &&
1141       (frame->hd.flags & NGHTTP2_FLAG_ACK) == 0) {
1142     http2session->start_settings_timer();
1143   }
1144   return 0;
1145 }
1146 } // namespace
1147
1148 namespace {
1149 int on_frame_not_send_callback(nghttp2_session *session,
1150                                const nghttp2_frame *frame, int lib_error_code,
1151                                void *user_data) {
1152   auto http2session = static_cast<Http2Session *>(user_data);
1153   if (LOG_ENABLED(INFO)) {
1154     SSLOG(INFO, http2session) << "Failed to send control frame type="
1155                               << static_cast<uint32_t>(frame->hd.type)
1156                               << "lib_error_code=" << lib_error_code << ":"
1157                               << nghttp2_strerror(lib_error_code);
1158   }
1159   if (frame->hd.type == NGHTTP2_HEADERS &&
1160       lib_error_code != NGHTTP2_ERR_STREAM_CLOSED &&
1161       lib_error_code != NGHTTP2_ERR_STREAM_CLOSING) {
1162     // To avoid stream hanging around, flag Downstream::MSG_RESET.
1163     auto sd = static_cast<StreamData *>(
1164         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
1165     if (!sd) {
1166       return 0;
1167     }
1168     if (!sd->dconn) {
1169       return 0;
1170     }
1171     auto downstream = sd->dconn->get_downstream();
1172     if (!downstream ||
1173         downstream->get_downstream_stream_id() != frame->hd.stream_id) {
1174       return 0;
1175     }
1176     downstream->set_response_state(Downstream::MSG_RESET);
1177     call_downstream_readcb(http2session, downstream);
1178   }
1179   return 0;
1180 }
1181 } // namespace
1182
1183 nghttp2_session_callbacks *create_http2_downstream_callbacks() {
1184   int rv;
1185   nghttp2_session_callbacks *callbacks;
1186
1187   rv = nghttp2_session_callbacks_new(&callbacks);
1188
1189   if (rv != 0) {
1190     return nullptr;
1191   }
1192
1193   nghttp2_session_callbacks_set_on_stream_close_callback(
1194       callbacks, on_stream_close_callback);
1195
1196   nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
1197                                                        on_frame_recv_callback);
1198
1199   nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
1200       callbacks, on_data_chunk_recv_callback);
1201
1202   nghttp2_session_callbacks_set_on_frame_send_callback(callbacks,
1203                                                        on_frame_send_callback);
1204
1205   nghttp2_session_callbacks_set_on_frame_not_send_callback(
1206       callbacks, on_frame_not_send_callback);
1207
1208   nghttp2_session_callbacks_set_on_header_callback(callbacks,
1209                                                    on_header_callback);
1210
1211   nghttp2_session_callbacks_set_on_begin_headers_callback(
1212       callbacks, on_begin_headers_callback);
1213
1214   if (get_config()->padding) {
1215     nghttp2_session_callbacks_set_select_padding_callback(
1216         callbacks, http::select_padding_callback);
1217   }
1218
1219   return callbacks;
1220 }
1221
1222 int Http2Session::connection_made() {
1223   int rv;
1224
1225   state_ = Http2Session::CONNECTED;
1226
1227   if (ssl_ctx_) {
1228     const unsigned char *next_proto = nullptr;
1229     unsigned int next_proto_len;
1230     SSL_get0_next_proto_negotiated(conn_.tls.ssl, &next_proto, &next_proto_len);
1231     for (int i = 0; i < 2; ++i) {
1232       if (next_proto) {
1233         if (LOG_ENABLED(INFO)) {
1234           std::string proto(next_proto, next_proto + next_proto_len);
1235           SSLOG(INFO, this) << "Negotiated next protocol: " << proto;
1236         }
1237         if (!util::check_h2_is_selected(next_proto, next_proto_len)) {
1238           return -1;
1239         }
1240         break;
1241       }
1242 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1243       SSL_get0_alpn_selected(conn_.tls.ssl, &next_proto, &next_proto_len);
1244 #else  // OPENSSL_VERSION_NUMBER < 0x10002000L
1245       break;
1246 #endif // OPENSSL_VERSION_NUMBER < 0x10002000L
1247     }
1248     if (!next_proto) {
1249       return -1;
1250     }
1251   }
1252
1253   rv = nghttp2_session_client_new2(&session_,
1254                                    get_config()->http2_downstream_callbacks,
1255                                    this, get_config()->http2_client_option);
1256
1257   if (rv != 0) {
1258     return -1;
1259   }
1260
1261   flow_control_ = true;
1262
1263   std::array<nghttp2_settings_entry, 3> entry;
1264   entry[0].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
1265   entry[0].value = 0;
1266   entry[1].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
1267   entry[1].value = get_config()->http2_max_concurrent_streams;
1268
1269   entry[2].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
1270   entry[2].value = (1 << get_config()->http2_downstream_window_bits) - 1;
1271
1272   rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
1273                                entry.size());
1274   if (rv != 0) {
1275     return -1;
1276   }
1277
1278   if (get_config()->http2_downstream_connection_window_bits > 16) {
1279     int32_t delta =
1280         (1 << get_config()->http2_downstream_connection_window_bits) - 1 -
1281         NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
1282     rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
1283     if (rv != 0) {
1284       return -1;
1285     }
1286   }
1287
1288   auto must_terminate = !get_config()->downstream_no_tls &&
1289                         !ssl::check_http2_requirement(conn_.tls.ssl);
1290
1291   if (must_terminate) {
1292     rv = terminate_session(NGHTTP2_INADEQUATE_SECURITY);
1293
1294     if (rv != 0) {
1295       return -1;
1296     }
1297   }
1298
1299   if (must_terminate) {
1300     return 0;
1301   }
1302
1303   reset_connection_check_timer(CONNCHK_TIMEOUT);
1304
1305   submit_pending_requests();
1306
1307   signal_write();
1308   return 0;
1309 }
1310
1311 int Http2Session::do_read() { return read_(*this); }
1312 int Http2Session::do_write() { return write_(*this); }
1313
1314 int Http2Session::on_read() { return on_read_(*this); }
1315 int Http2Session::on_write() { return on_write_(*this); }
1316
1317 int Http2Session::downstream_read() {
1318   ssize_t rv = 0;
1319
1320   if (rb_.rleft() > 0) {
1321     rv = nghttp2_session_mem_recv(
1322         session_, reinterpret_cast<const uint8_t *>(rb_.pos), rb_.rleft());
1323
1324     if (rv < 0) {
1325       SSLOG(ERROR, this) << "nghttp2_session_recv() returned error: "
1326                          << nghttp2_strerror(rv);
1327       return -1;
1328     }
1329
1330     // nghttp2_session_mem_recv() should consume all input data in
1331     // case of success.
1332     rb_.reset();
1333   }
1334
1335   if (nghttp2_session_want_read(session_) == 0 &&
1336       nghttp2_session_want_write(session_) == 0 && wb_.rleft() == 0) {
1337     if (LOG_ENABLED(INFO)) {
1338       SSLOG(INFO, this) << "No more read/write for this HTTP2 session";
1339     }
1340     return -1;
1341   }
1342
1343   signal_write();
1344   return 0;
1345 }
1346
1347 int Http2Session::downstream_write() {
1348   if (data_pending_) {
1349     auto n = std::min(wb_.wleft(), data_pendinglen_);
1350     wb_.write(data_pending_, n);
1351     if (n < data_pendinglen_) {
1352       data_pending_ += n;
1353       data_pendinglen_ -= n;
1354       return 0;
1355     }
1356
1357     data_pending_ = nullptr;
1358     data_pendinglen_ = 0;
1359   }
1360
1361   for (;;) {
1362     const uint8_t *data;
1363     auto datalen = nghttp2_session_mem_send(session_, &data);
1364
1365     if (datalen < 0) {
1366       SSLOG(ERROR, this) << "nghttp2_session_mem_send() returned error: "
1367                          << nghttp2_strerror(datalen);
1368       return -1;
1369     }
1370     if (datalen == 0) {
1371       break;
1372     }
1373     auto n = wb_.write(data, datalen);
1374     if (n < static_cast<decltype(n)>(datalen)) {
1375       data_pending_ = data + n;
1376       data_pendinglen_ = datalen - n;
1377       return 0;
1378     }
1379   }
1380
1381   if (nghttp2_session_want_read(session_) == 0 &&
1382       nghttp2_session_want_write(session_) == 0 && wb_.rleft() == 0) {
1383     if (LOG_ENABLED(INFO)) {
1384       SSLOG(INFO, this) << "No more read/write for this session";
1385     }
1386     return -1;
1387   }
1388
1389   return 0;
1390 }
1391
1392 void Http2Session::signal_write() {
1393   switch (state_) {
1394   case Http2Session::DISCONNECTED:
1395     if (LOG_ENABLED(INFO)) {
1396       LOG(INFO) << "Start connecting to backend server";
1397     }
1398     if (initiate_connection() != 0) {
1399       if (LOG_ENABLED(INFO)) {
1400         SSLOG(INFO, this) << "Could not initiate backend connection";
1401       }
1402       disconnect(true);
1403     }
1404     break;
1405   case Http2Session::CONNECTED:
1406     conn_.wlimit.startw();
1407     break;
1408   }
1409 }
1410
1411 struct ev_loop *Http2Session::get_loop() const {
1412   return conn_.loop;
1413 }
1414
1415 ev_io *Http2Session::get_wev() { return &conn_.wev; }
1416
1417 int Http2Session::get_state() const { return state_; }
1418
1419 void Http2Session::set_state(int state) { state_ = state; }
1420
1421 int Http2Session::terminate_session(uint32_t error_code) {
1422   int rv;
1423   rv = nghttp2_session_terminate_session(session_, error_code);
1424   if (rv != 0) {
1425     return -1;
1426   }
1427   return 0;
1428 }
1429
1430 SSL *Http2Session::get_ssl() const { return conn_.tls.ssl; }
1431
1432 int Http2Session::consume(int32_t stream_id, size_t len) {
1433   int rv;
1434
1435   if (!session_) {
1436     return 0;
1437   }
1438
1439   rv = nghttp2_session_consume(session_, stream_id, len);
1440
1441   if (rv != 0) {
1442     SSLOG(WARN, this) << "nghttp2_session_consume() returned error: "
1443                       << nghttp2_strerror(rv);
1444
1445     return -1;
1446   }
1447
1448   return 0;
1449 }
1450
1451 bool Http2Session::can_push_request() const {
1452   return state_ == CONNECTED &&
1453          connection_check_state_ == CONNECTION_CHECK_NONE;
1454 }
1455
1456 void Http2Session::start_checking_connection() {
1457   if (state_ != CONNECTED ||
1458       connection_check_state_ != CONNECTION_CHECK_REQUIRED) {
1459     return;
1460   }
1461   connection_check_state_ = CONNECTION_CHECK_STARTED;
1462
1463   SSLOG(INFO, this) << "Start checking connection";
1464   // If connection is down, we may get error when writing data.  Issue
1465   // ping frame to see whether connection is alive.
1466   nghttp2_submit_ping(session_, NGHTTP2_FLAG_NONE, NULL);
1467
1468   // set ping timeout and start timer again
1469   reset_connection_check_timer(CONNCHK_PING_TIMEOUT);
1470
1471   signal_write();
1472 }
1473
1474 void Http2Session::reset_connection_check_timer(ev_tstamp t) {
1475   connchk_timer_.repeat = t;
1476   ev_timer_again(conn_.loop, &connchk_timer_);
1477 }
1478
1479 void Http2Session::reset_connection_check_timer_if_not_checking() {
1480   if (connection_check_state_ != CONNECTION_CHECK_NONE) {
1481     return;
1482   }
1483
1484   reset_connection_check_timer(CONNCHK_TIMEOUT);
1485 }
1486
1487 void Http2Session::connection_alive() {
1488   reset_connection_check_timer(CONNCHK_TIMEOUT);
1489
1490   if (connection_check_state_ == CONNECTION_CHECK_NONE) {
1491     return;
1492   }
1493
1494   if (LOG_ENABLED(INFO)) {
1495     SSLOG(INFO, this) << "Connection alive";
1496   }
1497
1498   connection_check_state_ = CONNECTION_CHECK_NONE;
1499
1500   submit_pending_requests();
1501 }
1502
1503 void Http2Session::submit_pending_requests() {
1504   for (auto dconn = dconns_.head; dconn; dconn = dconn->dlnext) {
1505     auto downstream = dconn->get_downstream();
1506
1507     if (!downstream || !downstream->request_submission_ready()) {
1508       continue;
1509     }
1510
1511     auto upstream = downstream->get_upstream();
1512
1513     if (dconn->push_request_headers() != 0) {
1514       if (LOG_ENABLED(INFO)) {
1515         SSLOG(INFO, this) << "backend request failed";
1516       }
1517
1518       upstream->on_downstream_abort_request(downstream, 400);
1519
1520       continue;
1521     }
1522
1523     upstream->resume_read(SHRPX_NO_BUFFER, downstream, 0);
1524   }
1525 }
1526
1527 void Http2Session::set_connection_check_state(int state) {
1528   connection_check_state_ = state;
1529 }
1530
1531 int Http2Session::get_connection_check_state() const {
1532   return connection_check_state_;
1533 }
1534
1535 int Http2Session::noop() { return 0; }
1536
1537 int Http2Session::connected() {
1538   if (!util::check_socket_connected(conn_.fd)) {
1539     return -1;
1540   }
1541
1542   connect_blocker_->on_success();
1543
1544   if (LOG_ENABLED(INFO)) {
1545     SSLOG(INFO, this) << "Connection established";
1546   }
1547
1548   conn_.rlimit.startw();
1549
1550   if (conn_.tls.ssl) {
1551     read_ = &Http2Session::tls_handshake;
1552     write_ = &Http2Session::tls_handshake;
1553
1554     return do_write();
1555   }
1556
1557   read_ = &Http2Session::read_clear;
1558   write_ = &Http2Session::write_clear;
1559
1560   if (state_ == PROXY_CONNECTING) {
1561     return do_write();
1562   }
1563
1564   if (connection_made() != 0) {
1565     state_ = CONNECT_FAILING;
1566     return -1;
1567   }
1568
1569   return 0;
1570 }
1571
1572 int Http2Session::read_clear() {
1573   ev_timer_again(conn_.loop, &conn_.rt);
1574
1575   for (;;) {
1576     // we should process buffered data first before we read EOF.
1577     if (rb_.rleft() && on_read() != 0) {
1578       return -1;
1579     }
1580     if (rb_.rleft()) {
1581       return 0;
1582     }
1583     rb_.reset();
1584
1585     auto nread = conn_.read_clear(rb_.last, rb_.wleft());
1586
1587     if (nread == 0) {
1588       return 0;
1589     }
1590
1591     if (nread < 0) {
1592       return nread;
1593     }
1594
1595     rb_.write(nread);
1596   }
1597 }
1598
1599 int Http2Session::write_clear() {
1600   ev_timer_again(conn_.loop, &conn_.rt);
1601
1602   for (;;) {
1603     if (wb_.rleft() > 0) {
1604       auto nwrite = conn_.write_clear(wb_.pos, wb_.rleft());
1605
1606       if (nwrite == 0) {
1607         return 0;
1608       }
1609
1610       if (nwrite < 0) {
1611         return nwrite;
1612       }
1613
1614       wb_.drain(nwrite);
1615       continue;
1616     }
1617
1618     wb_.reset();
1619     if (on_write() != 0) {
1620       return -1;
1621     }
1622     if (wb_.rleft() == 0) {
1623       break;
1624     }
1625   }
1626
1627   conn_.wlimit.stopw();
1628   ev_timer_stop(conn_.loop, &conn_.wt);
1629
1630   return 0;
1631 }
1632
1633 int Http2Session::tls_handshake() {
1634   ev_timer_again(conn_.loop, &conn_.rt);
1635
1636   ERR_clear_error();
1637
1638   auto rv = conn_.tls_handshake();
1639
1640   if (rv == SHRPX_ERR_INPROGRESS) {
1641     return 0;
1642   }
1643
1644   if (rv < 0) {
1645     return rv;
1646   }
1647
1648   if (LOG_ENABLED(INFO)) {
1649     SSLOG(INFO, this) << "SSL/TLS handshake completed";
1650   }
1651
1652   if (!get_config()->downstream_no_tls && !get_config()->insecure &&
1653       check_cert() != 0) {
1654     return -1;
1655   }
1656
1657   read_ = &Http2Session::read_tls;
1658   write_ = &Http2Session::write_tls;
1659
1660   if (connection_made() != 0) {
1661     state_ = CONNECT_FAILING;
1662     return -1;
1663   }
1664
1665   return 0;
1666 }
1667
1668 int Http2Session::read_tls() {
1669   ev_timer_again(conn_.loop, &conn_.rt);
1670
1671   ERR_clear_error();
1672
1673   for (;;) {
1674     // we should process buffered data first before we read EOF.
1675     if (rb_.rleft() && on_read() != 0) {
1676       return -1;
1677     }
1678     if (rb_.rleft()) {
1679       return 0;
1680     }
1681     rb_.reset();
1682
1683     auto nread = conn_.read_tls(rb_.last, rb_.wleft());
1684
1685     if (nread == 0) {
1686       return 0;
1687     }
1688
1689     if (nread < 0) {
1690       return nread;
1691     }
1692
1693     rb_.write(nread);
1694   }
1695 }
1696
1697 int Http2Session::write_tls() {
1698   ev_timer_again(conn_.loop, &conn_.rt);
1699
1700   ERR_clear_error();
1701
1702   for (;;) {
1703     if (wb_.rleft() > 0) {
1704       auto nwrite = conn_.write_tls(wb_.pos, wb_.rleft());
1705
1706       if (nwrite == 0) {
1707         return 0;
1708       }
1709
1710       if (nwrite < 0) {
1711         return nwrite;
1712       }
1713
1714       wb_.drain(nwrite);
1715
1716       continue;
1717     }
1718     wb_.reset();
1719     if (on_write() != 0) {
1720       return -1;
1721     }
1722     if (wb_.rleft() == 0) {
1723       break;
1724     }
1725   }
1726
1727   conn_.wlimit.stopw();
1728   ev_timer_stop(conn_.loop, &conn_.wt);
1729
1730   return 0;
1731 }
1732
1733 bool Http2Session::should_hard_fail() const {
1734   switch (state_) {
1735   case PROXY_CONNECTING:
1736   case PROXY_FAILED:
1737   case CONNECTING:
1738   case CONNECT_FAILING:
1739     return true;
1740   default:
1741     return false;
1742   }
1743 }
1744
1745 size_t Http2Session::get_addr_idx() const { return addr_idx_; }
1746
1747 } // namespace shrpx