Imported Upstream version 1.0.0
[platform/upstream/nghttp2.git] / src / shrpx_http2_upstream.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_upstream.h"
26
27 #include <netinet/tcp.h>
28 #include <assert.h>
29 #include <cerrno>
30 #include <sstream>
31
32 #include "shrpx_client_handler.h"
33 #include "shrpx_https_upstream.h"
34 #include "shrpx_downstream.h"
35 #include "shrpx_downstream_connection.h"
36 #include "shrpx_config.h"
37 #include "shrpx_http.h"
38 #include "shrpx_worker.h"
39 #include "http2.h"
40 #include "util.h"
41 #include "base64.h"
42 #include "app_helper.h"
43 #include "template.h"
44
45 using namespace nghttp2;
46
47 namespace shrpx {
48
49 namespace {
50 int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
51                              uint32_t error_code, void *user_data) {
52   auto upstream = static_cast<Http2Upstream *>(user_data);
53   if (LOG_ENABLED(INFO)) {
54     ULOG(INFO, upstream) << "Stream stream_id=" << stream_id
55                          << " is being closed";
56   }
57
58   auto downstream = static_cast<Downstream *>(
59       nghttp2_session_get_stream_user_data(session, stream_id));
60
61   if (!downstream) {
62     return 0;
63   }
64
65   upstream->consume(stream_id, downstream->get_request_datalen());
66
67   downstream->reset_request_datalen();
68
69   if (downstream->get_request_state() == Downstream::CONNECT_FAIL) {
70     upstream->remove_downstream(downstream);
71     // downstream was deleted
72
73     return 0;
74   }
75
76   downstream->set_request_state(Downstream::STREAM_CLOSED);
77
78   if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
79     // At this point, downstream response was read
80     if (!downstream->get_upgraded() &&
81         !downstream->get_response_connection_close()) {
82       // Keep-alive
83       downstream->detach_downstream_connection();
84     }
85
86     upstream->remove_downstream(downstream);
87     // downstream was deleted
88
89     return 0;
90   }
91
92   // At this point, downstream read may be paused.
93
94   // If shrpx_downstream::push_request_headers() failed, the
95   // error is handled here.
96   upstream->remove_downstream(downstream);
97   // downstream was deleted
98
99   // How to test this case? Request sufficient large download
100   // and make client send RST_STREAM after it gets first DATA
101   // frame chunk.
102
103   return 0;
104 }
105 } // namespace
106
107 int Http2Upstream::upgrade_upstream(HttpsUpstream *http) {
108   int rv;
109
110   // to deduce :scheme and :authority, first we have to parse request
111   // URI.
112   http_parser_url u = {};
113   auto &url = http->get_downstream()->get_request_path();
114
115   std::string scheme, authority;
116   rv = http_parser_parse_url(url.c_str(), url.size(), 0, &u);
117   if (rv == 0) {
118     http2::copy_url_component(scheme, &u, UF_SCHEMA, url.c_str());
119     http2::copy_url_component(authority, &u, UF_HOST, url.c_str());
120   }
121   if (scheme.empty()) {
122     if (handler_->get_ssl()) {
123       scheme = "https";
124     } else {
125       scheme = "http";
126     }
127   }
128   if (!authority.empty()) {
129     if (authority.find(":") != std::string::npos) {
130       authority = "[" + authority;
131       authority += "]";
132     }
133     if (u.field_set & (1 << UF_PORT)) {
134       authority += ":";
135       authority += util::utos(u.port);
136     }
137   }
138
139   auto http2_settings = http->get_downstream()->get_http2_settings();
140   util::to_base64(http2_settings);
141
142   auto settings_payload =
143       base64::decode(std::begin(http2_settings), std::end(http2_settings));
144
145   rv = nghttp2_session_upgrade(
146       session_, reinterpret_cast<const uint8_t *>(settings_payload.c_str()),
147       settings_payload.size(), nullptr);
148   if (rv != 0) {
149     if (LOG_ENABLED(INFO)) {
150       ULOG(INFO, this) << "nghttp2_session_upgrade() returned error: "
151                        << nghttp2_strerror(rv);
152     }
153     return -1;
154   }
155   pre_upstream_.reset(http);
156   auto downstream = http->pop_downstream();
157   downstream->reset_upstream(this);
158   downstream->set_stream_id(1);
159   downstream->reset_upstream_rtimer();
160   downstream->set_stream_id(1);
161   downstream->set_priority(0);
162   downstream->set_request_http2_authority(authority);
163   downstream->set_request_http2_scheme(scheme);
164
165   auto ptr = downstream.get();
166
167   nghttp2_session_set_stream_user_data(session_, 1, ptr);
168   downstream_queue_.add_pending(std::move(downstream));
169   downstream_queue_.mark_active(ptr);
170
171   if (LOG_ENABLED(INFO)) {
172     ULOG(INFO, this) << "Connection upgraded to HTTP/2";
173   }
174
175   return 0;
176 }
177
178 void Http2Upstream::start_settings_timer() {
179   ev_timer_start(handler_->get_loop(), &settings_timer_);
180 }
181
182 void Http2Upstream::stop_settings_timer() {
183   ev_timer_stop(handler_->get_loop(), &settings_timer_);
184 }
185
186 namespace {
187 int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
188                        const uint8_t *name, size_t namelen,
189                        const uint8_t *value, size_t valuelen, uint8_t flags,
190                        void *user_data) {
191   if (get_config()->upstream_frame_debug) {
192     verbose_on_header_callback(session, frame, name, namelen, value, valuelen,
193                                flags, user_data);
194   }
195   if (frame->hd.type != NGHTTP2_HEADERS) {
196     return 0;
197   }
198   auto upstream = static_cast<Http2Upstream *>(user_data);
199   auto downstream = static_cast<Downstream *>(
200       nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
201   if (!downstream) {
202     return 0;
203   }
204
205   if (downstream->get_request_headers_sum() + namelen + valuelen >
206           get_config()->header_field_buffer ||
207       downstream->get_request_headers().size() >=
208           get_config()->max_header_fields) {
209     if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
210       return 0;
211     }
212
213     if (LOG_ENABLED(INFO)) {
214       ULOG(INFO, upstream) << "Too large or many header field size="
215                            << downstream->get_request_headers_sum() + namelen +
216                                   valuelen << ", num="
217                            << downstream->get_request_headers().size() + 1;
218     }
219
220     // just ignore header fields if this is trailer part.
221     if (frame->headers.cat == NGHTTP2_HCAT_HEADERS) {
222       return 0;
223     }
224
225     if (upstream->error_reply(downstream, 431) != 0) {
226       return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
227     }
228
229     return 0;
230   }
231
232   if (frame->headers.cat == NGHTTP2_HCAT_HEADERS) {
233     // just store header fields for trailer part
234     downstream->add_request_trailer(name, namelen, value, valuelen,
235                                     flags & NGHTTP2_NV_FLAG_NO_INDEX, -1);
236     return 0;
237   }
238
239   auto token = http2::lookup_token(name, namelen);
240
241   downstream->add_request_header(name, namelen, value, valuelen,
242                                  flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
243   return 0;
244 }
245 } // namespace
246
247 namespace {
248 int on_begin_headers_callback(nghttp2_session *session,
249                               const nghttp2_frame *frame, void *user_data) {
250   auto upstream = static_cast<Http2Upstream *>(user_data);
251
252   if (frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
253     return 0;
254   }
255   if (LOG_ENABLED(INFO)) {
256     ULOG(INFO, upstream) << "Received upstream request HEADERS stream_id="
257                          << frame->hd.stream_id;
258   }
259
260   auto handler = upstream->get_client_handler();
261
262   // TODO Use priority 0 for now
263   auto downstream = make_unique<Downstream>(upstream, handler->get_mcpool(),
264                                             frame->hd.stream_id, 0);
265   nghttp2_session_set_stream_user_data(session, frame->hd.stream_id,
266                                        downstream.get());
267
268   downstream->reset_upstream_rtimer();
269
270   // Although, we deprecated minor version from HTTP/2, we supply
271   // minor version 0 to use via header field in a conventional way.
272   downstream->set_request_major(2);
273   downstream->set_request_minor(0);
274
275   upstream->add_pending_downstream(std::move(downstream));
276
277   return 0;
278 }
279 } // namespace
280
281 int Http2Upstream::on_request_headers(Downstream *downstream,
282                                       const nghttp2_frame *frame) {
283   if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
284     return 0;
285   }
286
287   auto &nva = downstream->get_request_headers();
288
289   if (LOG_ENABLED(INFO)) {
290     std::stringstream ss;
291     for (auto &nv : nva) {
292       ss << TTY_HTTP_HD << nv.name << TTY_RST << ": " << nv.value << "\n";
293     }
294     ULOG(INFO, this) << "HTTP request headers. stream_id="
295                      << downstream->get_stream_id() << "\n" << ss.str();
296   }
297
298   if (get_config()->http2_upstream_dump_request_header) {
299     http2::dump_nv(get_config()->http2_upstream_dump_request_header, nva);
300   }
301
302   auto content_length =
303       downstream->get_request_header(http2::HD_CONTENT_LENGTH);
304   if (content_length) {
305     // libnghttp2 guarantees this can be parsed
306     auto len = util::parse_uint(content_length->value);
307     downstream->set_request_content_length(len);
308   }
309
310   auto authority = downstream->get_request_header(http2::HD__AUTHORITY);
311   auto path = downstream->get_request_header(http2::HD__PATH);
312   auto method = downstream->get_request_header(http2::HD__METHOD);
313   auto scheme = downstream->get_request_header(http2::HD__SCHEME);
314
315   // presence of mandatory header fields are guaranteed by libnghttp2.
316
317   // For HTTP/2 proxy, we request :authority.
318   if (method->value != "CONNECT" && get_config()->http2_proxy && !authority) {
319     rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR);
320     return 0;
321   }
322
323   downstream->set_request_method(http2::value_to_str(method));
324   downstream->set_request_http2_scheme(http2::value_to_str(scheme));
325   downstream->set_request_http2_authority(http2::value_to_str(authority));
326   downstream->set_request_path(http2::value_to_str(path));
327
328   if (!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
329     downstream->set_request_http2_expect_body(true);
330   }
331
332   downstream->inspect_http2_request();
333
334   downstream->set_request_state(Downstream::HEADER_COMPLETE);
335   if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
336     downstream->disable_upstream_rtimer();
337
338     downstream->set_request_state(Downstream::MSG_COMPLETE);
339   }
340
341   start_downstream(downstream);
342
343   return 0;
344 }
345
346 void Http2Upstream::start_downstream(Downstream *downstream) {
347   if (downstream_queue_.can_activate(
348           downstream->get_request_http2_authority())) {
349     initiate_downstream(downstream);
350     return;
351   }
352
353   downstream_queue_.mark_blocked(downstream);
354 }
355
356 void Http2Upstream::initiate_downstream(Downstream *downstream) {
357   int rv;
358
359   rv = downstream->attach_downstream_connection(
360       handler_->get_downstream_connection());
361   if (rv != 0) {
362     // downstream connection fails, send error page
363     if (error_reply(downstream, 503) != 0) {
364       rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
365     }
366
367     downstream->set_request_state(Downstream::CONNECT_FAIL);
368
369     downstream_queue_.mark_failure(downstream);
370
371     return;
372   }
373   rv = downstream->push_request_headers();
374   if (rv != 0) {
375
376     if (error_reply(downstream, 503) != 0) {
377       rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
378     }
379
380     downstream_queue_.mark_failure(downstream);
381
382     return;
383   }
384
385   downstream_queue_.mark_active(downstream);
386
387   return;
388 }
389
390 namespace {
391 int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame,
392                            void *user_data) {
393   if (get_config()->upstream_frame_debug) {
394     verbose_on_frame_recv_callback(session, frame, user_data);
395   }
396   auto upstream = static_cast<Http2Upstream *>(user_data);
397
398   switch (frame->hd.type) {
399   case NGHTTP2_DATA: {
400     auto downstream = static_cast<Downstream *>(
401         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
402     if (!downstream) {
403       return 0;
404     }
405
406     if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
407       downstream->disable_upstream_rtimer();
408
409       downstream->end_upload_data();
410       downstream->set_request_state(Downstream::MSG_COMPLETE);
411     }
412
413     return 0;
414   }
415   case NGHTTP2_HEADERS: {
416     auto downstream = static_cast<Downstream *>(
417         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
418     if (!downstream) {
419       return 0;
420     }
421
422     if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
423       downstream->reset_upstream_rtimer();
424
425       return upstream->on_request_headers(downstream, frame);
426     }
427
428     if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
429       downstream->disable_upstream_rtimer();
430
431       downstream->end_upload_data();
432       downstream->set_request_state(Downstream::MSG_COMPLETE);
433     }
434
435     return 0;
436   }
437   case NGHTTP2_SETTINGS:
438     if ((frame->hd.flags & NGHTTP2_FLAG_ACK) == 0) {
439       return 0;
440     }
441     upstream->stop_settings_timer();
442     return 0;
443   case NGHTTP2_GOAWAY:
444     if (LOG_ENABLED(INFO)) {
445       auto debug_data = util::ascii_dump(frame->goaway.opaque_data,
446                                          frame->goaway.opaque_data_len);
447
448       ULOG(INFO, upstream) << "GOAWAY received: last-stream-id="
449                            << frame->goaway.last_stream_id
450                            << ", error_code=" << frame->goaway.error_code
451                            << ", debug_data=" << debug_data;
452     }
453     return 0;
454   default:
455     return 0;
456   }
457 }
458 } // namespace
459
460 namespace {
461 int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
462                                 int32_t stream_id, const uint8_t *data,
463                                 size_t len, void *user_data) {
464   auto upstream = static_cast<Http2Upstream *>(user_data);
465   auto downstream = static_cast<Downstream *>(
466       nghttp2_session_get_stream_user_data(session, stream_id));
467
468   if (!downstream || !downstream->get_downstream_connection()) {
469     if (upstream->consume(stream_id, len) != 0) {
470       return NGHTTP2_ERR_CALLBACK_FAILURE;
471     }
472
473     return 0;
474   }
475
476   downstream->reset_upstream_rtimer();
477
478   if (downstream->push_upload_data_chunk(data, len) != 0) {
479     upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
480
481     if (upstream->consume(stream_id, len) != 0) {
482       return NGHTTP2_ERR_CALLBACK_FAILURE;
483     }
484
485     return 0;
486   }
487
488   return 0;
489 }
490 } // namespace
491
492 namespace {
493 int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
494                            void *user_data) {
495   if (get_config()->upstream_frame_debug) {
496     verbose_on_frame_send_callback(session, frame, user_data);
497   }
498   auto upstream = static_cast<Http2Upstream *>(user_data);
499   auto handler = upstream->get_client_handler();
500
501   switch (frame->hd.type) {
502   case NGHTTP2_DATA:
503   case NGHTTP2_HEADERS: {
504     if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
505       return 0;
506     }
507     // RST_STREAM if request is still incomplete.
508     auto stream_id = frame->hd.stream_id;
509     auto downstream = static_cast<Downstream *>(
510         nghttp2_session_get_stream_user_data(session, stream_id));
511
512     if (!downstream) {
513       return 0;
514     }
515
516     // For tunneling, issue RST_STREAM to finish the stream.
517     if (downstream->get_upgraded() ||
518         nghttp2_session_get_stream_remote_close(session, stream_id) == 0) {
519       if (LOG_ENABLED(INFO)) {
520         ULOG(INFO, upstream)
521             << "Send RST_STREAM to "
522             << (downstream->get_upgraded() ? "tunneled " : "")
523             << "stream stream_id=" << downstream->get_stream_id()
524             << " to finish off incomplete request";
525       }
526
527       upstream->rst_stream(downstream, NGHTTP2_NO_ERROR);
528     }
529
530     return 0;
531   }
532   case NGHTTP2_SETTINGS:
533     if ((frame->hd.flags & NGHTTP2_FLAG_ACK) == 0) {
534       upstream->start_settings_timer();
535     }
536     return 0;
537   case NGHTTP2_PUSH_PROMISE: {
538     auto promised_stream_id = frame->push_promise.promised_stream_id;
539     auto downstream = make_unique<Downstream>(upstream, handler->get_mcpool(),
540                                               promised_stream_id, 0);
541
542     nghttp2_session_set_stream_user_data(session, promised_stream_id,
543                                          downstream.get());
544
545     downstream->disable_upstream_rtimer();
546
547     downstream->set_request_major(2);
548     downstream->set_request_minor(0);
549
550     for (size_t i = 0; i < frame->push_promise.nvlen; ++i) {
551       auto &nv = frame->push_promise.nva[i];
552       auto token = http2::lookup_token(nv.name, nv.namelen);
553       switch (token) {
554       case http2::HD__METHOD:
555         downstream->set_request_method({nv.value, nv.value + nv.valuelen});
556         break;
557       case http2::HD__SCHEME:
558         downstream->set_request_http2_scheme(
559             {nv.value, nv.value + nv.valuelen});
560         break;
561       case http2::HD__AUTHORITY:
562         downstream->set_request_http2_authority(
563             {nv.value, nv.value + nv.valuelen});
564         break;
565       case http2::HD__PATH:
566         downstream->set_request_path({nv.value, nv.value + nv.valuelen});
567         break;
568       }
569       downstream->add_request_header(nv.name, nv.namelen, nv.value, nv.valuelen,
570                                      nv.flags & NGHTTP2_NV_FLAG_NO_INDEX,
571                                      token);
572     }
573
574     downstream->inspect_http2_request();
575
576     downstream->set_request_state(Downstream::MSG_COMPLETE);
577
578     // a bit weird but start_downstream() expects that given
579     // downstream is in pending queue.
580     auto ptr = downstream.get();
581     upstream->add_pending_downstream(std::move(downstream));
582     upstream->start_downstream(ptr);
583
584     return 0;
585   }
586   case NGHTTP2_GOAWAY:
587     if (LOG_ENABLED(INFO)) {
588       auto debug_data = util::ascii_dump(frame->goaway.opaque_data,
589                                          frame->goaway.opaque_data_len);
590
591       ULOG(INFO, upstream) << "Sending GOAWAY: last-stream-id="
592                            << frame->goaway.last_stream_id
593                            << ", error_code=" << frame->goaway.error_code
594                            << ", debug_data=" << debug_data;
595     }
596     return 0;
597   default:
598     return 0;
599   }
600 }
601 } // namespace
602
603 namespace {
604 int on_frame_not_send_callback(nghttp2_session *session,
605                                const nghttp2_frame *frame, int lib_error_code,
606                                void *user_data) {
607   auto upstream = static_cast<Http2Upstream *>(user_data);
608   if (LOG_ENABLED(INFO)) {
609     ULOG(INFO, upstream) << "Failed to send control frame type="
610                          << static_cast<uint32_t>(frame->hd.type)
611                          << ", lib_error_code=" << lib_error_code << ":"
612                          << nghttp2_strerror(lib_error_code);
613   }
614   if (frame->hd.type == NGHTTP2_HEADERS &&
615       lib_error_code != NGHTTP2_ERR_STREAM_CLOSED &&
616       lib_error_code != NGHTTP2_ERR_STREAM_CLOSING) {
617     // To avoid stream hanging around, issue RST_STREAM.
618     auto downstream = static_cast<Downstream *>(
619         nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
620     if (downstream) {
621       upstream->rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
622     }
623   }
624   return 0;
625 }
626 } // namespace
627
628 namespace {
629 uint32_t infer_upstream_rst_stream_error_code(uint32_t downstream_error_code) {
630   // NGHTTP2_REFUSED_STREAM is important because it tells upstream
631   // client to retry.
632   switch (downstream_error_code) {
633   case NGHTTP2_NO_ERROR:
634   case NGHTTP2_REFUSED_STREAM:
635     return downstream_error_code;
636   default:
637     return NGHTTP2_INTERNAL_ERROR;
638   }
639 }
640 } // namespace
641
642 namespace {
643 void settings_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
644   auto upstream = static_cast<Http2Upstream *>(w->data);
645   auto handler = upstream->get_client_handler();
646   ULOG(INFO, upstream) << "SETTINGS timeout";
647   if (upstream->terminate_session(NGHTTP2_SETTINGS_TIMEOUT) != 0) {
648     delete handler;
649     return;
650   }
651   handler->signal_write();
652 }
653 } // namespace
654
655 namespace {
656 void shutdown_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
657   auto upstream = static_cast<Http2Upstream *>(w->data);
658   auto handler = upstream->get_client_handler();
659   upstream->submit_goaway();
660   handler->signal_write();
661 }
662 } // namespace
663
664 namespace {
665 void prepare_cb(struct ev_loop *loop, ev_prepare *w, int revents) {
666   auto upstream = static_cast<Http2Upstream *>(w->data);
667   upstream->check_shutdown();
668 }
669 } // namespace
670
671 void Http2Upstream::submit_goaway() {
672   auto last_stream_id = nghttp2_session_get_last_proc_stream_id(session_);
673   nghttp2_submit_goaway(session_, NGHTTP2_FLAG_NONE, last_stream_id,
674                         NGHTTP2_NO_ERROR, nullptr, 0);
675 }
676
677 void Http2Upstream::check_shutdown() {
678   int rv;
679   if (shutdown_handled_) {
680     return;
681   }
682
683   auto worker = handler_->get_worker();
684
685   if (worker->get_graceful_shutdown()) {
686     shutdown_handled_ = true;
687     rv = nghttp2_submit_shutdown_notice(session_);
688     if (rv != 0) {
689       ULOG(FATAL, this) << "nghttp2_submit_shutdown_notice() failed: "
690                         << nghttp2_strerror(rv);
691       return;
692     }
693     handler_->signal_write();
694     ev_timer_start(handler_->get_loop(), &shutdown_timer_);
695   }
696 }
697
698 nghttp2_session_callbacks *create_http2_upstream_callbacks() {
699   int rv;
700   nghttp2_session_callbacks *callbacks;
701
702   rv = nghttp2_session_callbacks_new(&callbacks);
703
704   if (rv != 0) {
705     return nullptr;
706   }
707
708   nghttp2_session_callbacks_set_on_stream_close_callback(
709       callbacks, on_stream_close_callback);
710
711   nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
712                                                        on_frame_recv_callback);
713
714   nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
715       callbacks, on_data_chunk_recv_callback);
716
717   nghttp2_session_callbacks_set_on_frame_send_callback(callbacks,
718                                                        on_frame_send_callback);
719
720   nghttp2_session_callbacks_set_on_frame_not_send_callback(
721       callbacks, on_frame_not_send_callback);
722
723   nghttp2_session_callbacks_set_on_header_callback(callbacks,
724                                                    on_header_callback);
725
726   nghttp2_session_callbacks_set_on_begin_headers_callback(
727       callbacks, on_begin_headers_callback);
728
729   if (get_config()->padding) {
730     nghttp2_session_callbacks_set_select_padding_callback(
731         callbacks, http::select_padding_callback);
732   }
733
734   return callbacks;
735 }
736
737 Http2Upstream::Http2Upstream(ClientHandler *handler)
738     : downstream_queue_(
739           get_config()->http2_proxy
740               ? get_config()->downstream_connections_per_host
741               : get_config()->downstream_proto == PROTO_HTTP
742                     ? get_config()->downstream_connections_per_frontend
743                     : 0,
744           !get_config()->http2_proxy),
745       handler_(handler), session_(nullptr), data_pending_(nullptr),
746       data_pendinglen_(0), shutdown_handled_(false) {
747
748   int rv;
749
750   rv = nghttp2_session_server_new2(&session_,
751                                    get_config()->http2_upstream_callbacks, this,
752                                    get_config()->http2_option);
753
754   assert(rv == 0);
755
756   flow_control_ = true;
757
758   // TODO Maybe call from outside?
759   std::array<nghttp2_settings_entry, 2> entry;
760   entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
761   entry[0].value = get_config()->http2_max_concurrent_streams;
762
763   entry[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
764   entry[1].value = (1 << get_config()->http2_upstream_window_bits) - 1;
765
766   rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(),
767                                entry.size());
768   if (rv != 0) {
769     ULOG(ERROR, this) << "nghttp2_submit_settings() returned error: "
770                       << nghttp2_strerror(rv);
771   }
772
773   if (get_config()->http2_upstream_connection_window_bits > 16) {
774     int32_t delta = (1 << get_config()->http2_upstream_connection_window_bits) -
775                     1 - NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
776     rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0, delta);
777
778     if (rv != 0) {
779       ULOG(ERROR, this) << "nghttp2_submit_window_update() returned error: "
780                         << nghttp2_strerror(rv);
781     }
782   }
783
784   // We wait for SETTINGS ACK at least 10 seconds.
785   ev_timer_init(&settings_timer_, settings_timeout_cb, 10., 0.);
786
787   settings_timer_.data = this;
788
789   // timer for 2nd GOAWAY.  HTTP/2 spec recommend 1 RTT.  We wait for
790   // 2 seconds.
791   ev_timer_init(&shutdown_timer_, shutdown_timeout_cb, 2., 0);
792   shutdown_timer_.data = this;
793
794   ev_prepare_init(&prep_, prepare_cb);
795   prep_.data = this;
796   ev_prepare_start(handler_->get_loop(), &prep_);
797
798   handler_->reset_upstream_read_timeout(
799       get_config()->http2_upstream_read_timeout);
800
801   handler_->signal_write();
802 }
803
804 Http2Upstream::~Http2Upstream() {
805   nghttp2_session_del(session_);
806   ev_prepare_stop(handler_->get_loop(), &prep_);
807   ev_timer_stop(handler_->get_loop(), &shutdown_timer_);
808   ev_timer_stop(handler_->get_loop(), &settings_timer_);
809 }
810
811 int Http2Upstream::on_read() {
812   ssize_t rv = 0;
813   auto rb = handler_->get_rb();
814   auto rlimit = handler_->get_rlimit();
815
816   if (rb->rleft()) {
817     rv = nghttp2_session_mem_recv(session_, rb->pos, rb->rleft());
818     if (rv < 0) {
819       if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
820         ULOG(ERROR, this) << "nghttp2_session_recv() returned error: "
821                           << nghttp2_strerror(rv);
822       }
823       return -1;
824     }
825
826     // nghttp2_session_mem_recv should consume all input bytes on
827     // success.
828     assert(static_cast<size_t>(rv) == rb->rleft());
829     rb->reset();
830     rlimit->startw();
831   }
832
833   auto wb = handler_->get_wb();
834   if (nghttp2_session_want_read(session_) == 0 &&
835       nghttp2_session_want_write(session_) == 0 && wb->rleft() == 0) {
836     if (LOG_ENABLED(INFO)) {
837       ULOG(INFO, this) << "No more read/write for this HTTP2 session";
838     }
839     return -1;
840   }
841
842   handler_->signal_write();
843   return 0;
844 }
845
846 // After this function call, downstream may be deleted.
847 int Http2Upstream::on_write() {
848   auto wb = handler_->get_wb();
849
850   if (data_pending_) {
851     auto n = std::min(wb->wleft(), data_pendinglen_);
852     wb->write(data_pending_, n);
853     if (n < data_pendinglen_) {
854       data_pending_ += n;
855       data_pendinglen_ -= n;
856       return 0;
857     }
858
859     data_pending_ = nullptr;
860     data_pendinglen_ = 0;
861   }
862
863   for (;;) {
864     const uint8_t *data;
865     auto datalen = nghttp2_session_mem_send(session_, &data);
866
867     if (datalen < 0) {
868       ULOG(ERROR, this) << "nghttp2_session_mem_send() returned error: "
869                         << nghttp2_strerror(datalen);
870       return -1;
871     }
872     if (datalen == 0) {
873       break;
874     }
875     auto n = wb->write(data, datalen);
876     if (n < static_cast<decltype(n)>(datalen)) {
877       data_pending_ = data + n;
878       data_pendinglen_ = datalen - n;
879       return 0;
880     }
881   }
882
883   if (nghttp2_session_want_read(session_) == 0 &&
884       nghttp2_session_want_write(session_) == 0 && wb->rleft() == 0) {
885     if (LOG_ENABLED(INFO)) {
886       ULOG(INFO, this) << "No more read/write for this HTTP2 session";
887     }
888     return -1;
889   }
890
891   return 0;
892 }
893
894 ClientHandler *Http2Upstream::get_client_handler() const { return handler_; }
895
896 int Http2Upstream::downstream_read(DownstreamConnection *dconn) {
897   auto downstream = dconn->get_downstream();
898
899   if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
900     // If upstream HTTP2 stream was closed, we just close downstream,
901     // because there is no consumer now. Downstream connection is also
902     // closed in this case.
903     remove_downstream(downstream);
904     // downstream was deleted
905
906     return 0;
907   }
908
909   if (downstream->get_response_state() == Downstream::MSG_RESET) {
910     // The downstream stream was reset (canceled). In this case,
911     // RST_STREAM to the upstream and delete downstream connection
912     // here. Deleting downstream will be taken place at
913     // on_stream_close_callback.
914     rst_stream(downstream,
915                infer_upstream_rst_stream_error_code(
916                    downstream->get_response_rst_stream_error_code()));
917     downstream->pop_downstream_connection();
918     // dconn was deleted
919     dconn = nullptr;
920   } else if (downstream->get_response_state() == Downstream::MSG_BAD_HEADER) {
921     if (error_reply(downstream, 502) != 0) {
922       return -1;
923     }
924     downstream->pop_downstream_connection();
925     // dconn was deleted
926     dconn = nullptr;
927   } else {
928     auto rv = downstream->on_read();
929     if (rv == SHRPX_ERR_EOF) {
930       return downstream_eof(dconn);
931     }
932     if (rv != 0) {
933       if (rv != SHRPX_ERR_NETWORK) {
934         if (LOG_ENABLED(INFO)) {
935           DCLOG(INFO, dconn) << "HTTP parser failure";
936         }
937       }
938       return downstream_error(dconn, Downstream::EVENT_ERROR);
939     }
940     // Detach downstream connection early so that it could be reused
941     // without hitting server's request timeout.
942     if (downstream->get_response_state() == Downstream::MSG_COMPLETE &&
943         !downstream->get_response_connection_close()) {
944       // Keep-alive
945       downstream->detach_downstream_connection();
946     }
947   }
948
949   handler_->signal_write();
950
951   // At this point, downstream may be deleted.
952
953   return 0;
954 }
955
956 int Http2Upstream::downstream_write(DownstreamConnection *dconn) {
957   int rv;
958   rv = dconn->on_write();
959   if (rv == SHRPX_ERR_NETWORK) {
960     return downstream_error(dconn, Downstream::EVENT_ERROR);
961   }
962   if (rv != 0) {
963     return -1;
964   }
965   return 0;
966 }
967
968 int Http2Upstream::downstream_eof(DownstreamConnection *dconn) {
969   auto downstream = dconn->get_downstream();
970
971   if (LOG_ENABLED(INFO)) {
972     DCLOG(INFO, dconn) << "EOF. stream_id=" << downstream->get_stream_id();
973   }
974   if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
975     // If stream was closed already, we don't need to send reply at
976     // the first place. We can delete downstream.
977     remove_downstream(downstream);
978     // downstream was deleted
979
980     return 0;
981   }
982
983   // Delete downstream connection. If we don't delete it here, it will
984   // be pooled in on_stream_close_callback.
985   downstream->pop_downstream_connection();
986   // dconn was deleted
987   dconn = nullptr;
988   // downstream wil be deleted in on_stream_close_callback.
989   if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
990     // Server may indicate the end of the request by EOF
991     if (LOG_ENABLED(INFO)) {
992       ULOG(INFO, this) << "Downstream body was ended by EOF";
993     }
994     downstream->set_response_state(Downstream::MSG_COMPLETE);
995
996     // For tunneled connection, MSG_COMPLETE signals
997     // downstream_data_read_callback to send RST_STREAM after pending
998     // response body is sent. This is needed to ensure that RST_STREAM
999     // is sent after all pending data are sent.
1000     on_downstream_body_complete(downstream);
1001   } else if (downstream->get_response_state() != Downstream::MSG_COMPLETE) {
1002     // If stream was not closed, then we set MSG_COMPLETE and let
1003     // on_stream_close_callback delete downstream.
1004     if (error_reply(downstream, 502) != 0) {
1005       return -1;
1006     }
1007   }
1008   handler_->signal_write();
1009   // At this point, downstream may be deleted.
1010   return 0;
1011 }
1012
1013 int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) {
1014   auto downstream = dconn->get_downstream();
1015
1016   if (LOG_ENABLED(INFO)) {
1017     if (events & Downstream::EVENT_ERROR) {
1018       DCLOG(INFO, dconn) << "Downstream network/general error";
1019     } else {
1020       DCLOG(INFO, dconn) << "Timeout";
1021     }
1022     if (downstream->get_upgraded()) {
1023       DCLOG(INFO, dconn) << "Note: this is tunnel connection";
1024     }
1025   }
1026
1027   if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
1028     remove_downstream(downstream);
1029     // downstream was deleted
1030
1031     return 0;
1032   }
1033
1034   // Delete downstream connection. If we don't delete it here, it will
1035   // be pooled in on_stream_close_callback.
1036   downstream->pop_downstream_connection();
1037   // dconn was deleted
1038   dconn = nullptr;
1039
1040   if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
1041     // For SSL tunneling, we issue RST_STREAM. For other types of
1042     // stream, we don't have to do anything since response was
1043     // complete.
1044     if (downstream->get_upgraded()) {
1045       rst_stream(downstream, NGHTTP2_NO_ERROR);
1046     }
1047   } else {
1048     if (downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
1049       if (downstream->get_upgraded()) {
1050         on_downstream_body_complete(downstream);
1051       } else {
1052         rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
1053       }
1054     } else {
1055       unsigned int status;
1056       if (events & Downstream::EVENT_TIMEOUT) {
1057         status = 504;
1058       } else {
1059         status = 502;
1060       }
1061       if (error_reply(downstream, status) != 0) {
1062         return -1;
1063       }
1064     }
1065     downstream->set_response_state(Downstream::MSG_COMPLETE);
1066   }
1067   handler_->signal_write();
1068   // At this point, downstream may be deleted.
1069   return 0;
1070 }
1071
1072 int Http2Upstream::rst_stream(Downstream *downstream, uint32_t error_code) {
1073   if (LOG_ENABLED(INFO)) {
1074     ULOG(INFO, this) << "RST_STREAM stream_id=" << downstream->get_stream_id()
1075                      << " with error_code=" << error_code;
1076   }
1077   int rv;
1078   rv = nghttp2_submit_rst_stream(session_, NGHTTP2_FLAG_NONE,
1079                                  downstream->get_stream_id(), error_code);
1080   if (rv < NGHTTP2_ERR_FATAL) {
1081     ULOG(FATAL, this) << "nghttp2_submit_rst_stream() failed: "
1082                       << nghttp2_strerror(rv);
1083     DIE();
1084   }
1085   return 0;
1086 }
1087
1088 int Http2Upstream::terminate_session(uint32_t error_code) {
1089   int rv;
1090   rv = nghttp2_session_terminate_session(session_, error_code);
1091   if (rv != 0) {
1092     return -1;
1093   }
1094   return 0;
1095 }
1096
1097 namespace {
1098 ssize_t downstream_data_read_callback(nghttp2_session *session,
1099                                       int32_t stream_id, uint8_t *buf,
1100                                       size_t length, uint32_t *data_flags,
1101                                       nghttp2_data_source *source,
1102                                       void *user_data) {
1103   int rv;
1104   auto downstream = static_cast<Downstream *>(source->ptr);
1105   auto upstream = static_cast<Http2Upstream *>(downstream->get_upstream());
1106   auto body = downstream->get_response_buf();
1107   assert(body);
1108
1109   auto dconn = downstream->get_downstream_connection();
1110
1111   if (body->rleft() == 0 && dconn &&
1112       downstream->get_response_state() != Downstream::MSG_COMPLETE) {
1113     // Try to read more if buffer is empty.  This will help small
1114     // buffer and make priority handling a bit better.
1115     if (upstream->downstream_read(dconn) != 0) {
1116       return NGHTTP2_ERR_CALLBACK_FAILURE;
1117     }
1118   }
1119
1120   auto nread = body->remove(buf, length);
1121   auto body_empty = body->rleft() == 0;
1122
1123   if (body_empty &&
1124       downstream->get_response_state() == Downstream::MSG_COMPLETE) {
1125
1126     *data_flags |= NGHTTP2_DATA_FLAG_EOF;
1127
1128     if (!downstream->get_upgraded()) {
1129       auto &trailers = downstream->get_response_trailers();
1130       if (!trailers.empty()) {
1131         std::vector<nghttp2_nv> nva;
1132         nva.reserve(trailers.size());
1133         http2::copy_headers_to_nva(nva, trailers);
1134         if (!nva.empty()) {
1135           rv = nghttp2_submit_trailer(session, stream_id, nva.data(),
1136                                       nva.size());
1137           if (rv != 0) {
1138             if (nghttp2_is_fatal(rv)) {
1139               return NGHTTP2_ERR_CALLBACK_FAILURE;
1140             }
1141           } else {
1142             *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
1143           }
1144         }
1145       }
1146     }
1147   }
1148
1149   if (body_empty) {
1150     downstream->disable_upstream_wtimer();
1151   } else {
1152     downstream->reset_upstream_wtimer();
1153   }
1154
1155   if (nread > 0 && downstream->resume_read(SHRPX_NO_BUFFER, nread) != 0) {
1156     return NGHTTP2_ERR_CALLBACK_FAILURE;
1157   }
1158
1159   if (nread == 0 && ((*data_flags) & NGHTTP2_DATA_FLAG_EOF) == 0) {
1160     return NGHTTP2_ERR_DEFERRED;
1161   }
1162
1163   if (nread > 0) {
1164     downstream->add_response_sent_bodylen(nread);
1165   }
1166
1167   return nread;
1168 }
1169 } // namespace
1170
1171 int Http2Upstream::error_reply(Downstream *downstream,
1172                                unsigned int status_code) {
1173   int rv;
1174   auto html = http::create_error_html(status_code);
1175   downstream->set_response_http_status(status_code);
1176   auto body = downstream->get_response_buf();
1177   body->append(html.c_str(), html.size());
1178   downstream->set_response_state(Downstream::MSG_COMPLETE);
1179
1180   nghttp2_data_provider data_prd;
1181   data_prd.source.ptr = downstream;
1182   data_prd.read_callback = downstream_data_read_callback;
1183
1184   auto content_length = util::utos(html.size());
1185   auto status_code_str = util::utos(status_code);
1186   auto nva =
1187       make_array(http2::make_nv_ls(":status", status_code_str),
1188                  http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
1189                  http2::make_nv_lc("server", get_config()->server_name),
1190                  http2::make_nv_ls("content-length", content_length));
1191
1192   rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
1193                                nva.data(), nva.size(), &data_prd);
1194   if (rv < NGHTTP2_ERR_FATAL) {
1195     ULOG(FATAL, this) << "nghttp2_submit_response() failed: "
1196                       << nghttp2_strerror(rv);
1197     return -1;
1198   }
1199
1200   return 0;
1201 }
1202
1203 void
1204 Http2Upstream::add_pending_downstream(std::unique_ptr<Downstream> downstream) {
1205   downstream_queue_.add_pending(std::move(downstream));
1206 }
1207
1208 void Http2Upstream::remove_downstream(Downstream *downstream) {
1209   if (downstream->accesslog_ready()) {
1210     handler_->write_accesslog(downstream);
1211   }
1212
1213   nghttp2_session_set_stream_user_data(session_, downstream->get_stream_id(),
1214                                        nullptr);
1215
1216   auto next_downstream = downstream_queue_.remove_and_get_blocked(downstream);
1217
1218   if (next_downstream) {
1219     initiate_downstream(next_downstream);
1220   }
1221 }
1222
1223 // WARNING: Never call directly or indirectly nghttp2_session_send or
1224 // nghttp2_session_recv. These calls may delete downstream.
1225 int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
1226   int rv;
1227
1228   if (LOG_ENABLED(INFO)) {
1229     if (downstream->get_non_final_response()) {
1230       DLOG(INFO, downstream) << "HTTP non-final response header";
1231     } else {
1232       DLOG(INFO, downstream) << "HTTP response header completed";
1233     }
1234   }
1235
1236   if (!get_config()->http2_proxy && !get_config()->client_proxy &&
1237       !get_config()->no_location_rewrite) {
1238     downstream->rewrite_location_response_header(
1239         downstream->get_request_http2_scheme());
1240   }
1241
1242   size_t nheader = downstream->get_response_headers().size();
1243   auto nva = std::vector<nghttp2_nv>();
1244   // 3 means :status and possible server and via header field.
1245   nva.reserve(nheader + 3 + get_config()->add_response_headers.size());
1246   std::string via_value;
1247   auto response_status = util::utos(downstream->get_response_http_status());
1248   nva.push_back(http2::make_nv_ls(":status", response_status));
1249
1250   http2::copy_headers_to_nva(nva, downstream->get_response_headers());
1251
1252   if (downstream->get_non_final_response()) {
1253     if (LOG_ENABLED(INFO)) {
1254       log_response_headers(downstream, nva);
1255     }
1256
1257     rv = nghttp2_submit_headers(session_, NGHTTP2_FLAG_NONE,
1258                                 downstream->get_stream_id(), nullptr,
1259                                 nva.data(), nva.size(), nullptr);
1260
1261     downstream->clear_response_headers();
1262
1263     if (rv != 0) {
1264       ULOG(FATAL, this) << "nghttp2_submit_headers() failed";
1265       return -1;
1266     }
1267
1268     return 0;
1269   }
1270
1271   if (!get_config()->http2_proxy && !get_config()->client_proxy) {
1272     nva.push_back(http2::make_nv_lc("server", get_config()->server_name));
1273   } else {
1274     auto server = downstream->get_response_header(http2::HD_SERVER);
1275     if (server) {
1276       nva.push_back(http2::make_nv_ls("server", (*server).value));
1277     }
1278   }
1279
1280   auto via = downstream->get_response_header(http2::HD_VIA);
1281   if (get_config()->no_via) {
1282     if (via) {
1283       nva.push_back(http2::make_nv_ls("via", (*via).value));
1284     }
1285   } else {
1286     if (via) {
1287       via_value = (*via).value;
1288       via_value += ", ";
1289     }
1290     via_value += http::create_via_header_value(
1291         downstream->get_response_major(), downstream->get_response_minor());
1292     nva.push_back(http2::make_nv_ls("via", via_value));
1293   }
1294
1295   for (auto &p : get_config()->add_response_headers) {
1296     nva.push_back(http2::make_nv(p.first, p.second));
1297   }
1298
1299   if (LOG_ENABLED(INFO)) {
1300     log_response_headers(downstream, nva);
1301   }
1302
1303   if (get_config()->http2_upstream_dump_response_header) {
1304     http2::dump_nv(get_config()->http2_upstream_dump_response_header,
1305                    nva.data(), nva.size());
1306   }
1307
1308   nghttp2_data_provider data_prd;
1309   data_prd.source.ptr = downstream;
1310   data_prd.read_callback = downstream_data_read_callback;
1311
1312   nghttp2_data_provider *data_prdptr;
1313
1314   if (downstream->expect_response_body()) {
1315     data_prdptr = &data_prd;
1316   } else {
1317     data_prdptr = nullptr;
1318   }
1319
1320   rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
1321                                nva.data(), nva.size(), data_prdptr);
1322   if (rv != 0) {
1323     ULOG(FATAL, this) << "nghttp2_submit_response() failed";
1324     return -1;
1325   }
1326
1327   // We need some conditions that must be fulfilled to initiate server
1328   // push.
1329   //
1330   // * Server push is disabled for http2 proxy, since incoming headers
1331   //   are mixed origins.  We don't know how to reliably determine the
1332   //   authority yet.
1333   //
1334   // * If downstream is http/2, it is likely that PUSH_PROMISE is
1335   //   coming from there, so we don't initiate PUSH_RPOMISE here.
1336   //
1337   // * We need 200 response code for associated resource.  This is too
1338   //   restrictive, we will review this later.
1339   //
1340   // * We requires GET or POST for associated resource.  Probably we
1341   //   don't want to push for HEAD request.  Not sure other methods
1342   //   are also eligible for push.
1343   if (!get_config()->no_server_push &&
1344       get_config()->downstream_proto == PROTO_HTTP &&
1345       !get_config()->http2_proxy && (downstream->get_stream_id() % 2) &&
1346       downstream->get_response_header(http2::HD_LINK) &&
1347       downstream->get_response_http_status() == 200 &&
1348       (downstream->get_request_method() == "GET" ||
1349        downstream->get_request_method() == "POST")) {
1350
1351     if (prepare_push_promise(downstream) != 0) {
1352       return -1;
1353     }
1354   }
1355
1356   return 0;
1357 }
1358
1359 // WARNING: Never call directly or indirectly nghttp2_session_send or
1360 // nghttp2_session_recv. These calls may delete downstream.
1361 int Http2Upstream::on_downstream_body(Downstream *downstream,
1362                                       const uint8_t *data, size_t len,
1363                                       bool flush) {
1364   auto body = downstream->get_response_buf();
1365   body->append(data, len);
1366
1367   if (flush) {
1368     nghttp2_session_resume_data(session_, downstream->get_stream_id());
1369
1370     downstream->ensure_upstream_wtimer();
1371   }
1372
1373   return 0;
1374 }
1375
1376 // WARNING: Never call directly or indirectly nghttp2_session_send or
1377 // nghttp2_session_recv. These calls may delete downstream.
1378 int Http2Upstream::on_downstream_body_complete(Downstream *downstream) {
1379   if (LOG_ENABLED(INFO)) {
1380     DLOG(INFO, downstream) << "HTTP response completed";
1381   }
1382
1383   if (!downstream->validate_response_bodylen()) {
1384     rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR);
1385     downstream->set_response_connection_close(true);
1386     return 0;
1387   }
1388
1389   nghttp2_session_resume_data(session_, downstream->get_stream_id());
1390   downstream->ensure_upstream_wtimer();
1391
1392   return 0;
1393 }
1394
1395 bool Http2Upstream::get_flow_control() const { return flow_control_; }
1396
1397 void Http2Upstream::pause_read(IOCtrlReason reason) {}
1398
1399 int Http2Upstream::resume_read(IOCtrlReason reason, Downstream *downstream,
1400                                size_t consumed) {
1401   if (get_flow_control()) {
1402     assert(downstream->get_request_datalen() >= consumed);
1403
1404     if (consume(downstream->get_stream_id(), consumed) != 0) {
1405       return -1;
1406     }
1407
1408     downstream->dec_request_datalen(consumed);
1409   }
1410
1411   handler_->signal_write();
1412   return 0;
1413 }
1414
1415 int Http2Upstream::on_downstream_abort_request(Downstream *downstream,
1416                                                unsigned int status_code) {
1417   int rv;
1418
1419   rv = error_reply(downstream, status_code);
1420
1421   if (rv != 0) {
1422     return -1;
1423   }
1424
1425   handler_->signal_write();
1426   return 0;
1427 }
1428
1429 int Http2Upstream::consume(int32_t stream_id, size_t len) {
1430   int rv;
1431
1432   rv = nghttp2_session_consume(session_, stream_id, len);
1433
1434   if (rv != 0) {
1435     ULOG(WARN, this) << "nghttp2_session_consume() returned error: "
1436                      << nghttp2_strerror(rv);
1437     return -1;
1438   }
1439
1440   return 0;
1441 }
1442
1443 void
1444 Http2Upstream::log_response_headers(Downstream *downstream,
1445                                     const std::vector<nghttp2_nv> &nva) const {
1446   std::stringstream ss;
1447   for (auto &nv : nva) {
1448     ss << TTY_HTTP_HD << nv.name << TTY_RST << ": " << nv.value << "\n";
1449   }
1450   ULOG(INFO, this) << "HTTP response headers. stream_id="
1451                    << downstream->get_stream_id() << "\n" << ss.str();
1452 }
1453
1454 int Http2Upstream::on_timeout(Downstream *downstream) {
1455   if (LOG_ENABLED(INFO)) {
1456     ULOG(INFO, this) << "Stream timeout stream_id="
1457                      << downstream->get_stream_id();
1458   }
1459
1460   rst_stream(downstream, NGHTTP2_NO_ERROR);
1461
1462   return 0;
1463 }
1464
1465 void Http2Upstream::on_handler_delete() {
1466   for (auto d = downstream_queue_.get_downstreams(); d; d = d->dlnext) {
1467     if (d->get_dispatch_state() == Downstream::DISPATCH_ACTIVE &&
1468         d->accesslog_ready()) {
1469       handler_->write_accesslog(d);
1470     }
1471   }
1472 }
1473
1474 int Http2Upstream::on_downstream_reset(bool no_retry) {
1475   int rv;
1476
1477   for (auto downstream = downstream_queue_.get_downstreams(); downstream;
1478        downstream = downstream->dlnext) {
1479     if (downstream->get_dispatch_state() != Downstream::DISPATCH_ACTIVE) {
1480       continue;
1481     }
1482
1483     if (!downstream->request_submission_ready()) {
1484       rst_stream(downstream, NGHTTP2_INTERNAL_ERROR);
1485       downstream->pop_downstream_connection();
1486       continue;
1487     }
1488
1489     downstream->pop_downstream_connection();
1490
1491     downstream->add_retry();
1492
1493     if (no_retry || downstream->no_more_retry()) {
1494       goto fail;
1495     }
1496
1497     // downstream connection is clean; we can retry with new
1498     // downstream connection.
1499
1500     rv = downstream->attach_downstream_connection(
1501         handler_->get_downstream_connection());
1502     if (rv != 0) {
1503       goto fail;
1504     }
1505
1506     continue;
1507
1508   fail:
1509     if (on_downstream_abort_request(downstream, 503) != 0) {
1510       return -1;
1511     }
1512     downstream->pop_downstream_connection();
1513   }
1514
1515   handler_->signal_write();
1516
1517   return 0;
1518 }
1519
1520 int Http2Upstream::prepare_push_promise(Downstream *downstream) {
1521   int rv;
1522   http_parser_url u;
1523   memset(&u, 0, sizeof(u));
1524   rv = http_parser_parse_url(downstream->get_request_path().c_str(),
1525                              downstream->get_request_path().size(), 0, &u);
1526   if (rv != 0) {
1527     return 0;
1528   }
1529   const char *base;
1530   size_t baselen;
1531   if (u.field_set & (1 << UF_PATH)) {
1532     auto &f = u.field_data[UF_PATH];
1533     base = downstream->get_request_path().c_str() + f.off;
1534     baselen = f.len;
1535   } else {
1536     base = "/";
1537     baselen = 1;
1538   }
1539   for (auto &kv : downstream->get_response_headers()) {
1540     if (kv.token != http2::HD_LINK) {
1541       continue;
1542     }
1543     for (auto &link :
1544          http2::parse_link_header(kv.value.c_str(), kv.value.size())) {
1545       auto link_url = link.uri.first;
1546       auto link_urllen = link.uri.second - link.uri.first;
1547
1548       const char *rel;
1549       size_t rellen;
1550       const char *relq = nullptr;
1551       size_t relqlen = 0;
1552
1553       http_parser_url v;
1554       memset(&v, 0, sizeof(v));
1555       rv = http_parser_parse_url(link_url, link_urllen, 0, &v);
1556       if (rv != 0) {
1557         assert(link_urllen);
1558         if (link_url[0] == '/') {
1559           continue;
1560         }
1561         // treat link_url as relative URI.
1562         auto end = std::find(link_url, link_url + link_urllen, '#');
1563         auto q = std::find(link_url, end, '?');
1564         rel = link_url;
1565         rellen = q - link_url;
1566         if (q != end) {
1567           relq = q + 1;
1568           relqlen = end - relq;
1569         }
1570       } else {
1571         if (v.field_set & (1 << UF_HOST)) {
1572           continue;
1573         }
1574         if (v.field_set & (1 << UF_PATH)) {
1575           auto &f = v.field_data[UF_PATH];
1576           rel = link_url + f.off;
1577           rellen = f.len;
1578         } else {
1579           rel = "/";
1580           rellen = 1;
1581         }
1582
1583         if (v.field_set & (1 << UF_QUERY)) {
1584           auto &f = v.field_data[UF_QUERY];
1585           relq = link_url + f.off;
1586           relqlen = f.len;
1587         }
1588       }
1589       auto path = http2::path_join(base, baselen, nullptr, 0, rel, rellen, relq,
1590                                    relqlen);
1591       rv = submit_push_promise(path, downstream);
1592       if (rv != 0) {
1593         return -1;
1594       }
1595     }
1596   }
1597   return 0;
1598 }
1599
1600 int Http2Upstream::submit_push_promise(const std::string &path,
1601                                        Downstream *downstream) {
1602   int rv;
1603   std::vector<nghttp2_nv> nva;
1604   nva.reserve(downstream->get_request_headers().size());
1605
1606   // juse use "GET" for now
1607   nva.push_back(http2::make_nv_ll(":method", "GET"));
1608   nva.push_back(
1609       http2::make_nv_ls(":scheme", downstream->get_request_http2_scheme()));
1610   nva.push_back(http2::make_nv_ls(":path", path));
1611   auto &authority = downstream->get_request_http2_authority();
1612   if (!authority.empty()) {
1613     nva.push_back(http2::make_nv_ls(":authority", authority));
1614   }
1615
1616   for (auto &kv : downstream->get_request_headers()) {
1617     switch (kv.token) {
1618     // TODO generate referer
1619     case http2::HD__AUTHORITY:
1620     case http2::HD__SCHEME:
1621     case http2::HD__METHOD:
1622     case http2::HD__PATH:
1623       continue;
1624     case http2::HD_ACCEPT_ENCODING:
1625     case http2::HD_ACCEPT_LANGUAGE:
1626     case http2::HD_CACHE_CONTROL:
1627     case http2::HD_HOST:
1628     case http2::HD_USER_AGENT:
1629       nva.push_back(http2::make_nv(kv.name, kv.value, kv.no_index));
1630       break;
1631     }
1632   }
1633
1634   rv = nghttp2_submit_push_promise(session_, NGHTTP2_FLAG_NONE,
1635                                    downstream->get_stream_id(), nva.data(),
1636                                    nva.size(), nullptr);
1637
1638   if (rv < 0) {
1639     if (LOG_ENABLED(INFO)) {
1640       ULOG(INFO, this) << "nghttp2_submit_push_promise() failed: "
1641                        << nghttp2_strerror(rv);
1642     }
1643     if (nghttp2_is_fatal(rv)) {
1644       return -1;
1645     }
1646     return 0;
1647   }
1648
1649   if (LOG_ENABLED(INFO)) {
1650     std::stringstream ss;
1651     for (auto &nv : nva) {
1652       ss << TTY_HTTP_HD << nv.name << TTY_RST << ": " << nv.value << "\n";
1653     }
1654     ULOG(INFO, this) << "HTTP push request headers. promised_stream_id=" << rv
1655                      << "\n" << ss.str();
1656   }
1657
1658   return 0;
1659 }
1660
1661 } // namespace shrpx