syntax = "proto3";

package envoy.extensions.filters.http.header_to_metadata.v3;

import "envoy/type/matcher/v3/regex.proto";

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

option java_package = "io.envoyproxy.envoy.extensions.filters.http.header_to_metadata.v3";
option java_outer_classname = "HeaderToMetadataProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/header_to_metadata/v3;header_to_metadatav3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Header-To-Metadata Filter]
//
// The configuration for transforming headers into metadata. This is useful
// for matching load balancer subsets, logging, etc.
//
// Header to Metadata :ref:`configuration overview <config_http_filters_header_to_metadata>`.
// [#extension: envoy.filters.http.header_to_metadata]

message Config {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.config.filter.http.header_to_metadata.v2.Config";

  // Specifies the value type to use in metadata.
  enum ValueType {
    STRING = 0;

    NUMBER = 1;

    // The value is a serialized `protobuf.Value
    // <https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto#L62>`_.
    PROTOBUF_VALUE = 2;
  }

  // Specifies the encoding scheme for the value.
  enum ValueEncode {
    // No encoding is applied.
    NONE = 0;

    // The value is encoded in `Base64 <https://tools.ietf.org/html/rfc4648#section-4>`_.
    //
    // .. note::
    //
    //   This is mostly used for ``STRING`` and ``PROTOBUF_VALUE`` to escape the
    //   non-ASCII characters in the header.
    //
    BASE64 = 1;
  }

  // [#next-free-field: 7]
  message KeyValuePair {
    option (udpa.annotations.versioning).previous_message_type =
        "envoy.config.filter.http.header_to_metadata.v2.Config.KeyValuePair";

    // The namespace — if this is empty, the filter's namespace will be used.
    string metadata_namespace = 1;

    // The key to use within the namespace.
    string key = 2 [(validate.rules).string = {min_len: 1}];

    // The value to pair with the given key.
    //
    // When used for a
    // :ref:`on_header_present <envoy_v3_api_field_extensions.filters.http.header_to_metadata.v3.Config.Rule.on_header_present>`
    // case, if value is non-empty it'll be used instead of the header value. If both are empty, no metadata is added.
    //
    // When used for a :ref:`on_header_missing <envoy_v3_api_field_extensions.filters.http.header_to_metadata.v3.Config.Rule.on_header_missing>`
    // case, a non-empty value must be provided otherwise no metadata is added.
    string value = 3 [(udpa.annotations.field_migrate).oneof_promotion = "value_type"];

    // If present, the header's value will be matched and substituted with this. If there is no match or substitution, the header value
    // is used as-is.
    //
    // This is only used for :ref:`on_header_present <envoy_v3_api_field_extensions.filters.http.header_to_metadata.v3.Config.Rule.on_header_present>`.
    //
    // .. note::
    //
    //   If the ``value`` field is non-empty this field should be empty.
    //
    type.matcher.v3.RegexMatchAndSubstitute regex_value_rewrite = 6
        [(udpa.annotations.field_migrate).oneof_promotion = "value_type"];

    // The value's type — defaults to string.
    ValueType type = 4 [(validate.rules).enum = {defined_only: true}];

    // How is the value encoded, default is NONE (not encoded).
    // The value will be decoded accordingly before storing to metadata.
    ValueEncode encode = 5;
  }

  // A Rule defines what metadata to apply when a header is present or missing.
  // [#next-free-field: 6]
  message Rule {
    option (udpa.annotations.versioning).previous_message_type =
        "envoy.config.filter.http.header_to_metadata.v2.Config.Rule";

    // Specifies that a match will be performed on the value of a header or a cookie.
    //
    // The header to be extracted.
    string header = 1 [
      (validate.rules).string = {well_known_regex: HTTP_HEADER_NAME strict: false},
      (udpa.annotations.field_migrate).oneof_promotion = "header_cookie_specifier"
    ];

    // The cookie to be extracted.
    string cookie = 5 [
      (validate.rules).string = {well_known_regex: HTTP_HEADER_NAME strict: false},
      (udpa.annotations.field_migrate).oneof_promotion = "header_cookie_specifier"
    ];

    // If the header or cookie is present, apply this metadata ``KeyValuePair``.
    //
    // If the value in the ``KeyValuePair`` is non-empty, it'll be used instead
    // of the header or cookie value.
    KeyValuePair on_header_present = 2 [(udpa.annotations.field_migrate).rename = "on_present"];

    // If the header or cookie is not present, apply this metadata ``KeyValuePair``.
    //
    // The value in the ``KeyValuePair`` must be set, since it'll be used in lieu
    // of the missing header or cookie value.
    KeyValuePair on_header_missing = 3 [(udpa.annotations.field_migrate).rename = "on_missing"];

    // Whether or not to remove the header after a rule is applied.
    //
    // This prevents headers from leaking.
    // This field is not supported in case of a cookie.
    bool remove = 4;
  }

  // The list of rules to apply to requests.
  repeated Rule request_rules = 1;

  // The list of rules to apply to responses.
  repeated Rule response_rules = 2;

  // Optional prefix to use when emitting filter statistics. When configured,
  // statistics are emitted with the prefix ``http_filter_name.<stat_prefix>``.
  //
  // This emits statistics such as:
  //
  // - ``http_filter_name.my_header_converter.rules_processed``
  // - ``http_filter_name.my_header_converter.metadata_added``
  //
  // If not configured, no statistics are emitted.
  string stat_prefix = 3;
}
