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