Imported Upstream version 1.0.0
[platform/upstream/nghttp2.git] / src / HttpServer.cc
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2013 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 "HttpServer.h"
26
27 #include <sys/stat.h>
28 #ifdef HAVE_SYS_SOCKET_H
29 #include <sys/socket.h>
30 #endif // HAVE_SYS_SOCKET_H
31 #ifdef HAVE_NETDB_H
32 #include <netdb.h>
33 #endif // HAVE_NETDB_H
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif // HAVE_UNISTD_H
37 #ifdef HAVE_FCNTL_H
38 #include <fcntl.h>
39 #endif // HAVE_FCNTL_H
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
42 #endif // HAVE_NETINET_IN_H
43 #include <netinet/tcp.h>
44 #ifdef HAVE_ARPA_INET_H
45 #include <arpa/inet.h>
46 #endif // HAVE_ARPA_INET_H
47
48 #include <cassert>
49 #include <set>
50 #include <iostream>
51 #include <thread>
52 #include <mutex>
53 #include <deque>
54
55 #include <openssl/err.h>
56
57 #include <zlib.h>
58
59 #include "app_helper.h"
60 #include "http2.h"
61 #include "util.h"
62 #include "ssl.h"
63 #include "template.h"
64
65 #ifndef O_BINARY
66 #define O_BINARY (0)
67 #endif // O_BINARY
68
69 namespace nghttp2 {
70
71 namespace {
72 const std::string DEFAULT_HTML = "index.html";
73 const std::string NGHTTPD_SERVER = "nghttpd nghttp2/" NGHTTP2_VERSION;
74 } // namespace
75
76 namespace {
77 void delete_handler(Http2Handler *handler) {
78   handler->remove_self();
79   delete handler;
80 }
81 } // namespace
82
83 namespace {
84 void print_session_id(int64_t id) { std::cout << "[id=" << id << "] "; }
85 } // namespace
86
87 namespace {
88 template <typename Array> void append_nv(Stream *stream, const Array &nva) {
89   for (size_t i = 0; i < nva.size(); ++i) {
90     auto &nv = nva[i];
91     auto token = http2::lookup_token(nv.name, nv.namelen);
92     if (token != -1) {
93       http2::index_header(stream->hdidx, token, i);
94     }
95     http2::add_header(stream->headers, nv.name, nv.namelen, nv.value,
96                       nv.valuelen, nv.flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
97   }
98 }
99 } // namespace
100
101 Config::Config()
102     : stream_read_timeout(60.), stream_write_timeout(60.), data_ptr(nullptr),
103       padding(0), num_worker(1), max_concurrent_streams(100),
104       header_table_size(-1), port(0), verbose(false), daemon(false),
105       verify_client(false), no_tls(false), error_gzip(false),
106       early_response(false), hexdump(false), echo_upload(false) {}
107
108 Config::~Config() {}
109
110 namespace {
111 void stream_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
112   int rv;
113   auto stream = static_cast<Stream *>(w->data);
114   auto hd = stream->handler;
115   auto config = hd->get_config();
116
117   ev_timer_stop(hd->get_loop(), &stream->rtimer);
118   ev_timer_stop(hd->get_loop(), &stream->wtimer);
119
120   if (config->verbose) {
121     print_session_id(hd->session_id());
122     print_timer();
123     std::cout << " timeout stream_id=" << stream->stream_id << std::endl;
124   }
125
126   hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
127
128   rv = hd->on_write();
129   if (rv == -1) {
130     delete_handler(hd);
131   }
132 }
133 } // namespace
134
135 namespace {
136 void add_stream_read_timeout(Stream *stream) {
137   auto hd = stream->handler;
138   ev_timer_again(hd->get_loop(), &stream->rtimer);
139 }
140 } // namespace
141
142 namespace {
143 void add_stream_read_timeout_if_pending(Stream *stream) {
144   auto hd = stream->handler;
145   if (ev_is_active(&stream->rtimer)) {
146     ev_timer_again(hd->get_loop(), &stream->rtimer);
147   }
148 }
149 } // namespace
150
151 namespace {
152 void add_stream_write_timeout(Stream *stream) {
153   auto hd = stream->handler;
154   ev_timer_again(hd->get_loop(), &stream->wtimer);
155 }
156 } // namespace
157
158 namespace {
159 void remove_stream_read_timeout(Stream *stream) {
160   auto hd = stream->handler;
161   ev_timer_stop(hd->get_loop(), &stream->rtimer);
162 }
163 } // namespace
164
165 namespace {
166 void remove_stream_write_timeout(Stream *stream) {
167   auto hd = stream->handler;
168   ev_timer_stop(hd->get_loop(), &stream->wtimer);
169 }
170 } // namespace
171
172 namespace {
173 void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config);
174 } // namespace
175
176 class Sessions {
177 public:
178   Sessions(HttpServer *sv, struct ev_loop *loop, const Config *config,
179            SSL_CTX *ssl_ctx)
180       : sv_(sv), loop_(loop), config_(config), ssl_ctx_(ssl_ctx),
181         callbacks_(nullptr), next_session_id_(1), tstamp_cached_(ev_now(loop)),
182         cached_date_(util::http_date(tstamp_cached_)) {
183     nghttp2_session_callbacks_new(&callbacks_);
184
185     fill_callback(callbacks_, config_);
186   }
187   ~Sessions() {
188     for (auto handler : handlers_) {
189       delete handler;
190     }
191     nghttp2_session_callbacks_del(callbacks_);
192   }
193   void add_handler(Http2Handler *handler) { handlers_.insert(handler); }
194   void remove_handler(Http2Handler *handler) { handlers_.erase(handler); }
195   SSL_CTX *get_ssl_ctx() const { return ssl_ctx_; }
196   SSL *ssl_session_new(int fd) {
197     SSL *ssl = SSL_new(ssl_ctx_);
198     if (!ssl) {
199       std::cerr << "SSL_new() failed" << std::endl;
200       return nullptr;
201     }
202     if (SSL_set_fd(ssl, fd) == 0) {
203       std::cerr << "SSL_set_fd() failed" << std::endl;
204       SSL_free(ssl);
205       return nullptr;
206     }
207     return ssl;
208   }
209   const Config *get_config() const { return config_; }
210   struct ev_loop *get_loop() const {
211     return loop_;
212   }
213   int64_t get_next_session_id() {
214     auto session_id = next_session_id_;
215     if (next_session_id_ == std::numeric_limits<int64_t>::max()) {
216       next_session_id_ = 1;
217     } else {
218       ++next_session_id_;
219     }
220     return session_id;
221   }
222   const nghttp2_session_callbacks *get_callbacks() const { return callbacks_; }
223   void accept_connection(int fd) {
224     util::make_socket_nodelay(fd);
225     SSL *ssl = nullptr;
226     if (ssl_ctx_) {
227       ssl = ssl_session_new(fd);
228       if (!ssl) {
229         close(fd);
230         return;
231       }
232     }
233     auto handler =
234         make_unique<Http2Handler>(this, fd, ssl, get_next_session_id());
235     handler->setup_bev();
236     if (!ssl) {
237       if (handler->connection_made() != 0) {
238         return;
239       }
240     }
241     add_handler(handler.release());
242   }
243   void update_cached_date() { cached_date_ = util::http_date(tstamp_cached_); }
244   const std::string &get_cached_date() {
245     auto t = ev_now(loop_);
246     if (t != tstamp_cached_) {
247       tstamp_cached_ = t;
248       update_cached_date();
249     }
250     return cached_date_;
251   }
252   FileEntry *get_cached_fd(const std::string &path) {
253     auto i = fd_cache_.find(path);
254     if (i == std::end(fd_cache_)) {
255       return nullptr;
256     }
257     auto &ent = (*i).second;
258     ++ent.usecount;
259     return &ent;
260   }
261   FileEntry *cache_fd(const std::string &path, const FileEntry &ent) {
262     auto rv = fd_cache_.emplace(path, ent);
263     return &(*rv.first).second;
264   }
265   void release_fd(const std::string &path) {
266     auto i = fd_cache_.find(path);
267     if (i == std::end(fd_cache_)) {
268       return;
269     }
270     auto &ent = (*i).second;
271     if (--ent.usecount == 0) {
272       close(ent.fd);
273       fd_cache_.erase(i);
274     }
275   }
276   const HttpServer *get_server() const { return sv_; }
277
278 private:
279   std::set<Http2Handler *> handlers_;
280   // cache for file descriptors to read file.
281   std::map<std::string, FileEntry> fd_cache_;
282   HttpServer *sv_;
283   struct ev_loop *loop_;
284   const Config *config_;
285   SSL_CTX *ssl_ctx_;
286   nghttp2_session_callbacks *callbacks_;
287   int64_t next_session_id_;
288   ev_tstamp tstamp_cached_;
289   std::string cached_date_;
290 };
291
292 Stream::Stream(Http2Handler *handler, int32_t stream_id)
293     : handler(handler), file_ent(nullptr), body_length(0), body_offset(0),
294       stream_id(stream_id), echo_upload(false) {
295   auto config = handler->get_config();
296   ev_timer_init(&rtimer, stream_timeout_cb, 0., config->stream_read_timeout);
297   ev_timer_init(&wtimer, stream_timeout_cb, 0., config->stream_write_timeout);
298   rtimer.data = this;
299   wtimer.data = this;
300
301   headers.reserve(10);
302
303   http2::init_hdidx(hdidx);
304 }
305
306 Stream::~Stream() {
307   if (file_ent != nullptr) {
308     auto sessions = handler->get_sessions();
309     sessions->release_fd(file_ent->path);
310   }
311
312   auto loop = handler->get_loop();
313   ev_timer_stop(loop, &rtimer);
314   ev_timer_stop(loop, &wtimer);
315 }
316
317 namespace {
318 void on_session_closed(Http2Handler *hd, int64_t session_id) {
319   if (hd->get_config()->verbose) {
320     print_session_id(session_id);
321     print_timer();
322     std::cout << " closed" << std::endl;
323   }
324 }
325 } // namespace
326
327 namespace {
328 void settings_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
329   auto hd = static_cast<Http2Handler *>(w->data);
330   hd->terminate_session(NGHTTP2_SETTINGS_TIMEOUT);
331   hd->on_write();
332 }
333 } // namespace
334
335 namespace {
336 void readcb(struct ev_loop *loop, ev_io *w, int revents) {
337   int rv;
338   auto handler = static_cast<Http2Handler *>(w->data);
339
340   rv = handler->on_read();
341   if (rv == -1) {
342     delete_handler(handler);
343   }
344 }
345 } // namespace
346
347 namespace {
348 void writecb(struct ev_loop *loop, ev_io *w, int revents) {
349   int rv;
350   auto handler = static_cast<Http2Handler *>(w->data);
351
352   rv = handler->on_write();
353   if (rv == -1) {
354     delete_handler(handler);
355   }
356 }
357 } // namespace
358
359 Http2Handler::Http2Handler(Sessions *sessions, int fd, SSL *ssl,
360                            int64_t session_id)
361     : session_id_(session_id), session_(nullptr), sessions_(sessions),
362       ssl_(ssl), data_pending_(nullptr), data_pendinglen_(0), fd_(fd) {
363   ev_timer_init(&settings_timerev_, settings_timeout_cb, 10., 0.);
364   ev_io_init(&wev_, writecb, fd, EV_WRITE);
365   ev_io_init(&rev_, readcb, fd, EV_READ);
366
367   settings_timerev_.data = this;
368   wev_.data = this;
369   rev_.data = this;
370
371   auto loop = sessions_->get_loop();
372   ev_io_start(loop, &rev_);
373
374   if (ssl) {
375     SSL_set_accept_state(ssl);
376     read_ = &Http2Handler::tls_handshake;
377     write_ = &Http2Handler::tls_handshake;
378   } else {
379     read_ = &Http2Handler::read_clear;
380     write_ = &Http2Handler::write_clear;
381   }
382 }
383
384 Http2Handler::~Http2Handler() {
385   on_session_closed(this, session_id_);
386   nghttp2_session_del(session_);
387   if (ssl_) {
388     SSL_set_shutdown(ssl_, SSL_RECEIVED_SHUTDOWN);
389     ERR_clear_error();
390     SSL_shutdown(ssl_);
391   }
392   auto loop = sessions_->get_loop();
393   ev_timer_stop(loop, &settings_timerev_);
394   ev_io_stop(loop, &rev_);
395   ev_io_stop(loop, &wev_);
396   if (ssl_) {
397     SSL_free(ssl_);
398   }
399   shutdown(fd_, SHUT_WR);
400   close(fd_);
401 }
402
403 void Http2Handler::remove_self() { sessions_->remove_handler(this); }
404
405 struct ev_loop *Http2Handler::get_loop() const {
406   return sessions_->get_loop();
407 }
408
409 Http2Handler::WriteBuf *Http2Handler::get_wb() { return &wb_; }
410
411 int Http2Handler::setup_bev() { return 0; }
412
413 int Http2Handler::fill_wb() {
414   if (data_pending_) {
415     auto n = std::min(wb_.wleft(), data_pendinglen_);
416     wb_.write(data_pending_, n);
417     if (n < data_pendinglen_) {
418       data_pending_ += n;
419       data_pendinglen_ -= n;
420       return 0;
421     }
422
423     data_pending_ = nullptr;
424     data_pendinglen_ = 0;
425   }
426
427   for (;;) {
428     const uint8_t *data;
429     auto datalen = nghttp2_session_mem_send(session_, &data);
430
431     if (datalen < 0) {
432       std::cerr << "nghttp2_session_mem_send() returned error: "
433                 << nghttp2_strerror(datalen) << std::endl;
434       return -1;
435     }
436     if (datalen == 0) {
437       break;
438     }
439     auto n = wb_.write(data, datalen);
440     if (n < static_cast<decltype(n)>(datalen)) {
441       data_pending_ = data + n;
442       data_pendinglen_ = datalen - n;
443       break;
444     }
445   }
446   return 0;
447 }
448
449 int Http2Handler::read_clear() {
450   int rv;
451   std::array<uint8_t, 8192> buf;
452
453   for (;;) {
454     ssize_t nread;
455     while ((nread = read(fd_, buf.data(), buf.size())) == -1 && errno == EINTR)
456       ;
457     if (nread == -1) {
458       if (errno == EAGAIN || errno == EWOULDBLOCK) {
459         break;
460       }
461       return -1;
462     }
463     if (nread == 0) {
464       return -1;
465     }
466
467     if (get_config()->hexdump) {
468       util::hexdump(stdout, buf.data(), nread);
469     }
470
471     rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
472     if (rv < 0) {
473       if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
474         std::cerr << "nghttp2_session_mem_recv() returned error: "
475                   << nghttp2_strerror(rv) << std::endl;
476       }
477       return -1;
478     }
479   }
480
481   return write_(*this);
482 }
483
484 int Http2Handler::write_clear() {
485   auto loop = sessions_->get_loop();
486   for (;;) {
487     if (wb_.rleft() > 0) {
488       ssize_t nwrite;
489       while ((nwrite = write(fd_, wb_.pos, wb_.rleft())) == -1 &&
490              errno == EINTR)
491         ;
492       if (nwrite == -1) {
493         if (errno == EAGAIN || errno == EWOULDBLOCK) {
494           ev_io_start(loop, &wev_);
495           return 0;
496         }
497         return -1;
498       }
499       wb_.drain(nwrite);
500       continue;
501     }
502     wb_.reset();
503     if (fill_wb() != 0) {
504       return -1;
505     }
506     if (wb_.rleft() == 0) {
507       break;
508     }
509   }
510
511   if (wb_.rleft() == 0) {
512     ev_io_stop(loop, &wev_);
513   } else {
514     ev_io_start(loop, &wev_);
515   }
516
517   if (nghttp2_session_want_read(session_) == 0 &&
518       nghttp2_session_want_write(session_) == 0 && wb_.rleft() == 0) {
519     return -1;
520   }
521
522   return 0;
523 }
524
525 int Http2Handler::tls_handshake() {
526   ev_io_stop(sessions_->get_loop(), &wev_);
527
528   ERR_clear_error();
529
530   auto rv = SSL_do_handshake(ssl_);
531
532   if (rv == 0) {
533     return -1;
534   }
535
536   if (rv < 0) {
537     auto err = SSL_get_error(ssl_, rv);
538     switch (err) {
539     case SSL_ERROR_WANT_READ:
540       return 0;
541     case SSL_ERROR_WANT_WRITE:
542       ev_io_start(sessions_->get_loop(), &wev_);
543       return 0;
544     default:
545       return -1;
546     }
547   }
548
549   if (sessions_->get_config()->verbose) {
550     std::cerr << "SSL/TLS handshake completed" << std::endl;
551   }
552
553   if (verify_npn_result() != 0) {
554     return -1;
555   }
556
557   read_ = &Http2Handler::read_tls;
558   write_ = &Http2Handler::write_tls;
559
560   if (connection_made() != 0) {
561     return -1;
562   }
563
564   return 0;
565 }
566
567 int Http2Handler::read_tls() {
568   std::array<uint8_t, 8192> buf;
569
570   ERR_clear_error();
571
572   for (;;) {
573     auto rv = SSL_read(ssl_, buf.data(), buf.size());
574
575     if (rv == 0) {
576       return -1;
577     }
578
579     if (rv < 0) {
580       auto err = SSL_get_error(ssl_, rv);
581       switch (err) {
582       case SSL_ERROR_WANT_READ:
583         goto fin;
584       case SSL_ERROR_WANT_WRITE:
585         // renegotiation started
586         return -1;
587       default:
588         return -1;
589       }
590     }
591
592     auto nread = rv;
593
594     if (get_config()->hexdump) {
595       util::hexdump(stdout, buf.data(), nread);
596     }
597
598     rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
599     if (rv < 0) {
600       if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
601         std::cerr << "nghttp2_session_mem_recv() returned error: "
602                   << nghttp2_strerror(rv) << std::endl;
603       }
604       return -1;
605     }
606   }
607
608 fin:
609   return write_(*this);
610 }
611
612 int Http2Handler::write_tls() {
613   auto loop = sessions_->get_loop();
614
615   ERR_clear_error();
616
617   for (;;) {
618     if (wb_.rleft() > 0) {
619       auto rv = SSL_write(ssl_, wb_.pos, wb_.rleft());
620
621       if (rv == 0) {
622         return -1;
623       }
624
625       if (rv < 0) {
626         auto err = SSL_get_error(ssl_, rv);
627         switch (err) {
628         case SSL_ERROR_WANT_READ:
629           // renegotiation started
630           return -1;
631         case SSL_ERROR_WANT_WRITE:
632           ev_io_start(sessions_->get_loop(), &wev_);
633           return 0;
634         default:
635           return -1;
636         }
637       }
638
639       wb_.drain(rv);
640       continue;
641     }
642     wb_.reset();
643     if (fill_wb() != 0) {
644       return -1;
645     }
646     if (wb_.rleft() == 0) {
647       break;
648     }
649   }
650
651   if (wb_.rleft() == 0) {
652     ev_io_stop(loop, &wev_);
653   } else {
654     ev_io_start(loop, &wev_);
655   }
656
657   if (nghttp2_session_want_read(session_) == 0 &&
658       nghttp2_session_want_write(session_) == 0 && wb_.rleft() == 0) {
659     return -1;
660   }
661
662   return 0;
663 }
664
665 int Http2Handler::on_read() { return read_(*this); }
666
667 int Http2Handler::on_write() { return write_(*this); }
668
669 int Http2Handler::connection_made() {
670   int r;
671
672   r = nghttp2_session_server_new(&session_, sessions_->get_callbacks(), this);
673
674   if (r != 0) {
675     return r;
676   }
677
678   auto config = sessions_->get_config();
679   std::array<nghttp2_settings_entry, 4> entry;
680   size_t niv = 1;
681
682   entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
683   entry[0].value = config->max_concurrent_streams;
684
685   if (config->header_table_size >= 0) {
686     entry[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
687     entry[niv].value = config->header_table_size;
688     ++niv;
689   }
690   r = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, entry.data(), niv);
691   if (r != 0) {
692     return r;
693   }
694
695   ev_timer_start(sessions_->get_loop(), &settings_timerev_);
696
697   return on_write();
698 }
699
700 int Http2Handler::verify_npn_result() {
701   const unsigned char *next_proto = nullptr;
702   unsigned int next_proto_len;
703   // Check the negotiated protocol in NPN or ALPN
704   SSL_get0_next_proto_negotiated(ssl_, &next_proto, &next_proto_len);
705   for (int i = 0; i < 2; ++i) {
706     if (next_proto) {
707       if (sessions_->get_config()->verbose) {
708         std::string proto(next_proto, next_proto + next_proto_len);
709         std::cout << "The negotiated protocol: " << proto << std::endl;
710       }
711       if (util::check_h2_is_selected(next_proto, next_proto_len)) {
712         return 0;
713       }
714       break;
715     } else {
716 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
717       SSL_get0_alpn_selected(ssl_, &next_proto, &next_proto_len);
718 #else  // OPENSSL_VERSION_NUMBER < 0x10002000L
719       break;
720 #endif // OPENSSL_VERSION_NUMBER < 0x10002000L
721     }
722   }
723   if (sessions_->get_config()->verbose) {
724     std::cerr << "Client did not advertise HTTP/2 protocol."
725               << " (nghttp2 expects " << NGHTTP2_PROTO_VERSION_ID << ")"
726               << std::endl;
727   }
728   return -1;
729 }
730
731 int Http2Handler::submit_file_response(const std::string &status,
732                                        Stream *stream, time_t last_modified,
733                                        off_t file_length,
734                                        nghttp2_data_provider *data_prd) {
735   std::string content_length = util::utos(file_length);
736   std::string last_modified_str;
737   auto nva = make_array(http2::make_nv_ls(":status", status),
738                         http2::make_nv_ls("server", NGHTTPD_SERVER),
739                         http2::make_nv_ls("content-length", content_length),
740                         http2::make_nv_ll("cache-control", "max-age=3600"),
741                         http2::make_nv_ls("date", sessions_->get_cached_date()),
742                         http2::make_nv_ll("", ""), http2::make_nv_ll("", ""));
743   size_t nvlen = 5;
744   if (last_modified != 0) {
745     last_modified_str = util::http_date(last_modified);
746     nva[nvlen++] = http2::make_nv_ls("last-modified", last_modified_str);
747   }
748   auto &trailer = get_config()->trailer;
749   std::string trailer_names;
750   if (!trailer.empty()) {
751     trailer_names = trailer[0].name;
752     for (size_t i = 1; i < trailer.size(); ++i) {
753       trailer_names += ", ";
754       trailer_names += trailer[i].name;
755     }
756     nva[nvlen++] = http2::make_nv_ls("trailer", trailer_names);
757   }
758   return nghttp2_submit_response(session_, stream->stream_id, nva.data(), nvlen,
759                                  data_prd);
760 }
761
762 int Http2Handler::submit_response(const std::string &status, int32_t stream_id,
763                                   const Headers &headers,
764                                   nghttp2_data_provider *data_prd) {
765   auto nva = std::vector<nghttp2_nv>();
766   nva.reserve(3 + headers.size());
767   nva.push_back(http2::make_nv_ls(":status", status));
768   nva.push_back(http2::make_nv_ls("server", NGHTTPD_SERVER));
769   nva.push_back(http2::make_nv_ls("date", sessions_->get_cached_date()));
770   for (auto &nv : headers) {
771     nva.push_back(http2::make_nv(nv.name, nv.value, nv.no_index));
772   }
773   int r = nghttp2_submit_response(session_, stream_id, nva.data(), nva.size(),
774                                   data_prd);
775   return r;
776 }
777
778 int Http2Handler::submit_response(const std::string &status, int32_t stream_id,
779                                   nghttp2_data_provider *data_prd) {
780   auto nva = make_array(http2::make_nv_ls(":status", status),
781                         http2::make_nv_ls("server", NGHTTPD_SERVER));
782   return nghttp2_submit_response(session_, stream_id, nva.data(), nva.size(),
783                                  data_prd);
784 }
785
786 int Http2Handler::submit_non_final_response(const std::string &status,
787                                             int32_t stream_id) {
788   auto nva = make_array(http2::make_nv_ls(":status", status));
789   return nghttp2_submit_headers(session_, NGHTTP2_FLAG_NONE, stream_id, nullptr,
790                                 nva.data(), nva.size(), nullptr);
791 }
792
793 int Http2Handler::submit_push_promise(Stream *stream,
794                                       const std::string &push_path) {
795   auto authority =
796       http2::get_header(stream->hdidx, http2::HD__AUTHORITY, stream->headers);
797
798   if (!authority) {
799     authority =
800         http2::get_header(stream->hdidx, http2::HD_HOST, stream->headers);
801   }
802
803   auto nva =
804       make_array(http2::make_nv_ll(":method", "GET"),
805                  http2::make_nv_ls(":path", push_path),
806                  get_config()->no_tls ? http2::make_nv_ll(":scheme", "http")
807                                       : http2::make_nv_ll(":scheme", "https"),
808                  http2::make_nv_ls(":authority", authority->value));
809
810   auto promised_stream_id = nghttp2_submit_push_promise(
811       session_, NGHTTP2_FLAG_END_HEADERS, stream->stream_id, nva.data(),
812       nva.size(), nullptr);
813
814   if (promised_stream_id < 0) {
815     return promised_stream_id;
816   }
817
818   auto promised_stream = make_unique<Stream>(this, promised_stream_id);
819
820   append_nv(promised_stream.get(), nva);
821   add_stream(promised_stream_id, std::move(promised_stream));
822
823   return 0;
824 }
825
826 int Http2Handler::submit_rst_stream(Stream *stream, uint32_t error_code) {
827   remove_stream_read_timeout(stream);
828   remove_stream_write_timeout(stream);
829
830   return nghttp2_submit_rst_stream(session_, NGHTTP2_FLAG_NONE,
831                                    stream->stream_id, error_code);
832 }
833
834 void Http2Handler::add_stream(int32_t stream_id,
835                               std::unique_ptr<Stream> stream) {
836   id2stream_[stream_id] = std::move(stream);
837 }
838
839 void Http2Handler::remove_stream(int32_t stream_id) {
840   id2stream_.erase(stream_id);
841 }
842
843 Stream *Http2Handler::get_stream(int32_t stream_id) {
844   auto itr = id2stream_.find(stream_id);
845   if (itr == std::end(id2stream_)) {
846     return nullptr;
847   } else {
848     return (*itr).second.get();
849   }
850 }
851
852 int64_t Http2Handler::session_id() const { return session_id_; }
853
854 Sessions *Http2Handler::get_sessions() const { return sessions_; }
855
856 const Config *Http2Handler::get_config() const {
857   return sessions_->get_config();
858 }
859
860 void Http2Handler::remove_settings_timer() {
861   ev_timer_stop(sessions_->get_loop(), &settings_timerev_);
862 }
863
864 void Http2Handler::terminate_session(uint32_t error_code) {
865   nghttp2_session_terminate_session(session_, error_code);
866 }
867
868 ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
869                            uint8_t *buf, size_t length, uint32_t *data_flags,
870                            nghttp2_data_source *source, void *user_data) {
871   int rv;
872   auto hd = static_cast<Http2Handler *>(user_data);
873   auto stream = hd->get_stream(stream_id);
874
875   auto nread = std::min(stream->body_length - stream->body_offset,
876                         static_cast<int64_t>(length));
877
878   *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
879
880   if (nread == 0 || stream->body_length == stream->body_offset + nread) {
881     *data_flags |= NGHTTP2_DATA_FLAG_EOF;
882
883     auto config = hd->get_config();
884     if (!config->trailer.empty()) {
885       std::vector<nghttp2_nv> nva;
886       nva.reserve(config->trailer.size());
887       for (auto &kv : config->trailer) {
888         nva.push_back(http2::make_nv(kv.name, kv.value, kv.no_index));
889       }
890       rv = nghttp2_submit_trailer(session, stream_id, nva.data(), nva.size());
891       if (rv != 0) {
892         if (nghttp2_is_fatal(rv)) {
893           return NGHTTP2_ERR_CALLBACK_FAILURE;
894         }
895       } else {
896         *data_flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
897       }
898     }
899
900     if (nghttp2_session_get_stream_remote_close(session, stream_id) == 0) {
901       remove_stream_read_timeout(stream);
902       remove_stream_write_timeout(stream);
903
904       hd->submit_rst_stream(stream, NGHTTP2_NO_ERROR);
905     }
906   }
907
908   return nread;
909 }
910
911 namespace {
912 void prepare_status_response(Stream *stream, Http2Handler *hd, int status) {
913   auto sessions = hd->get_sessions();
914   auto status_page = sessions->get_server()->get_status_page(status);
915   auto file_ent = &status_page->file_ent;
916
917   // we don't set stream->file_ent since we don't want to expire it.
918   stream->body_length = file_ent->length;
919   nghttp2_data_provider data_prd;
920   data_prd.source.fd = file_ent->fd;
921   data_prd.read_callback = file_read_callback;
922
923   Headers headers;
924   headers.emplace_back("content-type", "text/html; charset=UTF-8");
925   hd->submit_response(status_page->status, stream->stream_id, headers,
926                       &data_prd);
927 }
928 } // namespace
929
930 namespace {
931 void prepare_echo_response(Stream *stream, Http2Handler *hd) {
932   auto length = lseek(stream->file_ent->fd, 0, SEEK_END);
933   if (length == -1) {
934     hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
935     return;
936   }
937   stream->body_length = length;
938   if (lseek(stream->file_ent->fd, 0, SEEK_SET) == -1) {
939     hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
940     return;
941   }
942   nghttp2_data_provider data_prd;
943   data_prd.source.fd = stream->file_ent->fd;
944   data_prd.read_callback = file_read_callback;
945
946   Headers headers;
947   headers.emplace_back("nghttpd-response", "echo");
948   headers.emplace_back("content-length", util::utos(length));
949
950   hd->submit_response("200", stream->stream_id, headers, &data_prd);
951 }
952 } // namespace
953
954 namespace {
955 bool prepare_upload_temp_store(Stream *stream, Http2Handler *hd) {
956   auto sessions = hd->get_sessions();
957
958   char tempfn[] = "/tmp/nghttpd.temp.XXXXXX";
959   auto fd = mkstemp(tempfn);
960   if (fd == -1) {
961     return false;
962   }
963   unlink(tempfn);
964   // Ordinary request never start with "echo:".  The length is 0 for
965   // now.  We will update it when we get whole request body.
966   stream->file_ent = sessions->cache_fd(std::string("echo:") + tempfn,
967                                         FileEntry(tempfn, 0, 0, fd));
968   stream->echo_upload = true;
969   return true;
970 }
971 } // namespace
972
973 namespace {
974 void prepare_redirect_response(Stream *stream, Http2Handler *hd,
975                                const std::string &path, int status) {
976   auto scheme =
977       http2::get_header(stream->hdidx, http2::HD__SCHEME, stream->headers);
978   auto authority =
979       http2::get_header(stream->hdidx, http2::HD__AUTHORITY, stream->headers);
980   if (!authority) {
981     authority =
982         http2::get_header(stream->hdidx, http2::HD_HOST, stream->headers);
983   }
984
985   auto redirect_url = scheme->value;
986   redirect_url += "://";
987   redirect_url += authority->value;
988   redirect_url += path;
989
990   auto headers = Headers{{"location", redirect_url}};
991
992   auto sessions = hd->get_sessions();
993   auto status_page = sessions->get_server()->get_status_page(status);
994
995   hd->submit_response(status_page->status, stream->stream_id, headers, nullptr);
996 }
997 } // namespace
998
999 namespace {
1000 void prepare_response(Stream *stream, Http2Handler *hd,
1001                       bool allow_push = true) {
1002   int rv;
1003   auto reqpath =
1004       http2::get_header(stream->hdidx, http2::HD__PATH, stream->headers)->value;
1005   auto ims =
1006       get_header(stream->hdidx, http2::HD_IF_MODIFIED_SINCE, stream->headers);
1007
1008   time_t last_mod = 0;
1009   bool last_mod_found = false;
1010   if (ims) {
1011     last_mod_found = true;
1012     last_mod = util::parse_http_date(ims->value);
1013   }
1014   auto query_pos = reqpath.find("?");
1015   std::string url;
1016   if (query_pos != std::string::npos) {
1017     // Do not response to this request to allow clients to test timeouts.
1018     if (reqpath.find("nghttpd_do_not_respond_to_req=yes", query_pos) !=
1019         std::string::npos) {
1020       return;
1021     }
1022     url = reqpath.substr(0, query_pos);
1023   } else {
1024     url = reqpath;
1025   }
1026
1027   auto sessions = hd->get_sessions();
1028
1029   url = util::percentDecode(std::begin(url), std::end(url));
1030   if (!util::check_path(url)) {
1031     if (stream->file_ent) {
1032       sessions->release_fd(stream->file_ent->path);
1033       stream->file_ent = nullptr;
1034     }
1035     prepare_status_response(stream, hd, 404);
1036     return;
1037   }
1038   auto push_itr = hd->get_config()->push.find(url);
1039   if (allow_push && push_itr != std::end(hd->get_config()->push)) {
1040     for (auto &push_path : (*push_itr).second) {
1041       rv = hd->submit_push_promise(stream, push_path);
1042       if (rv != 0) {
1043         std::cerr << "nghttp2_submit_push_promise() returned error: "
1044                   << nghttp2_strerror(rv) << std::endl;
1045       }
1046     }
1047   }
1048
1049   std::string path = hd->get_config()->htdocs + url;
1050   if (path[path.size() - 1] == '/') {
1051     path += DEFAULT_HTML;
1052   }
1053
1054   if (stream->echo_upload) {
1055     assert(stream->file_ent);
1056     prepare_echo_response(stream, hd);
1057     return;
1058   }
1059
1060   auto file_ent = sessions->get_cached_fd(path);
1061
1062   if (file_ent == nullptr) {
1063     int file = open(path.c_str(), O_RDONLY | O_BINARY);
1064     if (file == -1) {
1065       prepare_status_response(stream, hd, 404);
1066
1067       return;
1068     }
1069
1070     struct stat buf;
1071
1072     if (fstat(file, &buf) == -1) {
1073       close(file);
1074       prepare_status_response(stream, hd, 404);
1075
1076       return;
1077     }
1078
1079     if (buf.st_mode & S_IFDIR) {
1080       close(file);
1081
1082       if (query_pos == std::string::npos) {
1083         reqpath += "/";
1084       } else {
1085         reqpath.insert(query_pos, "/");
1086       }
1087
1088       prepare_redirect_response(stream, hd, reqpath, 301);
1089
1090       return;
1091     }
1092
1093     if (last_mod_found && buf.st_mtime <= last_mod) {
1094       close(file);
1095       prepare_status_response(stream, hd, 304);
1096
1097       return;
1098     }
1099
1100     file_ent = sessions->cache_fd(
1101         path, FileEntry(path, buf.st_size, buf.st_mtime, file));
1102   } else if (last_mod_found && file_ent->mtime <= last_mod) {
1103     sessions->release_fd(file_ent->path);
1104     prepare_status_response(stream, hd, 304);
1105
1106     return;
1107   }
1108
1109   stream->file_ent = file_ent;
1110   stream->body_length = file_ent->length;
1111
1112   nghttp2_data_provider data_prd;
1113
1114   data_prd.source.fd = file_ent->fd;
1115   data_prd.read_callback = file_read_callback;
1116
1117   hd->submit_file_response("200", stream, file_ent->mtime, file_ent->length,
1118                            &data_prd);
1119 }
1120 } // namespace
1121
1122 namespace {
1123 int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
1124                        const uint8_t *name, size_t namelen,
1125                        const uint8_t *value, size_t valuelen, uint8_t flags,
1126                        void *user_data) {
1127   auto hd = static_cast<Http2Handler *>(user_data);
1128   if (hd->get_config()->verbose) {
1129     print_session_id(hd->session_id());
1130     verbose_on_header_callback(session, frame, name, namelen, value, valuelen,
1131                                flags, user_data);
1132   }
1133   if (frame->hd.type != NGHTTP2_HEADERS ||
1134       frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
1135     return 0;
1136   }
1137   auto stream = hd->get_stream(frame->hd.stream_id);
1138   if (!stream) {
1139     return 0;
1140   }
1141
1142   auto token = http2::lookup_token(name, namelen);
1143
1144   http2::index_header(stream->hdidx, token, stream->headers.size());
1145   http2::add_header(stream->headers, name, namelen, value, valuelen,
1146                     flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
1147   return 0;
1148 }
1149 } // namespace
1150
1151 namespace {
1152 int on_begin_headers_callback(nghttp2_session *session,
1153                               const nghttp2_frame *frame, void *user_data) {
1154   auto hd = static_cast<Http2Handler *>(user_data);
1155
1156   if (frame->hd.type != NGHTTP2_HEADERS ||
1157       frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
1158     return 0;
1159   }
1160
1161   auto stream = make_unique<Stream>(hd, frame->hd.stream_id);
1162
1163   add_stream_read_timeout(stream.get());
1164
1165   hd->add_stream(frame->hd.stream_id, std::move(stream));
1166
1167   return 0;
1168 }
1169 } // namespace
1170
1171 namespace {
1172 int hd_on_frame_recv_callback(nghttp2_session *session,
1173                               const nghttp2_frame *frame, void *user_data) {
1174   auto hd = static_cast<Http2Handler *>(user_data);
1175   if (hd->get_config()->verbose) {
1176     print_session_id(hd->session_id());
1177     verbose_on_frame_recv_callback(session, frame, user_data);
1178   }
1179   switch (frame->hd.type) {
1180   case NGHTTP2_DATA: {
1181     // TODO Handle POST
1182     auto stream = hd->get_stream(frame->hd.stream_id);
1183     if (!stream) {
1184       return 0;
1185     }
1186
1187     if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
1188       remove_stream_read_timeout(stream);
1189       if (stream->echo_upload || !hd->get_config()->early_response) {
1190         prepare_response(stream, hd);
1191       }
1192     } else {
1193       add_stream_read_timeout(stream);
1194     }
1195
1196     break;
1197   }
1198   case NGHTTP2_HEADERS: {
1199     auto stream = hd->get_stream(frame->hd.stream_id);
1200     if (!stream) {
1201       return 0;
1202     }
1203
1204     if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
1205
1206       auto expect100 =
1207           http2::get_header(stream->hdidx, http2::HD_EXPECT, stream->headers);
1208
1209       if (expect100 && util::strieq_l("100-continue", expect100->value)) {
1210         hd->submit_non_final_response("100", frame->hd.stream_id);
1211       }
1212
1213       auto &method = http2::get_header(stream->hdidx, http2::HD__METHOD,
1214                                        stream->headers)->value;
1215       if (hd->get_config()->echo_upload &&
1216           (method == "POST" || method == "PUT")) {
1217         if (!prepare_upload_temp_store(stream, hd)) {
1218           hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
1219           return 0;
1220         }
1221       } else if (hd->get_config()->early_response) {
1222         prepare_response(stream, hd);
1223       }
1224     }
1225
1226     if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
1227       remove_stream_read_timeout(stream);
1228       if (stream->echo_upload || !hd->get_config()->early_response) {
1229         prepare_response(stream, hd);
1230       }
1231     } else {
1232       add_stream_read_timeout(stream);
1233     }
1234
1235     break;
1236   }
1237   case NGHTTP2_SETTINGS:
1238     if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
1239       hd->remove_settings_timer();
1240     }
1241     break;
1242   default:
1243     break;
1244   }
1245   return 0;
1246 }
1247 } // namespace
1248
1249 namespace {
1250 int hd_on_frame_send_callback(nghttp2_session *session,
1251                               const nghttp2_frame *frame, void *user_data) {
1252   auto hd = static_cast<Http2Handler *>(user_data);
1253
1254   if (hd->get_config()->verbose) {
1255     print_session_id(hd->session_id());
1256     verbose_on_frame_send_callback(session, frame, user_data);
1257   }
1258
1259   switch (frame->hd.type) {
1260   case NGHTTP2_DATA:
1261   case NGHTTP2_HEADERS: {
1262     auto stream = hd->get_stream(frame->hd.stream_id);
1263
1264     if (!stream) {
1265       return 0;
1266     }
1267
1268     if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
1269       remove_stream_write_timeout(stream);
1270     } else if (std::min(nghttp2_session_get_stream_remote_window_size(
1271                             session, frame->hd.stream_id),
1272                         nghttp2_session_get_remote_window_size(session)) <= 0) {
1273       // If stream is blocked by flow control, enable write timeout.
1274       add_stream_read_timeout_if_pending(stream);
1275       add_stream_write_timeout(stream);
1276     } else {
1277       add_stream_read_timeout_if_pending(stream);
1278       remove_stream_write_timeout(stream);
1279     }
1280
1281     break;
1282   }
1283   case NGHTTP2_PUSH_PROMISE: {
1284     auto promised_stream_id = frame->push_promise.promised_stream_id;
1285     auto promised_stream = hd->get_stream(promised_stream_id);
1286     auto stream = hd->get_stream(frame->hd.stream_id);
1287
1288     if (!stream || !promised_stream) {
1289       return 0;
1290     }
1291
1292     add_stream_read_timeout_if_pending(stream);
1293     add_stream_write_timeout(stream);
1294
1295     prepare_response(promised_stream, hd, /*allow_push */ false);
1296   }
1297   }
1298   return 0;
1299 }
1300 } // namespace
1301
1302 namespace {
1303 int send_data_callback(nghttp2_session *session, nghttp2_frame *frame,
1304                        const uint8_t *framehd, size_t length,
1305                        nghttp2_data_source *source, void *user_data) {
1306   auto hd = static_cast<Http2Handler *>(user_data);
1307   auto wb = hd->get_wb();
1308   auto padlen = frame->data.padlen;
1309   auto stream = hd->get_stream(frame->hd.stream_id);
1310
1311   if (wb->wleft() < 9 + length + padlen) {
1312     return NGHTTP2_ERR_WOULDBLOCK;
1313   }
1314
1315   int fd = source->fd;
1316
1317   auto p = wb->last;
1318
1319   p = std::copy_n(framehd, 9, p);
1320
1321   if (padlen) {
1322     *p++ = padlen - 1;
1323   }
1324
1325   while (length) {
1326     ssize_t nread;
1327     while ((nread = pread(fd, p, length, stream->body_offset)) == -1 &&
1328            errno == EINTR)
1329       ;
1330
1331     if (nread == -1) {
1332       remove_stream_read_timeout(stream);
1333       remove_stream_write_timeout(stream);
1334
1335       return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
1336     }
1337
1338     stream->body_offset += nread;
1339     length -= nread;
1340     p += nread;
1341   }
1342
1343   if (padlen) {
1344     std::fill(p, p + padlen - 1, 0);
1345     p += padlen - 1;
1346   }
1347
1348   wb->last = p;
1349
1350   return 0;
1351 }
1352 } // namespace
1353
1354 namespace {
1355 ssize_t select_padding_callback(nghttp2_session *session,
1356                                 const nghttp2_frame *frame, size_t max_payload,
1357                                 void *user_data) {
1358   auto hd = static_cast<Http2Handler *>(user_data);
1359   return std::min(max_payload, frame->hd.length + hd->get_config()->padding);
1360 }
1361 } // namespace
1362
1363 namespace {
1364 int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
1365                                 int32_t stream_id, const uint8_t *data,
1366                                 size_t len, void *user_data) {
1367   auto hd = static_cast<Http2Handler *>(user_data);
1368   auto stream = hd->get_stream(stream_id);
1369
1370   if (!stream) {
1371     return 0;
1372   }
1373
1374   if (stream->echo_upload) {
1375     assert(stream->file_ent);
1376     while (len) {
1377       ssize_t n;
1378       while ((n = write(stream->file_ent->fd, data, len)) == -1 &&
1379              errno == EINTR)
1380         ;
1381       if (n == -1) {
1382         hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
1383         return 0;
1384       }
1385       len -= n;
1386       data += n;
1387     }
1388   }
1389   // TODO Handle POST
1390
1391   add_stream_read_timeout(stream);
1392
1393   return 0;
1394 }
1395 } // namespace
1396
1397 namespace {
1398 int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
1399                              uint32_t error_code, void *user_data) {
1400   auto hd = static_cast<Http2Handler *>(user_data);
1401   hd->remove_stream(stream_id);
1402   if (hd->get_config()->verbose) {
1403     print_session_id(hd->session_id());
1404     print_timer();
1405     printf(" stream_id=%d closed\n", stream_id);
1406     fflush(stdout);
1407   }
1408   return 0;
1409 }
1410 } // namespace
1411
1412 namespace {
1413 void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config) {
1414   nghttp2_session_callbacks_set_on_stream_close_callback(
1415       callbacks, on_stream_close_callback);
1416
1417   nghttp2_session_callbacks_set_on_frame_recv_callback(
1418       callbacks, hd_on_frame_recv_callback);
1419
1420   nghttp2_session_callbacks_set_on_frame_send_callback(
1421       callbacks, hd_on_frame_send_callback);
1422
1423   if (config->verbose) {
1424     nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
1425         callbacks, verbose_on_invalid_frame_recv_callback);
1426   }
1427
1428   nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
1429       callbacks, on_data_chunk_recv_callback);
1430
1431   nghttp2_session_callbacks_set_on_header_callback(callbacks,
1432                                                    on_header_callback);
1433
1434   nghttp2_session_callbacks_set_on_begin_headers_callback(
1435       callbacks, on_begin_headers_callback);
1436
1437   nghttp2_session_callbacks_set_send_data_callback(callbacks,
1438                                                    send_data_callback);
1439
1440   if (config->padding) {
1441     nghttp2_session_callbacks_set_select_padding_callback(
1442         callbacks, select_padding_callback);
1443   }
1444 }
1445 } // namespace
1446
1447 struct ClientInfo {
1448   int fd;
1449 };
1450
1451 struct Worker {
1452   std::unique_ptr<Sessions> sessions;
1453   ev_async w;
1454   // protectes q
1455   std::mutex m;
1456   std::deque<ClientInfo> q;
1457 };
1458
1459 namespace {
1460 void worker_acceptcb(struct ev_loop *loop, ev_async *w, int revents) {
1461   auto worker = static_cast<Worker *>(w->data);
1462   auto &sessions = worker->sessions;
1463
1464   std::deque<ClientInfo> q;
1465   {
1466     std::lock_guard<std::mutex> lock(worker->m);
1467     q.swap(worker->q);
1468   }
1469
1470   for (auto c : q) {
1471     sessions->accept_connection(c.fd);
1472   }
1473 }
1474 } // namespace
1475
1476 namespace {
1477 void run_worker(Worker *worker) {
1478   auto loop = worker->sessions->get_loop();
1479
1480   ev_run(loop, 0);
1481 }
1482 } // namespace
1483
1484 class AcceptHandler {
1485 public:
1486   AcceptHandler(HttpServer *sv, Sessions *sessions, const Config *config)
1487       : sessions_(sessions), config_(config), next_worker_(0) {
1488     if (config_->num_worker == 1) {
1489       return;
1490     }
1491     for (size_t i = 0; i < config_->num_worker; ++i) {
1492       if (config_->verbose) {
1493         std::cerr << "spawning thread #" << i << std::endl;
1494       }
1495       auto worker = make_unique<Worker>();
1496       auto loop = ev_loop_new(0);
1497       worker->sessions =
1498           make_unique<Sessions>(sv, loop, config_, sessions_->get_ssl_ctx());
1499       ev_async_init(&worker->w, worker_acceptcb);
1500       worker->w.data = worker.get();
1501       ev_async_start(loop, &worker->w);
1502
1503       auto t = std::thread(run_worker, worker.get());
1504       t.detach();
1505       workers_.push_back(std::move(worker));
1506     }
1507   }
1508   void accept_connection(int fd) {
1509     if (config_->num_worker == 1) {
1510       sessions_->accept_connection(fd);
1511       return;
1512     }
1513
1514     // Dispatch client to the one of the worker threads, in a round
1515     // robin manner.
1516     auto &worker = workers_[next_worker_];
1517     if (next_worker_ == config_->num_worker - 1) {
1518       next_worker_ = 0;
1519     } else {
1520       ++next_worker_;
1521     }
1522     {
1523       std::lock_guard<std::mutex> lock(worker->m);
1524       worker->q.push_back({fd});
1525     }
1526     ev_async_send(worker->sessions->get_loop(), &worker->w);
1527   }
1528
1529 private:
1530   std::vector<std::unique_ptr<Worker>> workers_;
1531   Sessions *sessions_;
1532   const Config *config_;
1533   // In multi threading mode, this points to the next thread that
1534   // client will be dispatched.
1535   size_t next_worker_;
1536 };
1537
1538 namespace {
1539 void acceptcb(struct ev_loop *loop, ev_io *w, int revents);
1540 } // namespace
1541
1542 class ListenEventHandler {
1543 public:
1544   ListenEventHandler(Sessions *sessions, int fd,
1545                      std::shared_ptr<AcceptHandler> acceptor)
1546       : acceptor_(acceptor), sessions_(sessions), fd_(fd) {
1547     ev_io_init(&w_, acceptcb, fd, EV_READ);
1548     w_.data = this;
1549     ev_io_start(sessions_->get_loop(), &w_);
1550   }
1551   void accept_connection() {
1552     for (;;) {
1553 #ifdef HAVE_ACCEPT4
1554       auto fd = accept4(fd_, nullptr, nullptr, SOCK_NONBLOCK);
1555 #else  // !HAVE_ACCEPT4
1556       auto fd = accept(fd_, nullptr, nullptr);
1557 #endif // !HAVE_ACCEPT4
1558       if (fd == -1) {
1559         break;
1560       }
1561 #ifndef HAVE_ACCEPT4
1562       util::make_socket_nonblocking(fd);
1563 #endif // !HAVE_ACCEPT4
1564       acceptor_->accept_connection(fd);
1565     }
1566   }
1567
1568 private:
1569   ev_io w_;
1570   std::shared_ptr<AcceptHandler> acceptor_;
1571   Sessions *sessions_;
1572   int fd_;
1573 };
1574
1575 namespace {
1576 void acceptcb(struct ev_loop *loop, ev_io *w, int revents) {
1577   auto handler = static_cast<ListenEventHandler *>(w->data);
1578   handler->accept_connection();
1579 }
1580 } // namespace
1581
1582 namespace {
1583 FileEntry make_status_body(int status, uint16_t port) {
1584   std::string body;
1585   body = "<html><head><title>";
1586   body += http2::get_status_string(status);
1587   body += "</title></head><body><h1>";
1588   body += http2::get_status_string(status);
1589   body += "</h1><hr><address>";
1590   body += NGHTTPD_SERVER;
1591   body += " at port ";
1592   body += util::utos(port);
1593   body += "</address>";
1594   body += "</body></html>";
1595
1596   char tempfn[] = "/tmp/nghttpd.temp.XXXXXX";
1597   int fd = mkstemp(tempfn);
1598   if (fd == -1) {
1599     auto error = errno;
1600     std::cerr << "Could not open status response body file: errno=" << error;
1601     assert(0);
1602   }
1603   unlink(tempfn);
1604   ssize_t nwrite;
1605   while ((nwrite = write(fd, body.c_str(), body.size())) == -1 &&
1606          errno == EINTR)
1607     ;
1608   if (nwrite == -1) {
1609     auto error = errno;
1610     std::cerr << "Could not write status response body into file: errno="
1611               << error;
1612     assert(0);
1613   }
1614
1615   return FileEntry(util::utos(status), nwrite, 0, fd);
1616 }
1617 } // namespace
1618
1619 // index into HttpServer::status_pages_
1620 enum {
1621   IDX_200,
1622   IDX_301,
1623   IDX_304,
1624   IDX_400,
1625   IDX_404,
1626 };
1627
1628 HttpServer::HttpServer(const Config *config) : config_(config) {
1629   status_pages_ = std::vector<StatusPage>{
1630       {"200", make_status_body(200, config_->port)},
1631       {"301", make_status_body(301, config_->port)},
1632       {"304", make_status_body(304, config_->port)},
1633       {"400", make_status_body(400, config_->port)},
1634       {"404", make_status_body(404, config_->port)},
1635   };
1636 }
1637
1638 namespace {
1639 int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
1640                   void *arg) {
1641   auto next_proto = static_cast<std::vector<unsigned char> *>(arg);
1642   *data = next_proto->data();
1643   *len = next_proto->size();
1644   return SSL_TLSEXT_ERR_OK;
1645 }
1646 } // namespace
1647
1648 namespace {
1649 int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
1650   // We don't verify the client certificate. Just request it for the
1651   // testing purpose.
1652   return 1;
1653 }
1654 } // namespace
1655
1656 namespace {
1657 int start_listen(HttpServer *sv, struct ev_loop *loop, Sessions *sessions,
1658                  const Config *config) {
1659   addrinfo hints;
1660   int r;
1661   bool ok = false;
1662   const char *addr = nullptr;
1663
1664   auto acceptor = std::make_shared<AcceptHandler>(sv, sessions, config);
1665   auto service = util::utos(config->port);
1666
1667   memset(&hints, 0, sizeof(addrinfo));
1668   hints.ai_family = AF_UNSPEC;
1669   hints.ai_socktype = SOCK_STREAM;
1670   hints.ai_flags = AI_PASSIVE;
1671 #ifdef AI_ADDRCONFIG
1672   hints.ai_flags |= AI_ADDRCONFIG;
1673 #endif // AI_ADDRCONFIG
1674
1675   if (!config->address.empty()) {
1676     addr = config->address.c_str();
1677   }
1678
1679   addrinfo *res, *rp;
1680   r = getaddrinfo(addr, service.c_str(), &hints, &res);
1681   if (r != 0) {
1682     std::cerr << "getaddrinfo() failed: " << gai_strerror(r) << std::endl;
1683     return -1;
1684   }
1685
1686   for (rp = res; rp; rp = rp->ai_next) {
1687     int fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
1688     if (fd == -1) {
1689       continue;
1690     }
1691     int val = 1;
1692     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val,
1693                    static_cast<socklen_t>(sizeof(val))) == -1) {
1694       close(fd);
1695       continue;
1696     }
1697     (void)util::make_socket_nonblocking(fd);
1698 #ifdef IPV6_V6ONLY
1699     if (rp->ai_family == AF_INET6) {
1700       if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val,
1701                      static_cast<socklen_t>(sizeof(val))) == -1) {
1702         close(fd);
1703         continue;
1704       }
1705     }
1706 #endif // IPV6_V6ONLY
1707     if (bind(fd, rp->ai_addr, rp->ai_addrlen) == 0 && listen(fd, 1000) == 0) {
1708       new ListenEventHandler(sessions, fd, acceptor);
1709
1710       if (config->verbose) {
1711         std::string s = util::numeric_name(rp->ai_addr, rp->ai_addrlen);
1712         std::cout << (rp->ai_family == AF_INET ? "IPv4" : "IPv6") << ": listen "
1713                   << s << ":" << config->port << std::endl;
1714       }
1715       ok = true;
1716       continue;
1717     } else {
1718       std::cerr << strerror(errno) << std::endl;
1719     }
1720     close(fd);
1721   }
1722   freeaddrinfo(res);
1723
1724   if (!ok) {
1725     return -1;
1726   }
1727   return 0;
1728 }
1729 } // namespace
1730
1731 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1732 namespace {
1733 int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
1734                          unsigned char *outlen, const unsigned char *in,
1735                          unsigned int inlen, void *arg) {
1736   auto config = static_cast<HttpServer *>(arg)->get_config();
1737   if (config->verbose) {
1738     std::cout << "[ALPN] client offers:" << std::endl;
1739   }
1740   if (config->verbose) {
1741     for (unsigned int i = 0; i < inlen; i += in [i] + 1) {
1742       std::cout << " * ";
1743       std::cout.write(reinterpret_cast<const char *>(&in[i + 1]), in[i]);
1744       std::cout << std::endl;
1745     }
1746   }
1747   if (!util::select_h2(out, outlen, in, inlen)) {
1748     return SSL_TLSEXT_ERR_NOACK;
1749   }
1750   return SSL_TLSEXT_ERR_OK;
1751 }
1752 } // namespace
1753 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
1754
1755 int HttpServer::run() {
1756   SSL_CTX *ssl_ctx = nullptr;
1757   std::vector<unsigned char> next_proto;
1758
1759   if (!config_->no_tls) {
1760     ssl_ctx = SSL_CTX_new(SSLv23_server_method());
1761     if (!ssl_ctx) {
1762       std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
1763       return -1;
1764     }
1765
1766     SSL_CTX_set_options(ssl_ctx,
1767                         SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
1768                             SSL_OP_NO_COMPRESSION |
1769                             SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1770                             SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_TICKET |
1771                             SSL_OP_CIPHER_SERVER_PREFERENCE);
1772     SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
1773     SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
1774
1775     if (SSL_CTX_set_cipher_list(ssl_ctx, ssl::DEFAULT_CIPHER_LIST) == 0) {
1776       std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
1777       return -1;
1778     }
1779
1780     const unsigned char sid_ctx[] = "nghttpd";
1781     SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx) - 1);
1782     SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER);
1783
1784 #ifndef OPENSSL_NO_EC
1785
1786     // Disabled SSL_CTX_set_ecdh_auto, because computational cost of
1787     // chosen curve is much higher than P-256.
1788
1789     // #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1790     //     SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
1791     // #else // OPENSSL_VERSION_NUBMER < 0x10002000L
1792     // Use P-256, which is sufficiently secure at the time of this
1793     // writing.
1794     auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1795     if (ecdh == nullptr) {
1796       std::cerr << "EC_KEY_new_by_curv_name failed: "
1797                 << ERR_error_string(ERR_get_error(), nullptr);
1798       return -1;
1799     }
1800     SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
1801     EC_KEY_free(ecdh);
1802 // #endif // OPENSSL_VERSION_NUBMER < 0x10002000L
1803
1804 #endif // OPENSSL_NO_EC
1805
1806     if (!config_->dh_param_file.empty()) {
1807       // Read DH parameters from file
1808       auto bio = BIO_new_file(config_->dh_param_file.c_str(), "r");
1809       if (bio == nullptr) {
1810         std::cerr << "BIO_new_file() failed: "
1811                   << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
1812         return -1;
1813       }
1814
1815       auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
1816
1817       if (dh == nullptr) {
1818         std::cerr << "PEM_read_bio_DHparams() failed: "
1819                   << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
1820         return -1;
1821       }
1822
1823       SSL_CTX_set_tmp_dh(ssl_ctx, dh);
1824       DH_free(dh);
1825       BIO_free(bio);
1826     }
1827
1828     if (SSL_CTX_use_PrivateKey_file(ssl_ctx, config_->private_key_file.c_str(),
1829                                     SSL_FILETYPE_PEM) != 1) {
1830       std::cerr << "SSL_CTX_use_PrivateKey_file failed." << std::endl;
1831       return -1;
1832     }
1833     if (SSL_CTX_use_certificate_chain_file(ssl_ctx,
1834                                            config_->cert_file.c_str()) != 1) {
1835       std::cerr << "SSL_CTX_use_certificate_file failed." << std::endl;
1836       return -1;
1837     }
1838     if (SSL_CTX_check_private_key(ssl_ctx) != 1) {
1839       std::cerr << "SSL_CTX_check_private_key failed." << std::endl;
1840       return -1;
1841     }
1842     if (config_->verify_client) {
1843       SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE |
1844                                       SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1845                          verify_callback);
1846     }
1847
1848     next_proto = util::get_default_alpn();
1849
1850     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto);
1851 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
1852     // ALPN selection callback
1853     SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this);
1854 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
1855   }
1856
1857   auto loop = EV_DEFAULT;
1858
1859   Sessions sessions(this, loop, config_, ssl_ctx);
1860   if (start_listen(this, loop, &sessions, config_) != 0) {
1861     std::cerr << "Could not listen" << std::endl;
1862     return -1;
1863   }
1864
1865   ev_run(loop, 0);
1866   return 0;
1867 }
1868
1869 const Config *HttpServer::get_config() const { return config_; }
1870
1871 const StatusPage *HttpServer::get_status_page(int status) const {
1872   switch (status) {
1873   case 200:
1874     return &status_pages_[IDX_200];
1875   case 301:
1876     return &status_pages_[IDX_301];
1877   case 304:
1878     return &status_pages_[IDX_304];
1879   case 400:
1880     return &status_pages_[IDX_400];
1881   case 404:
1882     return &status_pages_[IDX_404];
1883   default:
1884     assert(0);
1885   }
1886   return nullptr;
1887 }
1888
1889 } // namespace nghttp2