-
Notifications
You must be signed in to change notification settings - Fork 5.3k
http3: support Http3Options for downstream #15753
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
Changes from all commits
0898c3e
c70d7cc
53695e7
215f63e
f8b7f03
6dd9ca1
720d792
85b7003
f21f032
e55bd8a
f35ef44
5004e70
511e79a
c255c5d
c860abf
c4e80a1
7f01805
5577f48
5d6362e
255c01b
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 |
|---|---|---|
|
|
@@ -333,5 +333,57 @@ bool HeaderUtility::isModifiableHeader(absl::string_view header) { | |
| !absl::EqualsIgnoreCase(header, Headers::get().HostLegacy.get())); | ||
| } | ||
|
|
||
| HeaderUtility::HeaderValidationResult HeaderUtility::checkHeaderNameForUnderscores( | ||
|
Member
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. It kills me that this code is now copied into a third place when we already effectively have it in both the H1 and H2 codec. This is really scary and security sensitive stuff and I feel we shouldn't be making the problem worse (it's in the opposite direction of #10646). Is there any work we can do to share some of this code now? Maybe we can do a different PR to add this helper and call it somehow from both other codecs?
Contributor
Author
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. I don't want to touch any code in production in this PR because that needs feature protection. Once this PR lands, the other two codec can switch to this utility function.
Member
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. OK fair enough. Can you at least add comments and put TODOs in the other codec places which reference this code and the tracking issue for merging?
Contributor
Author
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. done
Contributor
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. cc @yanavlasov might be a good starter project for one of the envoy-sec folks |
||
| const std::string& header_name, | ||
| envoy::config::core::v3::HttpProtocolOptions::HeadersWithUnderscoresAction | ||
| headers_with_underscores_action, | ||
| Stats::Counter& dropped_headers_with_underscores, | ||
| Stats::Counter& requests_rejected_with_underscores_in_headers) { | ||
| if (headers_with_underscores_action == envoy::config::core::v3::HttpProtocolOptions::ALLOW || | ||
| !HeaderUtility::headerNameContainsUnderscore(header_name)) { | ||
| return HeaderValidationResult::ACCEPT; | ||
| } | ||
| if (headers_with_underscores_action == | ||
| envoy::config::core::v3::HttpProtocolOptions::DROP_HEADER) { | ||
| ENVOY_LOG_MISC(debug, "Dropping header with invalid characters in its name: {}", header_name); | ||
| dropped_headers_with_underscores.inc(); | ||
| return HeaderValidationResult::DROP; | ||
| } | ||
| ENVOY_LOG_MISC(debug, "Rejecting request due to header name with underscores: {}", header_name); | ||
| requests_rejected_with_underscores_in_headers.inc(); | ||
| return HeaderUtility::HeaderValidationResult::REJECT; | ||
| } | ||
|
|
||
| HeaderUtility::HeaderValidationResult | ||
| HeaderUtility::validateContentLength(absl::string_view header_value, | ||
| bool override_stream_error_on_invalid_http_message, | ||
| bool& should_close_connection) { | ||
| should_close_connection = false; | ||
| std::vector<absl::string_view> values = absl::StrSplit(header_value, ','); | ||
| absl::optional<uint64_t> content_length; | ||
| for (const absl::string_view& value : values) { | ||
| uint64_t new_value; | ||
| if (!absl::SimpleAtoi(value, &new_value) || | ||
| !std::all_of(value.begin(), value.end(), absl::ascii_isdigit)) { | ||
| ENVOY_LOG_MISC(debug, "Content length was either unparseable or negative"); | ||
| should_close_connection = !override_stream_error_on_invalid_http_message; | ||
| return HeaderValidationResult::REJECT; | ||
| } | ||
| if (!content_length.has_value()) { | ||
| content_length = new_value; | ||
| continue; | ||
| } | ||
| if (new_value != content_length.value()) { | ||
| ENVOY_LOG_MISC( | ||
| debug, | ||
| "Parsed content length {} is inconsistent with previously detected content length {}", | ||
| new_value, content_length.value()); | ||
| should_close_connection = !override_stream_error_on_invalid_http_message; | ||
| return HeaderValidationResult::REJECT; | ||
| } | ||
| } | ||
| return HeaderValidationResult::ACCEPT; | ||
| } | ||
|
|
||
| } // namespace Http | ||
| } // namespace Envoy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| #pragma once | ||
|
|
||
| #include "envoy/stats/scope.h" | ||
| #include "envoy/stats/stats_macros.h" | ||
|
|
||
| #include "common/common/thread.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Http { | ||
| namespace Http3 { | ||
|
|
||
| /** | ||
| * All stats for the HTTP/3 codec. @see stats_macros.h | ||
| * TODO(danzh) populate all of them in codec. | ||
| */ | ||
| #define ALL_HTTP3_CODEC_STATS(COUNTER, GAUGE) \ | ||
| COUNTER(dropped_headers_with_underscores) \ | ||
| COUNTER(header_overflow) \ | ||
| COUNTER(requests_rejected_with_underscores_in_headers) \ | ||
| COUNTER(rx_messaging_error) \ | ||
| COUNTER(rx_reset) \ | ||
| COUNTER(trailers) \ | ||
| COUNTER(tx_reset) \ | ||
| GAUGE(streams_active, Accumulate) | ||
|
|
||
| /** | ||
| * Wrapper struct for the HTTP/3 codec stats. @see stats_macros.h | ||
| */ | ||
| struct CodecStats { | ||
| using AtomicPtr = Thread::AtomicPtr<CodecStats, Thread::AtomicPtrAllocMode::DeleteOnDestruct>; | ||
|
|
||
| static CodecStats& atomicGet(AtomicPtr& ptr, Stats::Scope& scope) { | ||
| return *ptr.get([&scope]() -> CodecStats* { | ||
| return new CodecStats{ALL_HTTP3_CODEC_STATS(POOL_COUNTER_PREFIX(scope, "http3."), | ||
| POOL_GAUGE_PREFIX(scope, "http3."))}; | ||
| }); | ||
| } | ||
|
|
||
| ALL_HTTP3_CODEC_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT) | ||
| }; | ||
|
|
||
| } // namespace Http3 | ||
| } // namespace Http | ||
| } // namespace Envoy |
Uh oh!
There was an error while loading. Please reload this page.