// Copyright 2025 Envoy Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package envoy.config.route.v3;

import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/config_source.proto";
import "envoy/config/route/v3/route_components.proto";

import "google/protobuf/any.proto";
import "google/protobuf/wrappers.proto";

import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.config.route.v3";
option java_outer_classname = "RouteProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/config/route/v3;routev3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: HTTP route configuration]
// * Routing :ref:`architecture overview <arch_overview_http_routing>`
// * HTTP :ref:`router filter <config_http_filters_router>`

// [#next-free-field: 18]
message RouteConfiguration {
  option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.RouteConfiguration";

  // The name of the route configuration. For example, it might match
  // :ref:`route_config_name
  // <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.Rds.route_config_name>` in
  // :ref:`envoy_v3_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`.
  string name = 1;

  // An array of virtual hosts that make up the route table.
  repeated VirtualHost virtual_hosts = 2;

  // An array of virtual hosts will be dynamically loaded via the VHDS API.
  // Both ``virtual_hosts`` and ``vhds`` fields will be used when present. ``virtual_hosts`` can be used
  // for a base routing table or for infrequently changing virtual hosts. ``vhds`` is used for
  // on-demand discovery of virtual hosts. The contents of these two fields will be merged to
  // generate a routing table for a given RouteConfiguration, with ``vhds`` derived configuration
  // taking precedence.
  Vhds vhds = 9;

  // Optionally specifies a list of HTTP headers that the connection manager
  // will consider to be internal only. If they are found on external requests they will be cleaned
  // prior to filter invocation. See :ref:`config_http_conn_man_headers_x-envoy-internal` for more
  // information.
  repeated string internal_only_headers = 3 [
    (validate.rules).repeated = {items {string {well_known_regex: HTTP_HEADER_NAME strict: false}}}
  ];

  // Specifies a list of HTTP headers that should be added to each response that
  // the connection manager encodes. Headers specified at this level are applied
  // after headers from any enclosed :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` or
  // :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. For more information, including details on
  // header value syntax, see the documentation on :ref:`custom request headers
  // <config_http_conn_man_headers_custom_request_headers>`.
  repeated core.v3.HeaderValueOption response_headers_to_add = 4
      [(validate.rules).repeated = {max_items: 1000}];

  // Specifies a list of HTTP headers that should be removed from each response
  // that the connection manager encodes.
  repeated string response_headers_to_remove = 5 [
    (validate.rules).repeated = {items {string {well_known_regex: HTTP_HEADER_NAME strict: false}}}
  ];

  // Specifies a list of HTTP headers that should be added to each request
  // routed by the HTTP connection manager. Headers specified at this level are
  // applied after headers from any enclosed :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` or
  // :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. For more information, including details on
  // header value syntax, see the documentation on :ref:`custom request headers
  // <config_http_conn_man_headers_custom_request_headers>`.
  repeated core.v3.HeaderValueOption request_headers_to_add = 6
      [(validate.rules).repeated = {max_items: 1000}];

  // Specifies a list of HTTP headers that should be removed from each request
  // routed by the HTTP connection manager.
  repeated string request_headers_to_remove = 8 [
    (validate.rules).repeated = {items {string {well_known_regex: HTTP_HEADER_NAME strict: false}}}
  ];

  // Headers mutations at all levels are evaluated, if specified. By default, the order is from most
  // specific (i.e. route entry level) to least specific (i.e. route configuration level). Later header
  // mutations may override earlier mutations.
  // This order can be reversed by setting this field to true. In other words, most specific level mutation
  // is evaluated last.
  //
  bool most_specific_header_mutations_wins = 10;

  // An optional boolean that specifies whether the clusters that the route
  // table refers to will be validated by the cluster manager. If set to true
  // and a route refers to a non-existent cluster, the route table will not
  // load. If set to false and a route refers to a non-existent cluster, the
  // route table will load and the router filter will return a 404 if the route
  // is selected at runtime. This setting defaults to true if the route table
  // is statically defined via the :ref:`route_config
  // <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.route_config>`
  // option. This setting default to false if the route table is loaded dynamically via the
  // :ref:`rds
  // <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.rds>`
  // option. Users may wish to override the default behavior in certain cases (for example when
  // using CDS with a static route table).
  google.protobuf.BoolValue validate_clusters = 7;

  // The maximum bytes of the response :ref:`direct response body
  // <envoy_v3_api_field_config.route.v3.DirectResponseAction.body>` size. If not specified the default
  // is 4096.
  //
  // .. warning::
  //
  //   Envoy currently holds the content of :ref:`direct response body
  //   <envoy_v3_api_field_config.route.v3.DirectResponseAction.body>` in memory. Be careful setting
  //   this to be larger than the default 4KB, since the allocated memory for direct response body
  //   is not subject to data plane buffering controls.
  //
  google.protobuf.UInt32Value max_direct_response_body_size_bytes = 11;

  // A list of plugins and their configurations which may be used by a
  // :ref:`cluster specifier plugin name <envoy_v3_api_field_config.route.v3.RouteAction.cluster_specifier_plugin>`
  // within the route. All ``extension.name`` fields in this list must be unique.
  repeated ClusterSpecifierPlugin cluster_specifier_plugins = 12;

  // Specify a set of default request mirroring policies which apply to all routes under its virtual hosts.
  // Note that policies are not merged, the most specific non-empty one becomes the mirror policies.
  repeated RouteAction.RequestMirrorPolicy request_mirror_policies = 13;

  // By default, port in :authority header (if any) is used in host matching.
  // With this option enabled, Envoy will ignore the port number in the :authority header (if any) when picking VirtualHost.
  // NOTE: this option will not strip the port number (if any) contained in route config
  // :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`.domains field.
  bool ignore_port_in_host_matching = 14;

  // Ignore path-parameters in path-matching.
  // Before RFC3986, URI were like(RFC1808): <scheme>://<net_loc>/<path>;<params>?<query>#<fragment>
  // Envoy by default takes ":path" as "<path>;<params>".
  // For users who want to only match path on the "<path>" portion, this option should be true.
  bool ignore_path_parameters_in_path_matching = 15;

  // This field can be used to provide RouteConfiguration level per filter config. The key should match the
  // :ref:`filter config name
  // <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpFilter.name>`.
  // See :ref:`Http filter route specific config <arch_overview_http_filters_per_filter_config>`
  // for details.
  // [#comment: An entry's value may be wrapped in a
  // :ref:`FilterConfig<envoy_v3_api_msg_config.route.v3.FilterConfig>`
  // message to specify additional options.]
  map<string, google.protobuf.Any> typed_per_filter_config = 16;

  // The metadata field can be used to provide additional information
  // about the route configuration. It can be used for configuration, stats, and logging.
  // The metadata should go under the filter namespace that will need it.
  // For instance, if the metadata is intended for the Router filter,
  // the filter name should be specified as ``envoy.filters.http.router``.
  core.v3.Metadata metadata = 17;
}

message Vhds {
  option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Vhds";

  // Configuration source specifier for VHDS.
  core.v3.ConfigSource config_source = 1 [(validate.rules).message = {required: true}];
}
