-
Notifications
You must be signed in to change notification settings - Fork 5.5k
http conn man: add an option to strip trailing host dot. #15568
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 19 commits
7c0674d
d2e05b7
595157c
4945289
74f247f
bb62fda
c3d1057
4b9c804
468ce45
3a4f449
40a1a44
8995b52
baed449
58b3759
e910496
dca8659
fffc458
d3cd808
ef66621
c744100
ec186fd
c94357b
d117486
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,7 +35,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; | |
| // HTTP connection manager :ref:`configuration overview <config_http_conn_man>`. | ||
| // [#extension: envoy.filters.network.http_connection_manager] | ||
|
|
||
| // [#next-free-field: 47] | ||
| // [#next-free-field: 48] | ||
| message HttpConnectionManager { | ||
| option (udpa.annotations.versioning).previous_message_type = | ||
| "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; | ||
|
|
@@ -702,6 +702,15 @@ message HttpConnectionManager { | |
| // <envoy_v3_api_msg_extensions.filters.network.http_connection_manager.v3.PathNormalizationOptions>` | ||
| // for details. | ||
| PathNormalizationOptions path_normalization_options = 43; | ||
|
|
||
| // Determines if trailing dot of the host should be removed from host/authority header before any | ||
| // processing of request by HTTP filters or routing. | ||
| // This affects the upstream host header. | ||
| // Without setting this option, incoming requests with host `example.com.` will not match against | ||
| // route with :ref:`domains<envoy_v3_api_field_config.route.v3.VirtualHost.domains>` match set to `example.com`. Defaults to `false`. | ||
| // When incoming requests with host/authority header has port part with host, on setting this option it removes trailing dot from host keeping port | ||
|
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. Maybe
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. thanks, will update. |
||
| // value as is (e.g. host value `example.com.:443` will be updated to `example.com:443`). | ||
| bool strip_trailing_host_dot = 47; | ||
| } | ||
|
|
||
| // The configuration to customize local reply returned by Envoy. | ||
|
|
||
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 |
|---|---|---|
|
|
@@ -60,11 +60,13 @@ Removed Config or Runtime | |
|
|
||
| New Features | ||
| ------------ | ||
|
|
||
|
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. remove this newline
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. will remove. |
||
| * crash support: restore crash context when continuing to processing requests or responses as a result of an asynchronous callback that invokes a filter directly. This is unlike the call stacks that go through the various network layers, to eventually reach the filter. For a concrete example see: ``Envoy::Extensions::HttpFilters::Cache::CacheFilter::getHeaders`` which posts a callback on the dispatcher that will invoke the filter directly. | ||
| * http: a new field `is_optional` is added to `extensions.filters.network.http_connection_manager.v3.HttpFilter`. When | ||
| value is `true`, the unsupported http filter will be ignored by envoy. This is also same with unsupported http filter | ||
| in the typed per filter config. For more information, please reference | ||
| :ref:`HttpFilter <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpFilter.is_optional>`. | ||
| * http: added :ref:`stripping trailing host dot from host header<envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.strip_trailing_host_dot>` support. | ||
| * http: added support for :ref:`original IP detection extensions<envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.original_ip_detection_extensions>`. | ||
| Two initial extensions were added, the :ref:`custom header <envoy_v3_api_msg_extensions.http.original_ip_detection.custom_header.v3.CustomHeaderConfig>` extension and the | ||
| :ref:`xff <envoy_v3_api_msg_extensions.http.original_ip_detection.xff.v3.XffConfig>` extension. | ||
|
|
||
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 |
|---|---|---|
|
|
@@ -216,6 +216,27 @@ bool HeaderUtility::isEnvoyInternalRequest(const RequestHeaderMap& headers) { | |
| internal_request_header->value() == Headers::get().EnvoyInternalRequestValues.True; | ||
| } | ||
|
|
||
| void HeaderUtility::stripTrailingHostDot(RequestHeaderMap& headers) { | ||
| auto host = headers.getHostValue(); | ||
| // If the host ends in a period, remove it. | ||
| auto dot_index = host.rfind('.'); | ||
| if (dot_index == std::string::npos) { | ||
| return; | ||
| } else if (dot_index == (host.size() - 1)) { | ||
| host.remove_suffix(1); | ||
| headers.setHost(host); | ||
| return; | ||
| } | ||
| // If the dot is just before a colon, it must be preceding the port number. | ||
| // Because although the host may contain a colon via an IPv6 bracketed | ||
| // address, and although that IPv6 address may also contain dots when | ||
| // embedding an address per RFC 4291 2.2.3. In this case the dot will never | ||
|
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. This is a bit tricky to read, maybe something like
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. sure, will update it. |
||
| // directly precede the colon like it would in foo.com.:123. | ||
| if (host[dot_index + 1] == ':') { | ||
| headers.setHost(absl::StrCat(host.substr(0, dot_index), host.substr(dot_index + 1))); | ||
| } | ||
| } | ||
|
|
||
| absl::optional<uint32_t> HeaderUtility::stripPortFromHost(RequestHeaderMap& headers, | ||
| absl::optional<uint32_t> listener_port) { | ||
| if (headers.getMethodValue() == Http::Headers::get().MethodValues.Connect && | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1194,6 +1194,27 @@ TEST_F(HttpConnectionManagerImplTest, RouteShouldUseNormalizedHost) { | |
| filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); | ||
| } | ||
|
|
||
| // Observe host header w/o trailing dot in host when trailing dot removal is configured. | ||
|
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. This makes it sound like the input doesn't have a trailing dot, maybe
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. thanks, will change. |
||
| TEST_F(HttpConnectionManagerImplTest, StripTrailingHostDot) { | ||
|
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. Mind adding a test where we set this config option but pass through a header without a trailing dot?
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. Sure. will add. |
||
| setup(false, ""); | ||
| // Enable removal of host's trailing dot. | ||
| strip_trailing_host_dot_ = true; | ||
| const std::string original_host = "host."; | ||
| const std::string updated_host = "host"; | ||
| // Set up the codec. | ||
| Buffer::OwnedImpl fake_input("1234"); | ||
| conn_manager_->createCodec(fake_input); | ||
| // Create a new stream. | ||
| decoder_ = &conn_manager_->newStream(response_encoder_); | ||
| RequestHeaderMapPtr headers{new TestRequestHeaderMapImpl{ | ||
| {":authority", original_host}, {":path", "/"}, {":method", "GET"}}}; | ||
| RequestHeaderMap* updated_headers = headers.get(); | ||
| decoder_->decodeHeaders(std::move(headers), true); | ||
| EXPECT_EQ(updated_host, updated_headers->getHostValue()); | ||
| // Clean up. | ||
| filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose); | ||
| } | ||
|
|
||
| TEST_F(HttpConnectionManagerImplTest, DateHeaderNotPresent) { | ||
| setup(false, ""); | ||
| setUpEncoderAndDecoder(false, false); | ||
|
|
||
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.
This should probably include something about how this handles the host:port case
Uh oh!
There was an error while loading. Please reload this page.
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.
Will following comment helps here in case of host:port?