From c00643b7355cc10fa3ee063c46b09d997a595afb Mon Sep 17 00:00:00 2001 From: "data-plane-api(Azure Pipelines)" Date: Fri, 5 Mar 2021 14:09:10 +0000 Subject: [PATCH] [http] API changes to split path header normalization and forwarding (#15044) * Configuration for path normalization so that normalization can be configured for internal only use and/or forwarding. Signed-off-by: Asra Ali Mirrored from https://github.com/envoyproxy/envoy @ 236107df5d15381ccf5040c0cb0f163ece9627a2 --- BUILD | 1 + .../network/http_connection_manager/v3/BUILD | 1 + .../v3/http_connection_manager.proto | 45 +++++++++++++- .../http_connection_manager/v4alpha/BUILD | 1 + .../v4alpha/http_connection_manager.proto | 49 +++++++++++++++- envoy/type/http/v3/BUILD | 9 +++ envoy/type/http/v3/path_transformation.proto | 58 +++++++++++++++++++ versioning/BUILD | 1 + 8 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 envoy/type/http/v3/BUILD create mode 100644 envoy/type/http/v3/path_transformation.proto diff --git a/BUILD b/BUILD index d3d57829..7819919e 100644 --- a/BUILD +++ b/BUILD @@ -286,6 +286,7 @@ proto_library( "//envoy/service/status/v3:pkg", "//envoy/service/tap/v3:pkg", "//envoy/service/trace/v3:pkg", + "//envoy/type/http/v3:pkg", "//envoy/type/matcher/v3:pkg", "//envoy/type/metadata/v3:pkg", "//envoy/type/tracing/v3:pkg", diff --git a/envoy/extensions/filters/network/http_connection_manager/v3/BUILD b/envoy/extensions/filters/network/http_connection_manager/v3/BUILD index 6ae87bf7..55b63248 100644 --- a/envoy/extensions/filters/network/http_connection_manager/v3/BUILD +++ b/envoy/extensions/filters/network/http_connection_manager/v3/BUILD @@ -11,6 +11,7 @@ api_proto_package( "//envoy/config/filter/network/http_connection_manager/v2:pkg", "//envoy/config/route/v3:pkg", "//envoy/config/trace/v3:pkg", + "//envoy/type/http/v3:pkg", "//envoy/type/tracing/v3:pkg", "//envoy/type/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", diff --git a/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto b/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto index 65fa6b3a..f75d624e 100644 --- a/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto +++ b/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -11,6 +11,7 @@ import "envoy/config/core/v3/substitution_format_string.proto"; import "envoy/config/route/v3/route.proto"; import "envoy/config/route/v3/scoped_route.proto"; import "envoy/config/trace/v3/http_tracer.proto"; +import "envoy/type/http/v3/path_transformation.proto"; import "envoy/type/tracing/v3/custom_tag.proto"; import "envoy/type/v3/percent.proto"; @@ -33,7 +34,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 43] +// [#next-free-field: 44] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"; @@ -238,6 +239,38 @@ message HttpConnectionManager { google.protobuf.BoolValue enabled = 3; } + // [#not-implemented-hide] Transformations that apply to path headers. Transformations are applied + // before any processing of requests by HTTP filters, routing, and matching. Only the normalized + // path will be visible internally if a transformation is enabled. Any path rewrites that the + // router performs (e.g. :ref:`regex_rewrite + // ` or :ref:`prefix_rewrite + // `) will apply to the *:path* header + // destined for the upstream. + // + // Note: access logging and tracing will show the original *:path* header. + message PathNormalizationOptions { + // [#not-implemented-hide] Normalization applies internally before any processing of requests by + // HTTP filters, routing, and matching *and* will affect the forwarded *:path* header. Defaults + // to :ref:`NormalizePathRFC3986 + // `. When not + // specified, this value may be overridden by the runtime variable + // :ref:`http_connection_manager.normalize_path`. + // Envoy will respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + // normalization due to disallowed characters.) + type.http.v3.PathTransformation forwarding_transformation = 1; + + // [#not-implemented-hide] Normalization only applies internally before any processing of + // requests by HTTP filters, routing, and matching. These will be applied after full + // transformation is applied. The *:path* header before this transformation will be restored in + // the router filter and sent upstream unless it was mutated by a filter. Defaults to no + // transformations. + // Multiple actions can be applied in the same Transformation, forming a sequential + // pipeline. The transformations will be performed in the order that they appear. Envoy will + // respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + // normalization due to disallowed characters.) + type.http.v3.PathTransformation http_filter_transformation = 2; + } + reserved 27, 11; reserved "idle_timeout"; @@ -588,6 +621,16 @@ message HttpConnectionManager { // *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; + + // [#not-implemented-hide:] Path normalization configuration. This includes + // configurations for transformations (e.g. RFC 3986 normalization or merge + // adjacent slashes) and the policy to apply them. The policy determines + // whether transformations affect the forwarded *:path* header. RFC 3986 path + // normalization is enabled by default and the default policy is that the + // normalized header will be forwarded. See :ref:`PathNormalizationOptions + // ` + // for details. + PathNormalizationOptions path_normalization_options = 43; } // The configuration to customize local reply returned by Envoy. diff --git a/envoy/extensions/filters/network/http_connection_manager/v4alpha/BUILD b/envoy/extensions/filters/network/http_connection_manager/v4alpha/BUILD index c2409f9e..64536cde 100644 --- a/envoy/extensions/filters/network/http_connection_manager/v4alpha/BUILD +++ b/envoy/extensions/filters/network/http_connection_manager/v4alpha/BUILD @@ -11,6 +11,7 @@ api_proto_package( "//envoy/config/route/v4alpha:pkg", "//envoy/config/trace/v4alpha:pkg", "//envoy/extensions/filters/network/http_connection_manager/v3:pkg", + "//envoy/type/http/v3:pkg", "//envoy/type/tracing/v3:pkg", "//envoy/type/v3:pkg", "@com_github_cncf_udpa//udpa/annotations:pkg", diff --git a/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto b/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto index 246df060..756d055d 100644 --- a/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto +++ b/envoy/extensions/filters/network/http_connection_manager/v4alpha/http_connection_manager.proto @@ -11,6 +11,7 @@ import "envoy/config/core/v4alpha/substitution_format_string.proto"; import "envoy/config/route/v4alpha/route.proto"; import "envoy/config/route/v4alpha/scoped_route.proto"; import "envoy/config/trace/v4alpha/http_tracer.proto"; +import "envoy/type/http/v3/path_transformation.proto"; import "envoy/type/tracing/v3/custom_tag.proto"; import "envoy/type/v3/percent.proto"; @@ -32,7 +33,7 @@ option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSIO // HTTP connection manager :ref:`configuration overview `. // [#extension: envoy.filters.network.http_connection_manager] -// [#next-free-field: 43] +// [#next-free-field: 44] message HttpConnectionManager { option (udpa.annotations.versioning).previous_message_type = "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"; @@ -237,6 +238,42 @@ message HttpConnectionManager { google.protobuf.BoolValue enabled = 3; } + // [#not-implemented-hide] Transformations that apply to path headers. Transformations are applied + // before any processing of requests by HTTP filters, routing, and matching. Only the normalized + // path will be visible internally if a transformation is enabled. Any path rewrites that the + // router performs (e.g. :ref:`regex_rewrite + // ` or :ref:`prefix_rewrite + // `) will apply to the *:path* header + // destined for the upstream. + // + // Note: access logging and tracing will show the original *:path* header. + message PathNormalizationOptions { + option (udpa.annotations.versioning).previous_message_type = + "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager." + "PathNormalizationOptions"; + + // [#not-implemented-hide] Normalization applies internally before any processing of requests by + // HTTP filters, routing, and matching *and* will affect the forwarded *:path* header. Defaults + // to :ref:`NormalizePathRFC3986 + // `. When not + // specified, this value may be overridden by the runtime variable + // :ref:`http_connection_manager.normalize_path`. + // Envoy will respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + // normalization due to disallowed characters.) + type.http.v3.PathTransformation forwarding_transformation = 1; + + // [#not-implemented-hide] Normalization only applies internally before any processing of + // requests by HTTP filters, routing, and matching. These will be applied after full + // transformation is applied. The *:path* header before this transformation will be restored in + // the router filter and sent upstream unless it was mutated by a filter. Defaults to no + // transformations. + // Multiple actions can be applied in the same Transformation, forming a sequential + // pipeline. The transformations will be performed in the order that they appear. Envoy will + // respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + // normalization due to disallowed characters.) + type.http.v3.PathTransformation http_filter_transformation = 2; + } + reserved 27, 11; reserved "idle_timeout"; @@ -586,6 +623,16 @@ message HttpConnectionManager { // *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging // ` google.protobuf.BoolValue stream_error_on_invalid_http_message = 40; + + // [#not-implemented-hide:] Path normalization configuration. This includes + // configurations for transformations (e.g. RFC 3986 normalization or merge + // adjacent slashes) and the policy to apply them. The policy determines + // whether transformations affect the forwarded *:path* header. RFC 3986 path + // normalization is enabled by default and the default policy is that the + // normalized header will be forwarded. See :ref:`PathNormalizationOptions + // ` + // for details. + PathNormalizationOptions path_normalization_options = 43; } // The configuration to customize local reply returned by Envoy. diff --git a/envoy/type/http/v3/BUILD b/envoy/type/http/v3/BUILD new file mode 100644 index 00000000..ee92fb65 --- /dev/null +++ b/envoy/type/http/v3/BUILD @@ -0,0 +1,9 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"], +) diff --git a/envoy/type/http/v3/path_transformation.proto b/envoy/type/http/v3/path_transformation.proto new file mode 100644 index 00000000..6f13b783 --- /dev/null +++ b/envoy/type/http/v3/path_transformation.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +package envoy.type.http.v3; + +import "udpa/annotations/migrate.proto"; +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.type.http.v3"; +option java_outer_classname = "PathTransformationProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Path Transformations API] + +// PathTransformation defines an API to apply a sequence of operations that can be used to alter +// text before it is used for matching or routing. Multiple actions can be applied in the same +// Transformation, forming a sequential pipeline. The transformations will be performed in the order +// that they appear. +// +// This API is a work in progress. + +message PathTransformation { + // A type of operation to alter text. + message Operation { + // Should text be normalized according to RFC 3986? This typically is used for path headers + // before any processing of requests by HTTP filters or routing. This applies percent-encoded + // normalization and path segment normalization. Fails on characters disallowed in URLs + // (e.g. NULLs). See `Normalization and Comparison + // `_ for details of normalization. Note that + // this options does not perform `case normalization + // `_ + message NormalizePathRFC3986 { + } + + // Determines if adjacent slashes are merged into one. A common use case is for a request path + // header. Using this option in `:ref: PathNormalizationOptions + // ` + // will allow incoming requests with path `//dir///file` to match against route with `prefix` + // match set to `/dir`. When using for header transformations, note that slash merging is not + // part of `HTTP spec `_ and is provided for convenience. + message MergeSlashes { + } + + oneof operation_specifier { + option (validate.required) = true; + + // Enable path normalization per RFC 3986. + NormalizePathRFC3986 normalize_path_rfc_3986 = 2; + + // Enable merging adjacent slashes. + MergeSlashes merge_slashes = 3; + } + } + + // A list of operations to apply. Transformations will be performed in the order that they appear. + repeated Operation operations = 1; +} diff --git a/versioning/BUILD b/versioning/BUILD index 173b942b..642a034e 100644 --- a/versioning/BUILD +++ b/versioning/BUILD @@ -169,6 +169,7 @@ proto_library( "//envoy/service/status/v3:pkg", "//envoy/service/tap/v3:pkg", "//envoy/service/trace/v3:pkg", + "//envoy/type/http/v3:pkg", "//envoy/type/matcher/v3:pkg", "//envoy/type/metadata/v3:pkg", "//envoy/type/tracing/v3:pkg",