2012-11-20 17:29:39 +01:00
|
|
|
/*
|
2014-03-30 12:09:21 +02:00
|
|
|
* nghttp2 - HTTP/2 C Library
|
2012-11-20 17:29:39 +01:00
|
|
|
*
|
|
|
|
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
2013-11-04 09:53:57 +01:00
|
|
|
#ifndef SHRPX_HTTP2_SESSION_H
|
|
|
|
#define SHRPX_HTTP2_SESSION_H
|
2012-11-20 17:29:39 +01:00
|
|
|
|
|
|
|
#include "shrpx.h"
|
|
|
|
|
|
|
|
#include <set>
|
2013-09-23 17:19:53 +02:00
|
|
|
#include <memory>
|
2012-11-20 17:29:39 +01:00
|
|
|
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
|
|
|
#include <event.h>
|
|
|
|
#include <event2/bufferevent.h>
|
|
|
|
|
2013-07-12 17:19:03 +02:00
|
|
|
#include <nghttp2/nghttp2.h>
|
2012-11-20 17:29:39 +01:00
|
|
|
|
2013-02-09 08:42:01 +01:00
|
|
|
#include "http-parser/http_parser.h"
|
|
|
|
|
2012-11-20 17:29:39 +01:00
|
|
|
namespace shrpx {
|
|
|
|
|
2013-11-04 09:53:57 +01:00
|
|
|
class Http2DownstreamConnection;
|
2012-11-20 17:29:39 +01:00
|
|
|
|
|
|
|
struct StreamData {
|
2013-11-04 09:53:57 +01:00
|
|
|
Http2DownstreamConnection *dconn;
|
2012-11-20 17:29:39 +01:00
|
|
|
};
|
|
|
|
|
2013-11-04 09:53:57 +01:00
|
|
|
class Http2Session {
|
2012-11-20 17:29:39 +01:00
|
|
|
public:
|
2013-11-04 09:53:57 +01:00
|
|
|
Http2Session(event_base *evbase, SSL_CTX *ssl_ctx);
|
|
|
|
~Http2Session();
|
2012-11-20 17:29:39 +01:00
|
|
|
|
|
|
|
int init_notification();
|
|
|
|
|
2012-11-22 13:46:15 +01:00
|
|
|
int check_cert();
|
|
|
|
|
2012-11-20 17:29:39 +01:00
|
|
|
int disconnect();
|
|
|
|
int initiate_connection();
|
|
|
|
|
2013-11-04 09:53:57 +01:00
|
|
|
void add_downstream_connection(Http2DownstreamConnection *dconn);
|
|
|
|
void remove_downstream_connection(Http2DownstreamConnection *dconn);
|
2012-11-20 17:29:39 +01:00
|
|
|
|
|
|
|
void remove_stream_data(StreamData *sd);
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
int submit_request(Http2DownstreamConnection *dconn, int32_t pri,
|
|
|
|
const nghttp2_nv *nva, size_t nvlen,
|
2013-07-12 17:19:03 +02:00
|
|
|
const nghttp2_data_provider *data_prd);
|
2012-11-20 17:29:39 +01:00
|
|
|
|
2014-08-23 10:34:56 +02:00
|
|
|
int submit_rst_stream(int32_t stream_id, uint32_t error_code);
|
2012-11-20 17:29:39 +01:00
|
|
|
|
2014-01-18 08:12:03 +01:00
|
|
|
int submit_priority(Http2DownstreamConnection *dconn, int32_t pri);
|
|
|
|
|
2014-08-23 10:34:56 +02:00
|
|
|
int terminate_session(uint32_t error_code);
|
2013-10-31 13:45:17 +01:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
nghttp2_session *get_session() const;
|
2013-10-29 16:07:35 +01:00
|
|
|
|
2012-11-21 15:47:48 +01:00
|
|
|
bool get_flow_control() const;
|
|
|
|
|
2013-11-04 09:53:57 +01:00
|
|
|
int resume_data(Http2DownstreamConnection *dconn);
|
2012-11-20 17:29:39 +01:00
|
|
|
|
|
|
|
int on_connect();
|
|
|
|
|
|
|
|
int on_read();
|
|
|
|
int on_write();
|
|
|
|
int send();
|
|
|
|
|
2013-02-09 08:42:01 +01:00
|
|
|
int on_read_proxy();
|
|
|
|
|
2012-11-20 17:29:39 +01:00
|
|
|
void clear_notify();
|
|
|
|
void notify();
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
bufferevent *get_bev() const;
|
2013-02-22 11:26:41 +01:00
|
|
|
void unwrap_free_bev();
|
2012-11-20 17:29:39 +01:00
|
|
|
|
|
|
|
int get_state() const;
|
2013-02-09 08:42:01 +01:00
|
|
|
void set_state(int state);
|
2012-11-20 17:29:39 +01:00
|
|
|
|
2013-10-31 13:45:17 +01:00
|
|
|
int start_settings_timer();
|
|
|
|
void stop_settings_timer();
|
|
|
|
|
2014-01-19 10:07:50 +01:00
|
|
|
size_t get_outbuf_length() const;
|
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
SSL *get_ssl() const;
|
2014-04-26 16:00:58 +02:00
|
|
|
|
2014-07-25 14:26:03 +02:00
|
|
|
int consume(int32_t stream_id, size_t len);
|
2014-07-02 16:20:45 +02:00
|
|
|
|
2014-09-18 16:19:28 +02:00
|
|
|
void reset_timeouts();
|
|
|
|
|
nghttpx: Check HTTP/2 downstream connection after certain idle time
Previously when requests are issued to HTTP/2 downstream connection,
but it turns out that connection is down, handlers of those requests
are deleted. In some situations, we only know connection is down when
we write something to network, so we'd like to handle this kind of
situation in more robust manner. In this change, certain seconds
passed after last network activity, we first issue PING frame to
downstream connection before issuing new HTTP request. If writing
PING frame is failed, it means connection was lost. In this case,
instead of deleting handler, pending requests are migrated to new
HTTP2/ downstream connection, so that it can continue without
affecting upstream connection.
2014-12-08 17:30:15 +01:00
|
|
|
// Returns true if request can be issued on downstream connection.
|
|
|
|
bool can_push_request() const;
|
|
|
|
// Initiates the connection checking if downstream connection has
|
|
|
|
// been established and connection checking is required.
|
|
|
|
void start_checking_connection();
|
|
|
|
// Resets connection check timer. After timeout, we require
|
|
|
|
// connection checking.
|
|
|
|
int reset_connection_check_timer();
|
|
|
|
// Signals that connection is alive. Internally
|
|
|
|
// reset_connection_check_timer() is called.
|
|
|
|
int connection_alive();
|
|
|
|
// Change connection check state.
|
|
|
|
void set_connection_check_state(int state);
|
|
|
|
|
2012-11-20 17:29:39 +01:00
|
|
|
enum {
|
2013-02-09 08:42:01 +01:00
|
|
|
// Disconnected
|
2012-11-20 17:29:39 +01:00
|
|
|
DISCONNECTED,
|
2013-02-09 08:42:01 +01:00
|
|
|
// Connecting proxy and making CONNECT request
|
|
|
|
PROXY_CONNECTING,
|
|
|
|
// Tunnel is established with proxy
|
|
|
|
PROXY_CONNECTED,
|
|
|
|
// Establishing tunnel is failed
|
|
|
|
PROXY_FAILED,
|
|
|
|
// Connecting to downstream and/or performing SSL/TLS handshake
|
2012-11-20 17:29:39 +01:00
|
|
|
CONNECTING,
|
2013-02-09 08:42:01 +01:00
|
|
|
// Connected to downstream
|
2012-11-20 17:29:39 +01:00
|
|
|
CONNECTED
|
|
|
|
};
|
2014-01-19 10:07:50 +01:00
|
|
|
|
2014-11-27 15:39:04 +01:00
|
|
|
static const size_t OUTBUF_MAX_THRES = 64 * 1024;
|
|
|
|
|
nghttpx: Check HTTP/2 downstream connection after certain idle time
Previously when requests are issued to HTTP/2 downstream connection,
but it turns out that connection is down, handlers of those requests
are deleted. In some situations, we only know connection is down when
we write something to network, so we'd like to handle this kind of
situation in more robust manner. In this change, certain seconds
passed after last network activity, we first issue PING frame to
downstream connection before issuing new HTTP request. If writing
PING frame is failed, it means connection was lost. In this case,
instead of deleting handler, pending requests are migrated to new
HTTP2/ downstream connection, so that it can continue without
affecting upstream connection.
2014-12-08 17:30:15 +01:00
|
|
|
enum {
|
|
|
|
// Connection checking is not required
|
|
|
|
CONNECTION_CHECK_NONE,
|
|
|
|
// Connection checking is required
|
|
|
|
CONNECTION_CHECK_REQUIRED,
|
|
|
|
// Connection checking has been started
|
|
|
|
CONNECTION_CHECK_STARTED
|
|
|
|
};
|
|
|
|
|
2012-11-20 17:29:39 +01:00
|
|
|
private:
|
2014-11-27 15:39:04 +01:00
|
|
|
std::set<Http2DownstreamConnection *> dconns_;
|
|
|
|
std::set<StreamData *> streams_;
|
2013-12-06 15:17:38 +01:00
|
|
|
// Used to parse the response from HTTP proxy
|
|
|
|
std::unique_ptr<http_parser> proxy_htp_;
|
2012-11-20 17:29:39 +01:00
|
|
|
event_base *evbase_;
|
2013-02-22 13:54:07 +01:00
|
|
|
// NULL if no TLS is configured
|
2012-11-20 17:29:39 +01:00
|
|
|
SSL_CTX *ssl_ctx_;
|
|
|
|
SSL *ssl_;
|
2013-12-06 15:17:38 +01:00
|
|
|
nghttp2_session *session_;
|
|
|
|
bufferevent *bev_;
|
|
|
|
bufferevent *wrbev_;
|
|
|
|
bufferevent *rdbev_;
|
|
|
|
event *settings_timerev_;
|
nghttpx: Check HTTP/2 downstream connection after certain idle time
Previously when requests are issued to HTTP/2 downstream connection,
but it turns out that connection is down, handlers of those requests
are deleted. In some situations, we only know connection is down when
we write something to network, so we'd like to handle this kind of
situation in more robust manner. In this change, certain seconds
passed after last network activity, we first issue PING frame to
downstream connection before issuing new HTTP request. If writing
PING frame is failed, it means connection was lost. In this case,
instead of deleting handler, pending requests are migrated to new
HTTP2/ downstream connection, so that it can continue without
affecting upstream connection.
2014-12-08 17:30:15 +01:00
|
|
|
event *connection_check_timerev_;
|
2013-02-22 13:54:07 +01:00
|
|
|
// fd_ is used for proxy connection and no TLS connection. For
|
|
|
|
// direct or TLS connection, it may be -1 even after connection is
|
|
|
|
// established. Use bufferevent_getfd(bev_) to get file descriptor
|
|
|
|
// in these cases.
|
2013-02-09 08:42:01 +01:00
|
|
|
int fd_;
|
2012-11-20 17:29:39 +01:00
|
|
|
int state_;
|
nghttpx: Check HTTP/2 downstream connection after certain idle time
Previously when requests are issued to HTTP/2 downstream connection,
but it turns out that connection is down, handlers of those requests
are deleted. In some situations, we only know connection is down when
we write something to network, so we'd like to handle this kind of
situation in more robust manner. In this change, certain seconds
passed after last network activity, we first issue PING frame to
downstream connection before issuing new HTTP request. If writing
PING frame is failed, it means connection was lost. In this case,
instead of deleting handler, pending requests are migrated to new
HTTP2/ downstream connection, so that it can continue without
affecting upstream connection.
2014-12-08 17:30:15 +01:00
|
|
|
int connection_check_state_;
|
2012-11-20 17:29:39 +01:00
|
|
|
bool notified_;
|
2012-11-21 15:47:48 +01:00
|
|
|
bool flow_control_;
|
2012-11-20 17:29:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace shrpx
|
|
|
|
|
2013-11-04 09:53:57 +01:00
|
|
|
#endif // SHRPX_HTTP2_SESSION_H
|