Imported Upstream version 1.0.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
49 namespace nghttp2 {
50
51 struct Config {
52   std::map<std::string, std::vector<std::string>> push;
53   Headers trailer;
54   std::string htdocs;
55   std::string host;
56   std::string private_key_file;
57   std::string cert_file;
58   std::string dh_param_file;
59   std::string address;
60   ev_tstamp stream_read_timeout;
61   ev_tstamp stream_write_timeout;
62   void *data_ptr;
63   size_t padding;
64   size_t num_worker;
65   size_t max_concurrent_streams;
66   ssize_t header_table_size;
67   uint16_t port;
68   bool verbose;
69   bool daemon;
70   bool verify_client;
71   bool no_tls;
72   bool error_gzip;
73   bool early_response;
74   bool hexdump;
75   bool echo_upload;
76   Config();
77   ~Config();
78 };
79
80 class Http2Handler;
81
82 struct FileEntry {
83   FileEntry(std::string path, int64_t length, int64_t mtime, int fd)
84       : path(std::move(path)), length(length), mtime(mtime), dlprev(nullptr),
85         dlnext(nullptr), fd(fd), usecount(1) {}
86   std::string path;
87   int64_t length;
88   int64_t mtime;
89   FileEntry *dlprev, *dlnext;
90   int fd;
91   int usecount;
92 };
93
94 struct Stream {
95   Headers headers;
96   Http2Handler *handler;
97   FileEntry *file_ent;
98   ev_timer rtimer;
99   ev_timer wtimer;
100   int64_t body_length;
101   int64_t body_offset;
102   int32_t stream_id;
103   http2::HeaderIndex hdidx;
104   bool echo_upload;
105   Stream(Http2Handler *handler, int32_t stream_id);
106   ~Stream();
107 };
108
109 class Sessions;
110
111 class Http2Handler {
112 public:
113   Http2Handler(Sessions *sessions, int fd, SSL *ssl, int64_t session_id);
114   ~Http2Handler();
115
116   void remove_self();
117   int setup_bev();
118   int on_read();
119   int on_write();
120   int connection_made();
121   int verify_npn_result();
122
123   int submit_file_response(const std::string &status, Stream *stream,
124                            time_t last_modified, off_t file_length,
125                            nghttp2_data_provider *data_prd);
126
127   int submit_response(const std::string &status, int32_t stream_id,
128                       nghttp2_data_provider *data_prd);
129
130   int submit_response(const std::string &status, int32_t stream_id,
131                       const Headers &headers, nghttp2_data_provider *data_prd);
132
133   int submit_non_final_response(const std::string &status, int32_t stream_id);
134
135   int submit_push_promise(Stream *stream, const std::string &push_path);
136
137   int submit_rst_stream(Stream *stream, uint32_t error_code);
138
139   void add_stream(int32_t stream_id, std::unique_ptr<Stream> stream);
140   void remove_stream(int32_t stream_id);
141   Stream *get_stream(int32_t stream_id);
142   int64_t session_id() const;
143   Sessions *get_sessions() const;
144   const Config *get_config() const;
145   void remove_settings_timer();
146   void terminate_session(uint32_t error_code);
147
148   int fill_wb();
149
150   int read_clear();
151   int write_clear();
152   int tls_handshake();
153   int read_tls();
154   int write_tls();
155
156   struct ev_loop *get_loop() const;
157
158   using WriteBuf = Buffer<65536>;
159
160   WriteBuf *get_wb();
161
162 private:
163   ev_io wev_;
164   ev_io rev_;
165   ev_timer settings_timerev_;
166   std::map<int32_t, std::unique_ptr<Stream>> id2stream_;
167   WriteBuf wb_;
168   std::function<int(Http2Handler &)> read_, write_;
169   int64_t session_id_;
170   nghttp2_session *session_;
171   Sessions *sessions_;
172   SSL *ssl_;
173   const uint8_t *data_pending_;
174   size_t data_pendinglen_;
175   int fd_;
176 };
177
178 struct StatusPage {
179   std::string status;
180   FileEntry file_ent;
181 };
182
183 class HttpServer {
184 public:
185   HttpServer(const Config *config);
186   int listen();
187   int run();
188   const Config *get_config() const;
189   const StatusPage *get_status_page(int status) const;
190
191 private:
192   std::vector<StatusPage> status_pages_;
193   const Config *config_;
194 };
195
196 ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
197                            uint8_t *buf, size_t length, int *eof,
198                            nghttp2_data_source *source, void *user_data);
199
200 } // namespace nghttp2
201
202 #endif // HTTP_SERVER_H