Imported Upstream version 1.46.0
[platform/upstream/nghttp2.git] / src / HttpServer.h
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 #ifndef HTTP_SERVER_H
26 #define HTTP_SERVER_H
27
28 #include "nghttp2_config.h"
29
30 #include <sys/types.h>
31
32 #include <cinttypes>
33 #include <cstdlib>
34
35 #include <string>
36 #include <vector>
37 #include <map>
38 #include <memory>
39
40 #include <openssl/ssl.h>
41
42 #include <ev.h>
43
44 #include <nghttp2/nghttp2.h>
45
46 #include "http2.h"
47 #include "buffer.h"
48 #include "template.h"
49 #include "allocator.h"
50
51 namespace nghttp2 {
52
53 struct Config {
54   std::map<std::string, std::vector<std::string>> push;
55   std::map<std::string, std::string> mime_types;
56   Headers trailer;
57   std::string trailer_names;
58   std::string htdocs;
59   std::string host;
60   std::string private_key_file;
61   std::string cert_file;
62   std::string dh_param_file;
63   std::string address;
64   std::string mime_types_file;
65   ev_tstamp stream_read_timeout;
66   ev_tstamp stream_write_timeout;
67   void *data_ptr;
68   size_t padding;
69   size_t num_worker;
70   size_t max_concurrent_streams;
71   ssize_t header_table_size;
72   ssize_t encoder_header_table_size;
73   int window_bits;
74   int connection_window_bits;
75   uint16_t port;
76   bool verbose;
77   bool daemon;
78   bool verify_client;
79   bool no_tls;
80   bool error_gzip;
81   bool early_response;
82   bool hexdump;
83   bool echo_upload;
84   bool no_content_length;
85   Config();
86   ~Config();
87 };
88
89 class Http2Handler;
90
91 struct FileEntry {
92   FileEntry(std::string path, int64_t length, int64_t mtime, int fd,
93             const std::string *content_type, ev_tstamp last_valid,
94             bool stale = false)
95       : path(std::move(path)),
96         length(length),
97         mtime(mtime),
98         last_valid(last_valid),
99         content_type(content_type),
100         dlnext(nullptr),
101         dlprev(nullptr),
102         fd(fd),
103         usecount(1),
104         stale(stale) {}
105   std::string path;
106   std::multimap<std::string, std::unique_ptr<FileEntry>>::iterator it;
107   int64_t length;
108   int64_t mtime;
109   ev_tstamp last_valid;
110   const std::string *content_type;
111   FileEntry *dlnext, *dlprev;
112   int fd;
113   int usecount;
114   bool stale;
115 };
116
117 struct RequestHeader {
118   StringRef method;
119   StringRef scheme;
120   StringRef authority;
121   StringRef host;
122   StringRef path;
123   StringRef ims;
124   StringRef expect;
125
126   struct {
127     nghttp2_rcbuf *method;
128     nghttp2_rcbuf *scheme;
129     nghttp2_rcbuf *authority;
130     nghttp2_rcbuf *host;
131     nghttp2_rcbuf *path;
132     nghttp2_rcbuf *ims;
133     nghttp2_rcbuf *expect;
134   } rcbuf;
135 };
136
137 struct Stream {
138   BlockAllocator balloc;
139   RequestHeader header;
140   Http2Handler *handler;
141   FileEntry *file_ent;
142   ev_timer rtimer;
143   ev_timer wtimer;
144   int64_t body_length;
145   int64_t body_offset;
146   // Total amount of bytes (sum of name and value length) used in
147   // headers.
148   size_t header_buffer_size;
149   int32_t stream_id;
150   bool echo_upload;
151   Stream(Http2Handler *handler, int32_t stream_id);
152   ~Stream();
153 };
154
155 class Sessions;
156
157 class Http2Handler {
158 public:
159   Http2Handler(Sessions *sessions, int fd, SSL *ssl, int64_t session_id);
160   ~Http2Handler();
161
162   void remove_self();
163   void start_settings_timer();
164   int on_read();
165   int on_write();
166   int connection_made();
167   int verify_npn_result();
168
169   int submit_file_response(const StringRef &status, Stream *stream,
170                            time_t last_modified, off_t file_length,
171                            const std::string *content_type,
172                            nghttp2_data_provider *data_prd);
173
174   int submit_response(const StringRef &status, int32_t stream_id,
175                       nghttp2_data_provider *data_prd);
176
177   int submit_response(const StringRef &status, int32_t stream_id,
178                       const HeaderRefs &headers,
179                       nghttp2_data_provider *data_prd);
180
181   int submit_non_final_response(const std::string &status, int32_t stream_id);
182
183   int submit_push_promise(Stream *stream, const StringRef &push_path);
184
185   int submit_rst_stream(Stream *stream, uint32_t error_code);
186
187   void add_stream(int32_t stream_id, std::unique_ptr<Stream> stream);
188   void remove_stream(int32_t stream_id);
189   Stream *get_stream(int32_t stream_id);
190   int64_t session_id() const;
191   Sessions *get_sessions() const;
192   const Config *get_config() const;
193   void remove_settings_timer();
194   void terminate_session(uint32_t error_code);
195
196   int fill_wb();
197
198   int read_clear();
199   int write_clear();
200   int tls_handshake();
201   int read_tls();
202   int write_tls();
203
204   struct ev_loop *get_loop() const;
205
206   using WriteBuf = Buffer<64_k>;
207
208   WriteBuf *get_wb();
209
210 private:
211   ev_io wev_;
212   ev_io rev_;
213   ev_timer settings_timerev_;
214   std::map<int32_t, std::unique_ptr<Stream>> id2stream_;
215   WriteBuf wb_;
216   std::function<int(Http2Handler &)> read_, write_;
217   int64_t session_id_;
218   nghttp2_session *session_;
219   Sessions *sessions_;
220   SSL *ssl_;
221   const uint8_t *data_pending_;
222   size_t data_pendinglen_;
223   int fd_;
224 };
225
226 struct StatusPage {
227   std::string status;
228   FileEntry file_ent;
229 };
230
231 class HttpServer {
232 public:
233   HttpServer(const Config *config);
234   int listen();
235   int run();
236   const Config *get_config() const;
237   const StatusPage *get_status_page(int status) const;
238
239 private:
240   std::vector<StatusPage> status_pages_;
241   const Config *config_;
242 };
243
244 ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
245                            uint8_t *buf, size_t length, uint32_t *data_flags,
246                            nghttp2_data_source *source, void *user_data);
247
248 } // namespace nghttp2
249
250 #endif // HTTP_SERVER_H