nghttpx: Convert shrpx_connect_proto to enum class
This commit is contained in:
parent
00554779e1
commit
0735ec55f3
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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().
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue