Commit 86174f53 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

shrpx: Send and receive client connection header

parent 9b271601
...@@ -106,7 +106,6 @@ void upstream_eventcb(bufferevent *bev, short events, void *arg) ...@@ -106,7 +106,6 @@ void upstream_eventcb(bufferevent *bev, short events, void *arg)
if(LOG_ENABLED(INFO)) { if(LOG_ENABLED(INFO)) {
CLOG(INFO, handler) << "SSL/TLS handleshake completed"; CLOG(INFO, handler) << "SSL/TLS handleshake completed";
} }
handler->set_bev_cb(upstream_readcb, upstream_writecb, upstream_eventcb);
handler->validate_next_proto(); handler->validate_next_proto();
if(LOG_ENABLED(INFO)) { if(LOG_ENABLED(INFO)) {
if(SSL_session_reused(handler->get_ssl())) { if(SSL_session_reused(handler->get_ssl())) {
...@@ -122,6 +121,38 @@ void upstream_eventcb(bufferevent *bev, short events, void *arg) ...@@ -122,6 +121,38 @@ void upstream_eventcb(bufferevent *bev, short events, void *arg)
} }
} // namespace } // namespace
namespace {
void upstream_connhd_readcb(bufferevent *bev, void *arg)
{
uint8_t data[NGHTTP2_CLIENT_CONNECTION_HEADER_LEN];
auto handler = reinterpret_cast<ClientHandler*>(arg);
size_t leftlen = handler->get_left_connhd_len();
auto input = bufferevent_get_input(bev);
int readlen = evbuffer_remove(input, data, leftlen);
if(readlen == -1) {
delete handler;
return;
}
if(memcmp(NGHTTP2_CLIENT_CONNECTION_HEADER +
NGHTTP2_CLIENT_CONNECTION_HEADER_LEN - leftlen,
data, readlen) != 0) {
delete handler;
return;
}
leftlen -= readlen;
handler->set_left_connhd_len(leftlen);
if(leftlen == 0) {
handler->set_bev_cb(upstream_readcb, upstream_writecb, upstream_eventcb);
// Run on_read to process data left in buffer since they are not
// notified further
if(handler->on_read() != 0) {
delete handler;
return;
}
}
}
} // namespace
ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl, ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl,
const char *ipaddr) const char *ipaddr)
: bev_(bev), : bev_(bev),
...@@ -130,7 +161,8 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl, ...@@ -130,7 +161,8 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl,
upstream_(nullptr), upstream_(nullptr),
ipaddr_(ipaddr), ipaddr_(ipaddr),
should_close_after_write_(false), should_close_after_write_(false),
spdy_(nullptr) spdy_(nullptr),
left_connhd_len_(NGHTTP2_CLIENT_CONNECTION_HEADER_LEN)
{ {
bufferevent_enable(bev_, EV_READ | EV_WRITE); bufferevent_enable(bev_, EV_READ | EV_WRITE);
bufferevent_setwatermark(bev_, EV_READ, 0, SHRPX_READ_WARTER_MARK); bufferevent_setwatermark(bev_, EV_READ, 0, SHRPX_READ_WARTER_MARK);
...@@ -142,11 +174,12 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl, ...@@ -142,11 +174,12 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl,
if(get_config()->client_mode) { if(get_config()->client_mode) {
// Client mode // Client mode
upstream_ = new HttpsUpstream(this); upstream_ = new HttpsUpstream(this);
set_bev_cb(upstream_readcb, upstream_writecb, upstream_eventcb);
} else { } else {
// no-TLS SPDY // no-TLS SPDY
upstream_ = new Http2Upstream(this); upstream_ = new Http2Upstream(this);
set_bev_cb(upstream_connhd_readcb, upstream_writecb, upstream_eventcb);
} }
set_bev_cb(upstream_readcb, upstream_writecb, upstream_eventcb);
} }
} }
...@@ -207,6 +240,8 @@ int ClientHandler::validate_next_proto() ...@@ -207,6 +240,8 @@ int ClientHandler::validate_next_proto()
{ {
const unsigned char *next_proto = nullptr; const unsigned char *next_proto = nullptr;
unsigned int next_proto_len; unsigned int next_proto_len;
// First set callback for catch all cases
set_bev_cb(upstream_readcb, upstream_writecb, upstream_eventcb);
SSL_get0_next_proto_negotiated(ssl_, &next_proto, &next_proto_len); SSL_get0_next_proto_negotiated(ssl_, &next_proto, &next_proto_len);
if(next_proto) { if(next_proto) {
std::string proto(next_proto, next_proto+next_proto_len); std::string proto(next_proto, next_proto+next_proto_len);
...@@ -214,6 +249,7 @@ int ClientHandler::validate_next_proto() ...@@ -214,6 +249,7 @@ int ClientHandler::validate_next_proto()
CLOG(INFO, this) << "The negotiated next protocol: " << proto; CLOG(INFO, this) << "The negotiated next protocol: " << proto;
} }
if(proto == NGHTTP2_PROTO_VERSION_ID) { if(proto == NGHTTP2_PROTO_VERSION_ID) {
set_bev_cb(upstream_connhd_readcb, upstream_writecb, upstream_eventcb);
upstream_ = new Http2Upstream(this); upstream_ = new Http2Upstream(this);
return 0; return 0;
} else { } else {
...@@ -323,4 +359,14 @@ SpdySession* ClientHandler::get_spdy_session() const ...@@ -323,4 +359,14 @@ SpdySession* ClientHandler::get_spdy_session() const
return spdy_; return spdy_;
} }
size_t ClientHandler::get_left_connhd_len() const
{
return left_connhd_len_;
}
void ClientHandler::set_left_connhd_len(size_t left)
{
left_connhd_len_ = left;
}
} // namespace shrpx } // namespace shrpx
...@@ -63,6 +63,8 @@ public: ...@@ -63,6 +63,8 @@ public:
SSL* get_ssl() const; SSL* get_ssl() const;
void set_spdy_session(SpdySession *spdy); void set_spdy_session(SpdySession *spdy);
SpdySession* get_spdy_session() const; SpdySession* get_spdy_session() const;
size_t get_left_connhd_len() const;
void set_left_connhd_len(size_t left);
private: private:
bufferevent *bev_; bufferevent *bev_;
int fd_; int fd_;
...@@ -74,6 +76,8 @@ private: ...@@ -74,6 +76,8 @@ private:
// Shared SPDY session for each thread. NULL if backend is not // Shared SPDY session for each thread. NULL if backend is not
// SPDY. Not deleted by this object. // SPDY. Not deleted by this object.
SpdySession *spdy_; SpdySession *spdy_;
// The number of bytes of HTTP/2.0 client connection header to read
size_t left_connhd_len_;
}; };
} // namespace shrpx } // namespace shrpx
......
...@@ -1077,6 +1077,9 @@ int SpdySession::on_connect() ...@@ -1077,6 +1077,9 @@ int SpdySession::on_connect()
return -1; return -1;
} }
bufferevent_write(bev_, NGHTTP2_CLIENT_CONNECTION_HEADER,
NGHTTP2_CLIENT_CONNECTION_HEADER_LEN);
rv = send(); rv = send();
if(rv != 0) { if(rv != 0) {
return -1; return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment