tizen 2.4 release
[external/nghttp2.git] / src / shrpx_downstream.h
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 #ifndef SHRPX_DOWNSTREAM_H
26 #define SHRPX_DOWNSTREAM_H
27
28 #include "shrpx.h"
29
30 #include <stdint.h>
31
32 #include <vector>
33 #include <string>
34 #include <memory>
35 #include <chrono>
36
37 #include <ev.h>
38
39 #include <nghttp2/nghttp2.h>
40
41 #include "shrpx_io_control.h"
42 #include "http2.h"
43 #include "memchunk.h"
44
45 using namespace nghttp2;
46
47 namespace shrpx {
48
49 class Upstream;
50 class DownstreamConnection;
51
52 class Downstream {
53 public:
54   Downstream(Upstream *upstream, int32_t stream_id, int32_t priority);
55   ~Downstream();
56   void reset_upstream(Upstream *upstream);
57   Upstream *get_upstream() const;
58   void set_stream_id(int32_t stream_id);
59   int32_t get_stream_id() const;
60   void set_priority(int32_t pri);
61   int32_t get_priority() const;
62   void pause_read(IOCtrlReason reason);
63   int resume_read(IOCtrlReason reason, size_t consumed);
64   void force_resume_read();
65   // Set stream ID for downstream HTTP2 connection.
66   void set_downstream_stream_id(int32_t stream_id);
67   int32_t get_downstream_stream_id() const;
68
69   int attach_downstream_connection(std::unique_ptr<DownstreamConnection> dconn);
70   void detach_downstream_connection();
71   // Releases dconn_, without freeing it.
72   void release_downstream_connection();
73   DownstreamConnection *get_downstream_connection();
74   // Returns dconn_ and nullifies dconn_.
75   std::unique_ptr<DownstreamConnection> pop_downstream_connection();
76
77   // Returns true if output buffer is full. If underlying dconn_ is
78   // NULL, this function always returns false.
79   bool request_buf_full();
80   // Returns true if upgrade (HTTP Upgrade or CONNECT) is succeeded.
81   void check_upgrade_fulfilled();
82   // Returns true if the request is upgrade.
83   bool get_upgrade_request() const;
84   // Returns true if the upgrade is succeded as a result of the call
85   // check_upgrade_fulfilled().
86   bool get_upgraded() const;
87   // Inspects HTTP/2 request.
88   void inspect_http2_request();
89   // Inspects HTTP/1 request.  This checks whether the request is
90   // upgrade request and tranfer-encoding etc.
91   void inspect_http1_request();
92   // Returns true if the request is HTTP Upgrade for HTTP/2
93   bool get_http2_upgrade_request() const;
94   // Returns the value of HTTP2-Settings request header field.
95   const std::string &get_http2_settings() const;
96   // downstream request API
97   const Headers &get_request_headers() const;
98   // Crumbles (split cookie by ";") in request_headers_ and returns
99   // them.  Headers::no_index is inherited.
100   Headers crumble_request_cookie();
101   void assemble_request_cookie();
102   const std::string &get_assembled_request_cookie() const;
103   // Lower the request header field names and indexes request headers.
104   // If there is any invalid headers (e.g., multiple Content-Length
105   // having different values), returns -1.
106   int index_request_headers();
107   // Returns pointer to the request header with the name |name|.  If
108   // multiple header have |name| as name, return last occurrence from
109   // the beginning.  If no such header is found, returns nullptr.
110   // This function must be called after headers are indexed
111   const Headers::value_type *get_request_header(int16_t token) const;
112   // Returns pointer to the request header with the name |name|.  If
113   // no such header is found, returns nullptr.
114   const Headers::value_type *get_request_header(const std::string &name) const;
115   void add_request_header(std::string name, std::string value);
116   void set_last_request_header_value(std::string value);
117
118   void add_request_header(const uint8_t *name, size_t namelen,
119                           const uint8_t *value, size_t valuelen, bool no_index,
120                           int16_t token);
121
122   bool get_request_header_key_prev() const;
123   void append_last_request_header_key(const char *data, size_t len);
124   void append_last_request_header_value(const char *data, size_t len);
125   // Empties request headers.
126   void clear_request_headers();
127
128   size_t get_request_headers_sum() const;
129
130   void set_request_method(std::string method);
131   const std::string &get_request_method() const;
132   void set_request_path(std::string path);
133   void
134   set_request_start_time(std::chrono::high_resolution_clock::time_point time);
135   const std::chrono::high_resolution_clock::time_point &
136   get_request_start_time() const;
137   void append_request_path(const char *data, size_t len);
138   // Returns request path. For HTTP/1.1, this is request-target. For
139   // HTTP/2, this is :path header field value.
140   const std::string &get_request_path() const;
141   // Returns HTTP/2 :scheme header field value.
142   const std::string &get_request_http2_scheme() const;
143   void set_request_http2_scheme(std::string scheme);
144   // Returns HTTP/2 :authority header field value.
145   const std::string &get_request_http2_authority() const;
146   void set_request_http2_authority(std::string authority);
147   void set_request_major(int major);
148   void set_request_minor(int minor);
149   int get_request_major() const;
150   int get_request_minor() const;
151   int push_request_headers();
152   bool get_chunked_request() const;
153   void set_chunked_request(bool f);
154   bool get_request_connection_close() const;
155   void set_request_connection_close(bool f);
156   bool get_request_http2_expect_body() const;
157   void set_request_http2_expect_body(bool f);
158   int push_upload_data_chunk(const uint8_t *data, size_t datalen);
159   int end_upload_data();
160   size_t get_request_datalen() const;
161   void dec_request_datalen(size_t len);
162   void reset_request_datalen();
163   // Validates that received request body length and content-length
164   // matches.
165   bool validate_request_bodylen() const;
166   int64_t get_request_content_length() const;
167   void set_request_content_length(int64_t len);
168   bool request_pseudo_header_allowed(int16_t token) const;
169   void set_request_downstream_host(std::string host);
170   bool expect_response_body() const;
171   enum {
172     INITIAL,
173     HEADER_COMPLETE,
174     MSG_COMPLETE,
175     STREAM_CLOSED,
176     CONNECT_FAIL,
177     IDLE,
178     MSG_RESET,
179     // header contains invalid header field.  We can safely send error
180     // response (502) to a client.
181     MSG_BAD_HEADER,
182   };
183   void set_request_state(int state);
184   int get_request_state() const;
185   DefaultMemchunks *get_request_buf();
186   // downstream response API
187   const Headers &get_response_headers() const;
188   // Lower the response header field names and indexes response
189   // headers.  If there are invalid headers (e.g., multiple
190   // Content-Length with different values), returns -1.
191   int index_response_headers();
192   // Returns pointer to the response header with the name |name|.  If
193   // multiple header have |name| as name, return last occurrence from
194   // the beginning.  If no such header is found, returns nullptr.
195   // This function must be called after response headers are indexed.
196   const Headers::value_type *get_response_header(int16_t token) const;
197   // Rewrites the location response header field.
198   void rewrite_location_response_header(const std::string &upstream_scheme);
199   void add_response_header(std::string name, std::string value);
200   void set_last_response_header_value(std::string value);
201
202   void add_response_header(std::string name, std::string value, int16_t token);
203   void add_response_header(const uint8_t *name, size_t namelen,
204                            const uint8_t *value, size_t valuelen, bool no_index,
205                            int16_t token);
206
207   bool get_response_header_key_prev() const;
208   void append_last_response_header_key(const char *data, size_t len);
209   void append_last_response_header_value(const char *data, size_t len);
210   // Empties response headers.
211   void clear_response_headers();
212
213   size_t get_response_headers_sum() const;
214
215   unsigned int get_response_http_status() const;
216   void set_response_http_status(unsigned int status);
217   void set_response_major(int major);
218   void set_response_minor(int minor);
219   int get_response_major() const;
220   int get_response_minor() const;
221   int get_response_version() const;
222   bool get_chunked_response() const;
223   void set_chunked_response(bool f);
224   bool get_response_connection_close() const;
225   void set_response_connection_close(bool f);
226   void set_response_state(int state);
227   int get_response_state() const;
228   DefaultMemchunks *get_response_buf();
229   bool response_buf_full();
230   void add_response_bodylen(size_t amount);
231   int64_t get_response_bodylen() const;
232   void add_response_sent_bodylen(size_t amount);
233   int64_t get_response_sent_bodylen() const;
234   int64_t get_response_content_length() const;
235   void set_response_content_length(int64_t len);
236   // Validates that received response body length and content-length
237   // matches.
238   bool validate_response_bodylen() const;
239   uint32_t get_response_rst_stream_error_code() const;
240   void set_response_rst_stream_error_code(uint32_t error_code);
241   // Inspects HTTP/1 response.  This checks tranfer-encoding etc.
242   void inspect_http1_response();
243   // Clears some of member variables for response.
244   void reset_response();
245   bool get_non_final_response() const;
246   void set_expect_final_response(bool f);
247   bool get_expect_final_response() const;
248   void add_response_datalen(size_t len);
249   void dec_response_datalen(size_t len);
250   size_t get_response_datalen() const;
251   void reset_response_datalen();
252   bool response_pseudo_header_allowed(int16_t token) const;
253
254   // Call this method when there is incoming data in downstream
255   // connection.
256   int on_read();
257
258   // Change the priority of downstream
259   int change_priority(int32_t pri);
260
261   // Maximum buffer size for header name/value pairs.
262   static const size_t MAX_HEADERS_SUM = 32768;
263
264   bool get_rst_stream_after_end_stream() const;
265   void set_rst_stream_after_end_stream(bool f);
266
267   // Resets upstream read timer.  If it is active, timeout value is
268   // reset.  If it is not active, timer will be started.
269   void reset_upstream_rtimer();
270   // Resets upstream write timer. If it is active, timeout value is
271   // reset.  If it is not active, timer will be started.  This
272   // function also resets read timer if it has been started.
273   void reset_upstream_wtimer();
274   // Makes sure that upstream write timer is started.  If it has been
275   // started, do nothing.  Otherwise, write timer will be started.
276   void ensure_upstream_wtimer();
277   // Disables upstream read timer.
278   void disable_upstream_rtimer();
279   // Disables upstream write timer.
280   void disable_upstream_wtimer();
281
282   // Downstream timer functions.  They works in a similar way just
283   // like the upstream timer function.
284   void reset_downstream_rtimer();
285   void reset_downstream_wtimer();
286   void ensure_downstream_wtimer();
287   void disable_downstream_rtimer();
288   void disable_downstream_wtimer();
289
290   // Returns true if accesslog can be written for this downstream.
291   bool accesslog_ready() const;
292
293   // Increment retry count
294   void add_retry();
295   // true if retry attempt should not be done.
296   bool no_more_retry() const;
297
298   enum {
299     EVENT_ERROR = 0x1,
300     EVENT_TIMEOUT = 0x2,
301   };
302
303 private:
304   Headers request_headers_;
305   Headers response_headers_;
306
307   std::chrono::high_resolution_clock::time_point request_start_time_;
308
309   std::string request_method_;
310   std::string request_path_;
311   std::string request_http2_scheme_;
312   std::string request_http2_authority_;
313   // host we requested to downstream.  This is used to rewrite
314   // location header field to decide the location should be rewritten
315   // or not.
316   std::string request_downstream_host_;
317   std::string assembled_request_cookie_;
318
319   DefaultMemchunks request_buf_;
320   DefaultMemchunks response_buf_;
321
322   ev_timer upstream_rtimer_;
323   ev_timer upstream_wtimer_;
324
325   ev_timer downstream_rtimer_;
326   ev_timer downstream_wtimer_;
327
328   // the length of request body received so far
329   int64_t request_bodylen_;
330   // the length of response body received so far
331   int64_t response_bodylen_;
332
333   // the length of response body sent to upstream client
334   int64_t response_sent_bodylen_;
335
336   // content-length of request body, -1 if it is unknown.
337   int64_t request_content_length_;
338   // content-length of response body, -1 if it is unknown.
339   int64_t response_content_length_;
340
341   Upstream *upstream_;
342   std::unique_ptr<DownstreamConnection> dconn_;
343
344   size_t request_headers_sum_;
345   size_t response_headers_sum_;
346
347   // The number of bytes not consumed by the application yet.
348   size_t request_datalen_;
349   size_t response_datalen_;
350
351   size_t num_retry_;
352
353   int32_t stream_id_;
354   int32_t priority_;
355   // stream ID in backend connection
356   int32_t downstream_stream_id_;
357
358   // RST_STREAM error_code from downstream HTTP2 connection
359   uint32_t response_rst_stream_error_code_;
360
361   int request_state_;
362   int request_major_;
363   int request_minor_;
364
365   int response_state_;
366   unsigned int response_http_status_;
367   int response_major_;
368   int response_minor_;
369
370   http2::HeaderIndex request_hdidx_;
371   http2::HeaderIndex response_hdidx_;
372
373   // true if the request contains upgrade token (HTTP Upgrade or
374   // CONNECT)
375   bool upgrade_request_;
376   // true if the connection is upgraded (HTTP Upgrade or CONNECT)
377   bool upgraded_;
378
379   bool http2_upgrade_seen_;
380
381   bool chunked_request_;
382   bool request_connection_close_;
383   bool request_header_key_prev_;
384   bool request_http2_expect_body_;
385
386   bool chunked_response_;
387   bool response_connection_close_;
388   bool response_header_key_prev_;
389   bool expect_final_response_;
390 };
391
392 } // namespace shrpx
393
394 #endif // SHRPX_DOWNSTREAM_H