Imported Upstream version 1.0.0
[platform/upstream/nghttp2.git] / src / nghttp.h
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2015 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 NGHTTP_H
26 #define NGHTTP_H
27
28 #include "nghttp2_config.h"
29
30 #include <sys/types.h>
31 #ifdef HAVE_SYS_SOCKET_H
32 #include <sys/socket.h>
33 #endif // HAVE_SYS_SOCKET_H
34 #ifdef HAVE_NETDB_H
35 #include <netdb.h>
36 #endif // HAVE_NETDB_H
37
38 #include <string>
39 #include <vector>
40 #include <set>
41 #include <chrono>
42 #include <memory>
43
44 #include <openssl/ssl.h>
45
46 #include <ev.h>
47
48 #include <nghttp2/nghttp2.h>
49
50 #include "http-parser/http_parser.h"
51
52 #include "buffer.h"
53 #include "http2.h"
54 #include "nghttp2_gzip.h"
55
56 namespace nghttp2 {
57
58 class HtmlParser;
59
60 struct Config {
61   Config();
62   ~Config();
63
64   Headers headers;
65   Headers trailer;
66   std::string certfile;
67   std::string keyfile;
68   std::string datafile;
69   std::string harfile;
70   nghttp2_option *http2_option;
71   size_t output_upper_thres;
72   size_t padding;
73   ssize_t peer_max_concurrent_streams;
74   ssize_t header_table_size;
75   int32_t weight;
76   int multiply;
77   // milliseconds
78   ev_tstamp timeout;
79   int window_bits;
80   int connection_window_bits;
81   int verbose;
82   bool null_out;
83   bool remote_name;
84   bool get_assets;
85   bool stat;
86   bool upgrade;
87   bool continuation;
88   bool no_content_length;
89   bool no_dep;
90   bool hexdump;
91   bool no_push;
92 };
93
94 enum class RequestState { INITIAL, ON_REQUEST, ON_RESPONSE, ON_COMPLETE };
95
96 struct RequestTiming {
97   // The point in time when request is started to be sent.
98   // Corresponds to requestStart in Resource Timing TR.
99   std::chrono::steady_clock::time_point request_start_time;
100   // The point in time when first byte of response is received.
101   // Corresponds to responseStart in Resource Timing TR.
102   std::chrono::steady_clock::time_point response_start_time;
103   // The point in time when last byte of response is received.
104   // Corresponds to responseEnd in Resource Timing TR.
105   std::chrono::steady_clock::time_point response_end_time;
106   RequestState state;
107   RequestTiming() : state(RequestState::INITIAL) {}
108 };
109
110 struct Request {
111   // For pushed request, |uri| is empty and |u| is zero-cleared.
112   Request(const std::string &uri, const http_parser_url &u,
113           const nghttp2_data_provider *data_prd, int64_t data_length,
114           const nghttp2_priority_spec &pri_spec, int level = 0);
115   ~Request();
116
117   void init_inflater();
118
119   void init_html_parser();
120   int update_html_parser(const uint8_t *data, size_t len, int fin);
121
122   std::string make_reqpath() const;
123
124   bool is_ipv6_literal_addr() const;
125
126   bool response_pseudo_header_allowed(int16_t token) const;
127   bool push_request_pseudo_header_allowed(int16_t token) const;
128
129   Headers::value_type *get_res_header(int16_t token);
130   Headers::value_type *get_req_header(int16_t token);
131
132   void record_request_start_time();
133   void record_response_start_time();
134   void record_response_end_time();
135
136   Headers res_nva;
137   Headers req_nva;
138   // URI without fragment
139   std::string uri;
140   http_parser_url u;
141   nghttp2_priority_spec pri_spec;
142   RequestTiming timing;
143   int64_t data_length;
144   int64_t data_offset;
145   // Number of bytes received from server
146   int64_t response_len;
147   nghttp2_gzip *inflater;
148   HtmlParser *html_parser;
149   const nghttp2_data_provider *data_prd;
150   int32_t stream_id;
151   int status;
152   // Recursion level: 0: first entity, 1: entity linked from first entity
153   int level;
154   http2::HeaderIndex res_hdidx;
155   // used for incoming PUSH_PROMISE
156   http2::HeaderIndex req_hdidx;
157   bool expect_final_response;
158 };
159
160 struct SessionTiming {
161   // The point in time when operation was started.  Corresponds to
162   // startTime in Resource Timing TR, but recorded in system clock time.
163   std::chrono::system_clock::time_point system_start_time;
164   // Same as above, but recorded in steady clock time.
165   std::chrono::steady_clock::time_point start_time;
166   // The point in time when DNS resolution was completed.  Corresponds
167   // to domainLookupEnd in Resource Timing TR.
168   std::chrono::steady_clock::time_point domain_lookup_end_time;
169   // The point in time when connection was established or SSL/TLS
170   // handshake was completed.  Corresponds to connectEnd in Resource
171   // Timing TR.
172   std::chrono::steady_clock::time_point connect_end_time;
173 };
174
175 enum class ClientState { IDLE, CONNECTED };
176
177 struct HttpClient {
178   HttpClient(const nghttp2_session_callbacks *callbacks, struct ev_loop *loop,
179              SSL_CTX *ssl_ctx);
180   ~HttpClient();
181
182   bool need_upgrade() const;
183   int resolve_host(const std::string &host, uint16_t port);
184   int initiate_connection();
185   void disconnect();
186
187   int noop();
188   int read_clear();
189   int write_clear();
190   int connected();
191   int tls_handshake();
192   int read_tls();
193   int write_tls();
194
195   int do_read();
196   int do_write();
197
198   int on_upgrade_connect();
199   int on_upgrade_read(const uint8_t *data, size_t len);
200   int on_read(const uint8_t *data, size_t len);
201   int on_write();
202
203   int connection_made();
204   void connect_fail();
205   void request_done(Request *req);
206
207   void signal_write();
208
209   bool all_requests_processed() const;
210   void update_hostport();
211   bool add_request(const std::string &uri,
212                    const nghttp2_data_provider *data_prd, int64_t data_length,
213                    const nghttp2_priority_spec &pri_spec, int level = 0);
214
215   void record_start_time();
216   void record_domain_lookup_end_time();
217   void record_connect_end_time();
218
219 #ifdef HAVE_JANSSON
220   void output_har(FILE *outfile);
221 #endif // HAVE_JANSSON
222
223   std::vector<std::unique_ptr<Request>> reqvec;
224   // Insert path already added in reqvec to prevent multiple request
225   // for 1 resource.
226   std::set<std::string> path_cache;
227   std::string scheme;
228   std::string host;
229   std::string hostport;
230   // Used for parse the HTTP upgrade response from server
231   std::unique_ptr<http_parser> htp;
232   SessionTiming timing;
233   ev_io wev;
234   ev_io rev;
235   ev_timer wt;
236   ev_timer rt;
237   ev_timer settings_timer;
238   std::function<int(HttpClient &)> readfn, writefn;
239   std::function<int(HttpClient &, const uint8_t *, size_t)> on_readfn;
240   std::function<int(HttpClient &)> on_writefn;
241   nghttp2_session *session;
242   const nghttp2_session_callbacks *callbacks;
243   struct ev_loop *loop;
244   SSL_CTX *ssl_ctx;
245   SSL *ssl;
246   addrinfo *addrs;
247   addrinfo *next_addr;
248   addrinfo *cur_addr;
249   // The number of completed requests, including failed ones.
250   size_t complete;
251   // The number of requests that local endpoint received END_STREAM
252   // from peer.
253   size_t success;
254   // The length of settings_payload
255   size_t settings_payloadlen;
256   ClientState state;
257   // The HTTP status code of the response message of HTTP Upgrade.
258   unsigned int upgrade_response_status_code;
259   int fd;
260   // true if the response message of HTTP Upgrade request is fully
261   // received. It is not relevant the upgrade succeeds, or not.
262   bool upgrade_response_complete;
263   Buffer<65536> wb;
264   // SETTINGS payload sent as token68 in HTTP Upgrade
265   std::array<uint8_t, 128> settings_payload;
266
267   enum { ERR_CONNECT_FAIL = -100 };
268 };
269
270 } // namespace nghttp2
271
272 #endif // NGHTTP_H