1 // 2 // 3 // Copyright 2020 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPC_SRC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_COMPRESSION_FILTER_H 20 #define GRPC_SRC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_COMPRESSION_FILTER_H 21 22 #include <grpc/impl/compression_types.h> 23 #include <grpc/support/port_platform.h> 24 #include <stddef.h> 25 #include <stdint.h> 26 27 #include "absl/status/statusor.h" 28 #include "absl/strings/string_view.h" 29 #include "absl/types/optional.h" 30 #include "src/core/lib/channel/channel_args.h" 31 #include "src/core/lib/channel/channel_fwd.h" 32 #include "src/core/lib/channel/promise_based_filter.h" 33 #include "src/core/lib/compression/compression_internal.h" 34 #include "src/core/lib/promise/arena_promise.h" 35 #include "src/core/lib/transport/metadata_batch.h" 36 #include "src/core/lib/transport/transport.h" 37 38 namespace grpc_core { 39 40 /// Compression filter for messages. 41 /// 42 /// See <grpc/compression.h> for the available compression settings. 43 /// 44 /// Compression settings may come from: 45 /// - Channel configuration, as established at channel creation time. 46 /// - The metadata accompanying the outgoing data to be compressed. This is 47 /// taken as a request only. We may choose not to honor it. The metadata key 48 /// is given by \a GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY. 49 /// 50 /// Compression can be disabled for concrete messages (for instance in order to 51 /// prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set 52 /// in the MessageHandle flags. 53 /// 54 /// The attempted compression mechanism is added to the resulting initial 55 /// metadata under the 'grpc-encoding' key. 56 /// 57 /// If compression is actually performed, the MessageHandle's flag is modified 58 /// to incorporate GRPC_WRITE_INTERNAL_COMPRESS. Otherwise, and regardless of 59 /// the aforementioned 'grpc-encoding' metadata value, data will pass through 60 /// uncompressed. 61 62 class ChannelCompression { 63 public: 64 explicit ChannelCompression(const ChannelArgs& args); 65 66 struct DecompressArgs { 67 grpc_compression_algorithm algorithm; 68 absl::optional<uint32_t> max_recv_message_length; 69 }; 70 default_compression_algorithm()71 grpc_compression_algorithm default_compression_algorithm() const { 72 return default_compression_algorithm_; 73 } 74 enabled_compression_algorithms()75 CompressionAlgorithmSet enabled_compression_algorithms() const { 76 return enabled_compression_algorithms_; 77 } 78 79 grpc_compression_algorithm HandleOutgoingMetadata( 80 grpc_metadata_batch& outgoing_metadata); 81 DecompressArgs HandleIncomingMetadata( 82 const grpc_metadata_batch& incoming_metadata); 83 84 // Compress one message synchronously. 85 MessageHandle CompressMessage(MessageHandle message, 86 grpc_compression_algorithm algorithm) const; 87 // Decompress one message synchronously. 88 absl::StatusOr<MessageHandle> DecompressMessage(bool is_client, 89 MessageHandle message, 90 DecompressArgs args) const; 91 92 private: 93 // Max receive message length, if set. 94 absl::optional<uint32_t> max_recv_size_; 95 size_t message_size_service_config_parser_index_; 96 // The default, channel-level, compression algorithm. 97 grpc_compression_algorithm default_compression_algorithm_; 98 // Enabled compression algorithms. 99 CompressionAlgorithmSet enabled_compression_algorithms_; 100 // Is compression enabled? 101 bool enable_compression_; 102 // Is decompression enabled? 103 bool enable_decompression_; 104 }; 105 106 class ClientCompressionFilter final 107 : public ImplementChannelFilter<ClientCompressionFilter> { 108 public: 109 static const grpc_channel_filter kFilter; 110 TypeName()111 static absl::string_view TypeName() { return "compression"; } 112 113 static absl::StatusOr<std::unique_ptr<ClientCompressionFilter>> Create( 114 const ChannelArgs& args, ChannelFilter::Args filter_args); 115 ClientCompressionFilter(const ChannelArgs & args)116 explicit ClientCompressionFilter(const ChannelArgs& args) 117 : compression_engine_(args) {} 118 119 // Construct a promise for one call. 120 class Call { 121 public: 122 void OnClientInitialMetadata(ClientMetadata& md, 123 ClientCompressionFilter* filter); 124 MessageHandle OnClientToServerMessage(MessageHandle message, 125 ClientCompressionFilter* filter); 126 127 void OnServerInitialMetadata(ServerMetadata& md, 128 ClientCompressionFilter* filter); 129 absl::StatusOr<MessageHandle> OnServerToClientMessage( 130 MessageHandle message, ClientCompressionFilter* filter); 131 132 static const NoInterceptor OnClientToServerHalfClose; 133 static const NoInterceptor OnServerTrailingMetadata; 134 static const NoInterceptor OnFinalize; 135 136 private: 137 grpc_compression_algorithm compression_algorithm_; 138 ChannelCompression::DecompressArgs decompress_args_; 139 }; 140 141 private: 142 ChannelCompression compression_engine_; 143 }; 144 145 class ServerCompressionFilter final 146 : public ImplementChannelFilter<ServerCompressionFilter> { 147 public: 148 static const grpc_channel_filter kFilter; 149 TypeName()150 static absl::string_view TypeName() { return "compression"; } 151 152 static absl::StatusOr<std::unique_ptr<ServerCompressionFilter>> Create( 153 const ChannelArgs& args, ChannelFilter::Args filter_args); 154 ServerCompressionFilter(const ChannelArgs & args)155 explicit ServerCompressionFilter(const ChannelArgs& args) 156 : compression_engine_(args) {} 157 158 // Construct a promise for one call. 159 class Call { 160 public: 161 void OnClientInitialMetadata(ClientMetadata& md, 162 ServerCompressionFilter* filter); 163 absl::StatusOr<MessageHandle> OnClientToServerMessage( 164 MessageHandle message, ServerCompressionFilter* filter); 165 166 void OnServerInitialMetadata(ServerMetadata& md, 167 ServerCompressionFilter* filter); 168 MessageHandle OnServerToClientMessage(MessageHandle message, 169 ServerCompressionFilter* filter); 170 171 static const NoInterceptor OnClientToServerHalfClose; 172 static const NoInterceptor OnServerTrailingMetadata; 173 static const NoInterceptor OnFinalize; 174 175 private: 176 ChannelCompression::DecompressArgs decompress_args_; 177 grpc_compression_algorithm compression_algorithm_; 178 }; 179 180 private: 181 ChannelCompression compression_engine_; 182 }; 183 184 } // namespace grpc_core 185 186 #endif // GRPC_SRC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_COMPRESSION_FILTER_H 187