-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http: stream error on invalid HTTP messaging for HTTP/1 #11884
Changes from 37 commits
ee7cb0d
b04b98e
46768be
d1bf85d
2d7e93d
86031f0
397e369
c139ff1
2d6cac8
d30e854
aa421fd
9718246
cc33ccf
cab6751
00814d2
7f61bdf
908bdfc
e5239e8
4b2f72a
922bb6f
9dec35a
5fb9be3
83cbadf
c9c55bc
a31323f
354c08b
07c3ee5
5e1b95e
eec3bb2
f1787af
2fe6fbc
447b719
c1d456a
025dbc4
30154d7
f99724d
a35bada
b037f64
16414a0
4bb2a86
1410972
5e63612
85e57c4
3dd2c3d
464a5c7
e663b45
d92640d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,6 +142,12 @@ class ResponseEncoder : public virtual StreamEncoder { | |
* @param trailers supplies the trailers to encode. | ||
*/ | ||
virtual void encodeTrailers(const ResponseTrailerMap& trailers) PURE; | ||
|
||
/** | ||
* Indicates whether invalid HTTP messaging should be handled with a stream error or a connection | ||
* error; if value is missing, then HCM drives behaviour on invalid HTTP messaging. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. update comment to remove "if value is missing, then HCM drives behaviour on invalid HTTP messaging." |
||
*/ | ||
virtual absl::optional<bool> streamErrorOnInvalidHttpMessage() const PURE; | ||
}; | ||
|
||
/** | ||
|
@@ -386,6 +392,12 @@ struct Http1Settings { | |
|
||
// How header keys should be formatted when serializing HTTP/1.1 headers. | ||
HeaderKeyFormat header_key_format_{HeaderKeyFormat::Default}; | ||
|
||
// Behaviour on invalid HTTP messaging: | ||
// - if set and true, the HTTP/1.1 connection is left open (where possible) | ||
// - if set and false, the HTTP/1.1 connection is terminated | ||
// - if not set, fall back to the HCM behaviour on invalid HTTP messaging | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar comment here about HCM. This is generic for upstream and downstream. Where does the upstream default come from? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new HTTP/1.1 config introduced here works in tandem with the newly introduced There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I think it would be good to call this out more in the comments and the proto documentation. The proto is a generic message that is used for both upstream and downstream, so I think it would be good to clarify that it only applies right now for downstream? |
||
absl::optional<bool> stream_error_on_invalid_http_message_; | ||
}; | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,6 +80,16 @@ void recordLatestDataFilter(const typename FilterList<T>::iterator current_filte | |
} | ||
} | ||
|
||
bool streamErrorOnInvalidHttpMessage( | ||
bool hcm_stream_error_on_invalid_http_message, | ||
const absl::optional<bool> override_stream_error_on_invalid_http_message) { | ||
if (override_stream_error_on_invalid_http_message.has_value()) { | ||
return override_stream_error_on_invalid_http_message.value(); | ||
} else { | ||
return hcm_stream_error_on_invalid_http_message; | ||
} | ||
} | ||
|
||
} // namespace | ||
|
||
ConnectionManagerStats ConnectionManagerImpl::generateStats(const std::string& prefix, | ||
|
@@ -1578,8 +1588,10 @@ void ConnectionManagerImpl::ActiveStream::sendLocalReply( | |
// The BadRequest error code indicates there has been a messaging error. | ||
if (Runtime::runtimeFeatureEnabled( | ||
"envoy.reloadable_features.hcm_stream_error_on_invalid_message") && | ||
!connection_manager_.config_.streamErrorOnInvalidHttpMessaging() && | ||
code == Http::Code::BadRequest && connection_manager_.codec_->protocol() < Protocol::Http2) { | ||
code == Http::Code::BadRequest && connection_manager_.codec_->protocol() < Protocol::Http2 && | ||
!streamErrorOnInvalidHttpMessage( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to runtime guard this twice? Can we remove the first if condition? Also, I haven't been tracking all of these changes, and you probably already discussed this with Alyssa, but is this the only place this needs to be checked? I would have naively assumed there are more places this is needed but maybe not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The runtime guard here is needed because it affects HTTP/1.1 specifically, and the other place where it's checked affects HTTP/2 instead. As far as I understand, prior to #11714, we were sending errors in two places (codec and HCM), however after that change we now send errors only in the HCM. Not sure if we should check in the other code path as well (see #11884 (comment)). |
||
connection_manager_.config_.streamErrorOnInvalidHttpMessaging(), | ||
response_encoder_->streamErrorOnInvalidHttpMessage())) { | ||
state_.saw_connection_close_ = true; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can leave out the "if not set" because the sentence above makes it clear that otherwise the HCM value is used.