// 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.extensions.filters.http.compressor.v3;

import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/extension.proto";

import "google/protobuf/wrappers.proto";

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

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

// [#protodoc-title: Compressor]
// Compressor :ref:`configuration overview <config_http_filters_compressor>`.
// [#extension: envoy.filters.http.compressor]

// [#next-free-field: 10]
message Compressor {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.config.filter.http.compressor.v2.Compressor";

  message CommonDirectionConfig {
    // Runtime flag that controls whether compression is enabled or not for the direction this
    // common config is put in. If set to false, the filter will operate as a pass-through filter
    // in the chosen direction, unless overridden by CompressorPerRoute.
    // If the field is omitted, the filter will be enabled.
    config.core.v3.RuntimeFeatureFlag enabled = 1;

    // Minimum value of Content-Length header of request or response messages (depending on the direction
    // this common config is put in), in bytes, which will trigger compression. The default value is 30.
    google.protobuf.UInt32Value min_content_length = 2;

    // Set of strings that allows specifying which mime-types yield compression; e.g.,
    // application/json, text/html, etc. When this field is not defined, compression will be applied
    // to the following mime-types: "application/javascript", "application/json",
    // "application/xhtml+xml", "image/svg+xml", "text/css", "text/html", "text/plain", "text/xml"
    // and their synonyms.
    repeated string content_type = 3;
  }

  // Configuration for filter behavior on the request direction.
  message RequestDirectionConfig {
    CommonDirectionConfig common_config = 1;
  }

  // Configuration for filter behavior on the response direction.
  message ResponseDirectionConfig {
    CommonDirectionConfig common_config = 1;

    // If true, disables compression when the response contains an etag header. When it is false, the
    // filter will preserve weak etags and remove the ones that require strong validation.
    bool disable_on_etag_header = 2;

    // If true, removes accept-encoding from the request headers before dispatching it to the upstream
    // so that responses do not get compressed before reaching the filter.
    //
    // .. attention::
    //
    //    To avoid interfering with other compression filters in the same chain use this option in
    //    the filter closest to the upstream.
    bool remove_accept_encoding_header = 3;

    // Set of response codes for which compression is disabled, e.g. 206 Partial Content should not
    // be compressed.
    repeated uint32 uncompressible_response_codes = 4 [(validate.rules).repeated = {
      unique: true
      items {uint32 {lt: 600 gte: 200}}
    }];
  }

  // Minimum response length, in bytes, which will trigger compression. The default value is 30.
  google.protobuf.UInt32Value content_length = 1
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // Set of strings that allows specifying which mime-types yield compression; e.g.,
  // application/json, text/html, etc. When this field is not defined, compression will be applied
  // to the following mime-types: "application/javascript", "application/json",
  // "application/xhtml+xml", "image/svg+xml", "text/css", "text/html", "text/plain", "text/xml"
  // and their synonyms.
  repeated string content_type = 2
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // If true, disables compression when the response contains an etag header. When it is false, the
  // filter will preserve weak etags and remove the ones that require strong validation.
  bool disable_on_etag_header = 3
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // If true, removes accept-encoding from the request headers before dispatching it to the upstream
  // so that responses do not get compressed before reaching the filter.
  //
  // .. attention::
  //
  //    To avoid interfering with other compression filters in the same chain use this option in
  //    the filter closest to the upstream.
  bool remove_accept_encoding_header = 4
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // Runtime flag that controls whether the filter is enabled or not. If set to false, the
  // filter will operate as a pass-through filter, unless overridden by
  // CompressorPerRoute. If not specified, defaults to enabled.
  config.core.v3.RuntimeFeatureFlag runtime_enabled = 5
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // A compressor library to use for compression. Currently only
  // :ref:`envoy.compression.gzip.compressor<envoy_v3_api_msg_extensions.compression.gzip.compressor.v3.Gzip>`
  // is included in Envoy.
  // [#extension-category: envoy.compression.compressor]
  config.core.v3.TypedExtensionConfig compressor_library = 6
      [(validate.rules).message = {required: true}];

  // Configuration for request compression. Compression is disabled by default if left empty.
  RequestDirectionConfig request_direction_config = 7;

  // Configuration for response compression. Compression is enabled by default if left empty.
  //
  // .. attention::
  //
  //    If the field is not empty then the duplicate deprecated fields of the ``Compressor`` message,
  //    such as ``content_length``, ``content_type``, ``disable_on_etag_header``,
  //    ``remove_accept_encoding_header`` and ``runtime_enabled``, are ignored.
  //
  //    Also all the statistics related to response compression will be rooted in
  //    ``<stat_prefix>.compressor.<compressor_library.name>.<compressor_library_stat_prefix>.response.*``
  //    instead of
  //    ``<stat_prefix>.compressor.<compressor_library.name>.<compressor_library_stat_prefix>.*``.
  ResponseDirectionConfig response_direction_config = 8;

  // If true, chooses this compressor first to do compression when the q-values in ``Accept-Encoding`` are same.
  // The last compressor which enables choose_first will be chosen if multiple compressor filters in the chain have choose_first as true.
  bool choose_first = 9;
}

// Per-route overrides of ``ResponseDirectionConfig``. Anything added here should be optional,
// to allow overriding arbitrary subsets of configuration. Omitted fields must have no effect.
message ResponseDirectionOverrides {
  // If set, overrides the filter-level
  // :ref:`remove_accept_encoding_header<envoy_v3_api_field_extensions.filters.http.compressor.v3.Compressor.ResponseDirectionConfig.remove_accept_encoding_header>`.
  google.protobuf.BoolValue remove_accept_encoding_header = 1;
}

// Per-route overrides. As per-route overrides are needed, they should be
// added here, mirroring the structure of ``Compressor``. All fields should be
// optional, to allow overriding arbitrary subsets of configuration.
message CompressorOverrides {
  // If present, response compression is enabled.
  ResponseDirectionOverrides response_direction_config = 1;
}

message CompressorPerRoute {
  oneof override {
    option (validate.required) = true;

    // If set, the filter will operate as a pass-through filter.
    // Overrides Compressor.runtime_enabled and CommonDirectionConfig.enabled.
    bool disabled = 1 [(validate.rules).bool = {const: true}];

    // Per-route overrides. Fields set here will override corresponding fields in ``Compressor``.
    CompressorOverrides overrides = 2;
  }
}
