nghttpx: Convert shrpx_connect_proto to enum class

This commit is contained in:
Tatsuhiro Tsujikawa 2018-10-17 09:50:29 +09:00
parent 00554779e1
commit 0735ec55f3
7 changed files with 27 additions and 24 deletions

View File

@ -767,13 +767,13 @@ void Downstream::check_upgrade_fulfilled_http2() {
// This handles nonzero req_.connect_proto and h1 frontend requests // This handles nonzero req_.connect_proto and h1 frontend requests
// WebSocket upgrade. // WebSocket upgrade.
upgraded_ = (req_.method == HTTP_CONNECT || upgraded_ = (req_.method == HTTP_CONNECT ||
req_.connect_proto == CONNECT_PROTO_WEBSOCKET) && req_.connect_proto == ConnectProto::WEBSOCKET) &&
resp_.http_status / 100 == 2; resp_.http_status / 100 == 2;
} }
void Downstream::check_upgrade_fulfilled_http1() { void Downstream::check_upgrade_fulfilled_http1() {
if (req_.method == HTTP_CONNECT) { if (req_.method == HTTP_CONNECT) {
if (req_.connect_proto == CONNECT_PROTO_WEBSOCKET) { if (req_.connect_proto == ConnectProto::WEBSOCKET) {
if (resp_.http_status != 101) { if (resp_.http_status != 101) {
return; return;
} }
@ -827,7 +827,7 @@ void Downstream::inspect_http1_request() {
// TODO Should we check Sec-WebSocket-Key, and // TODO Should we check Sec-WebSocket-Key, and
// Sec-WebSocket-Version as well? // Sec-WebSocket-Version as well?
if (util::strieq_l("websocket", val)) { if (util::strieq_l("websocket", val)) {
req_.connect_proto = CONNECT_PROTO_WEBSOCKET; req_.connect_proto = ConnectProto::WEBSOCKET;
} }
} }
} }

View File

@ -135,9 +135,9 @@ private:
}; };
// Protocols allowed in HTTP/2 :protocol header field. // Protocols allowed in HTTP/2 :protocol header field.
enum shrpx_connect_proto { enum class ConnectProto {
CONNECT_PROTO_NONE, NONE,
CONNECT_PROTO_WEBSOCKET, WEBSOCKET,
}; };
struct Request { struct Request {
@ -148,7 +148,7 @@ struct Request {
method(-1), method(-1),
http_major(1), http_major(1),
http_minor(1), http_minor(1),
connect_proto(CONNECT_PROTO_NONE), connect_proto(ConnectProto::NONE),
upgrade_request(false), upgrade_request(false),
http2_upgrade_seen(false), http2_upgrade_seen(false),
connection_close(false), connection_close(false),
@ -161,10 +161,12 @@ struct Request {
} }
bool regular_connect_method() const { bool regular_connect_method() const {
return method == HTTP_CONNECT && !connect_proto; return method == HTTP_CONNECT && connect_proto == ConnectProto::NONE;
} }
bool extended_connect_method() const { return connect_proto; } bool extended_connect_method() const {
return connect_proto != ConnectProto::NONE;
}
FieldStore fs; FieldStore fs;
// Timestamp when all request header fields are received. // Timestamp when all request header fields are received.
@ -192,7 +194,7 @@ struct Request {
// connect_proto specified in HTTP/2 :protocol pseudo header field // connect_proto specified in HTTP/2 :protocol pseudo header field
// which enables extended CONNECT method. This field is also set if // which enables extended CONNECT method. This field is also set if
// WebSocket upgrade is requested in h1 frontend for convenience. // WebSocket upgrade is requested in h1 frontend for convenience.
int connect_proto; ConnectProto connect_proto;
// Returns true if the request is HTTP upgrade (HTTP Upgrade or // Returns true if the request is HTTP upgrade (HTTP Upgrade or
// CONNECT method). Upgrade to HTTP/2 is excluded. For HTTP/2 // CONNECT method). Upgrade to HTTP/2 is excluded. For HTTP/2
// Upgrade, check get_http2_upgrade_request(). // Upgrade, check get_http2_upgrade_request().

View File

@ -105,7 +105,7 @@ int Http2DownstreamConnection::attach_downstream(Downstream *downstream) {
auto &req = downstream_->request(); auto &req = downstream_->request();
// HTTP/2 disables HTTP Upgrade. // HTTP/2 disables HTTP Upgrade.
if (req.method != HTTP_CONNECT && !req.connect_proto) { if (req.method != HTTP_CONNECT && req.connect_proto == ConnectProto::NONE) {
req.upgrade_request = false; req.upgrade_request = false;
} }
@ -244,7 +244,8 @@ int Http2DownstreamConnection::push_request_headers() {
const auto &req = downstream_->request(); const auto &req = downstream_->request();
if (req.connect_proto && !http2session_->get_allow_connect_proto()) { if (req.connect_proto != ConnectProto::NONE &&
!http2session_->get_allow_connect_proto()) {
return -1; return -1;
} }
@ -292,7 +293,7 @@ int Http2DownstreamConnection::push_request_headers() {
nva.reserve(req.fs.headers().size() + 11 + num_cookies + nva.reserve(req.fs.headers().size() + 11 + num_cookies +
httpconf.add_request_headers.size()); httpconf.add_request_headers.size());
if (req.connect_proto == CONNECT_PROTO_WEBSOCKET) { if (req.connect_proto == ConnectProto::WEBSOCKET) {
nva.push_back(http2::make_nv_ll(":method", "CONNECT")); nva.push_back(http2::make_nv_ll(":method", "CONNECT"));
nva.push_back(http2::make_nv_ll(":protocol", "websocket")); nva.push_back(http2::make_nv_ll(":protocol", "websocket"));
} else { } else {
@ -318,7 +319,7 @@ int Http2DownstreamConnection::push_request_headers() {
nva.push_back(http2::make_nv_ls_nocopy(":path", req.path)); nva.push_back(http2::make_nv_ls_nocopy(":path", req.path));
} }
if (!req.no_authority || req.connect_proto) { if (!req.no_authority || req.connect_proto != ConnectProto::NONE) {
nva.push_back(http2::make_nv_ls_nocopy(":authority", authority)); nva.push_back(http2::make_nv_ls_nocopy(":authority", authority));
} else { } else {
nva.push_back(http2::make_nv_ls_nocopy("host", authority)); nva.push_back(http2::make_nv_ls_nocopy("host", authority));
@ -475,8 +476,8 @@ int Http2DownstreamConnection::push_request_headers() {
// Add body as long as transfer-encoding is given even if // Add body as long as transfer-encoding is given even if
// req.fs.content_length == 0 to forward trailer fields. // req.fs.content_length == 0 to forward trailer fields.
if (req.method == HTTP_CONNECT || req.connect_proto || transfer_encoding || if (req.method == HTTP_CONNECT || req.connect_proto != ConnectProto::NONE ||
req.fs.content_length > 0 || req.http2_expect_body) { transfer_encoding || req.fs.content_length > 0 || req.http2_expect_body) {
// Request-body is expected. // Request-body is expected.
data_prd = {{}, http2_data_read_callback}; data_prd = {{}, http2_data_read_callback};
data_prdptr = &data_prd; data_prdptr = &data_prd;

View File

@ -1859,7 +1859,7 @@ bool Http2Session::can_push_request(const Downstream *downstream) const {
auto &req = downstream->request(); auto &req = downstream->request();
return state_ == CONNECTED && return state_ == CONNECTED &&
connection_check_state_ == CONNECTION_CHECK_NONE && connection_check_state_ == CONNECTION_CHECK_NONE &&
(!req.connect_proto || settings_recved_); (req.connect_proto == ConnectProto::NONE || settings_recved_);
} }
void Http2Session::start_checking_connection() { void Http2Session::start_checking_connection() {
@ -1919,7 +1919,7 @@ void Http2Session::submit_pending_requests() {
} }
auto &req = downstream->request(); auto &req = downstream->request();
if (req.connect_proto && !settings_recved_) { if (req.connect_proto != ConnectProto::NONE && !settings_recved_) {
continue; continue;
} }

View File

@ -400,7 +400,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
} }
return 0; return 0;
} }
req.connect_proto = CONNECT_PROTO_WEBSOCKET; req.connect_proto = ConnectProto::WEBSOCKET;
} }
if (!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { if (!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
@ -1752,7 +1752,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
auto striphd_flags = http2::HDOP_STRIP_ALL & ~http2::HDOP_STRIP_VIA; auto striphd_flags = http2::HDOP_STRIP_ALL & ~http2::HDOP_STRIP_VIA;
StringRef response_status; StringRef response_status;
if (req.connect_proto == CONNECT_PROTO_WEBSOCKET && resp.http_status == 101) { if (req.connect_proto == ConnectProto::WEBSOCKET && resp.http_status == 101) {
response_status = http2::stringify_status(balloc, 200); response_status = http2::stringify_status(balloc, 200);
striphd_flags |= http2::HDOP_STRIP_SEC_WEBSOCKET_ACCEPT; striphd_flags |= http2::HDOP_STRIP_SEC_WEBSOCKET_ACCEPT;
} else { } else {

View File

@ -513,7 +513,7 @@ int HttpDownstreamConnection::push_request_headers() {
// Assume that method and request path do not contain \r\n. // Assume that method and request path do not contain \r\n.
auto meth = http2::to_method_string( auto meth = http2::to_method_string(
req.connect_proto == CONNECT_PROTO_WEBSOCKET ? HTTP_GET : req.method); req.connect_proto == ConnectProto::WEBSOCKET ? HTTP_GET : req.method);
buf->append(meth); buf->append(meth);
buf->append(' '); buf->append(' ');
@ -566,7 +566,7 @@ int HttpDownstreamConnection::push_request_headers() {
buf->append("Transfer-Encoding: chunked\r\n"); buf->append("Transfer-Encoding: chunked\r\n");
} }
if (req.connect_proto == CONNECT_PROTO_WEBSOCKET) { if (req.connect_proto == ConnectProto::WEBSOCKET) {
if (req.http_major == 2) { if (req.http_major == 2) {
std::array<uint8_t, 16> nonce; std::array<uint8_t, 16> nonce;
util::random_bytes(std::begin(nonce), std::end(nonce), util::random_bytes(std::begin(nonce), std::end(nonce),

View File

@ -1091,7 +1091,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
buf->append('.'); buf->append('.');
buf->append('0' + req.http_minor); buf->append('0' + req.http_minor);
buf->append(' '); buf->append(' ');
if (req.connect_proto && downstream->get_upgraded()) { if (req.connect_proto != ConnectProto::NONE && downstream->get_upgraded()) {
buf->append(http2::stringify_status(balloc, 101)); buf->append(http2::stringify_status(balloc, 101));
buf->append(' '); buf->append(' ');
buf->append(http2::get_reason_phrase(101)); buf->append(http2::get_reason_phrase(101));
@ -1153,7 +1153,7 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
} }
if (!connect_method && downstream->get_upgraded()) { if (!connect_method && downstream->get_upgraded()) {
if (req.connect_proto == CONNECT_PROTO_WEBSOCKET && if (req.connect_proto == ConnectProto::WEBSOCKET &&
resp.http_status / 100 == 2) { resp.http_status / 100 == 2) {
buf->append("Upgrade: websocket\r\nConnection: Upgrade\r\n"); buf->append("Upgrade: websocket\r\nConnection: Upgrade\r\n");
auto key = req.fs.header(http2::HD_SEC_WEBSOCKET_KEY); auto key = req.fs.header(http2::HD_SEC_WEBSOCKET_KEY);