grpc 1.54.0 → 1.54.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

@@ -105,7 +105,9 @@ class HPackParser {
105
105
  class String;
106
106
 
107
107
  grpc_error_handle ParseInput(Input input, bool is_last);
108
- bool ParseInputInner(Input* input, bool is_last);
108
+ void ParseInputInner(Input* input);
109
+ GPR_ATTRIBUTE_NOINLINE
110
+ void HandleMetadataSoftSizeLimitExceeded(Input* input);
109
111
 
110
112
  // Target metadata buffer
111
113
  grpc_metadata_batch* metadata_buffer_ = nullptr;
@@ -82,8 +82,8 @@ void HPackTable::MementoRingBuffer::Rebuild(uint32_t max_entries) {
82
82
  // Evict one element from the table
83
83
  void HPackTable::EvictOne() {
84
84
  auto first_entry = entries_.PopOne();
85
- GPR_ASSERT(first_entry.transport_size() <= mem_used_);
86
- mem_used_ -= first_entry.transport_size();
85
+ GPR_ASSERT(first_entry.md.transport_size() <= mem_used_);
86
+ mem_used_ -= first_entry.md.transport_size();
87
87
  }
88
88
 
89
89
  void HPackTable::SetMaxBytes(uint32_t max_bytes) {
@@ -104,7 +104,7 @@ grpc_error_handle HPackTable::SetCurrentTableSize(uint32_t bytes) {
104
104
  return absl::OkStatus();
105
105
  }
106
106
  if (bytes > max_bytes_) {
107
- return GRPC_ERROR_CREATE(absl::StrFormat(
107
+ return absl::InternalError(absl::StrFormat(
108
108
  "Attempt to make hpack table %d bytes when max is %d bytes", bytes,
109
109
  max_bytes_));
110
110
  }
@@ -130,7 +130,7 @@ grpc_error_handle HPackTable::Add(Memento md) {
130
130
  }
131
131
 
132
132
  // we can't add elements bigger than the max table size
133
- if (md.transport_size() > current_table_bytes_) {
133
+ if (md.md.transport_size() > current_table_bytes_) {
134
134
  // HPACK draft 10 section 4.4 states:
135
135
  // If the size of the new entry is less than or equal to the maximum
136
136
  // size, that entry is added to the table. It is not an error to
@@ -145,13 +145,13 @@ grpc_error_handle HPackTable::Add(Memento md) {
145
145
  }
146
146
 
147
147
  // evict entries to ensure no overflow
148
- while (md.transport_size() >
148
+ while (md.md.transport_size() >
149
149
  static_cast<size_t>(current_table_bytes_) - mem_used_) {
150
150
  EvictOne();
151
151
  }
152
152
 
153
153
  // copy the finalized entry in
154
- mem_used_ += md.transport_size();
154
+ mem_used_ += md.md.transport_size();
155
155
  entries_.Put(std::move(md));
156
156
  return absl::OkStatus();
157
157
  }
@@ -228,12 +228,14 @@ const StaticTableEntry kStaticTable[hpack_constants::kLastStaticEntry] = {
228
228
 
229
229
  HPackTable::Memento MakeMemento(size_t i) {
230
230
  auto sm = kStaticTable[i];
231
- return grpc_metadata_batch::Parse(
232
- sm.key, Slice::FromStaticString(sm.value),
233
- strlen(sm.key) + strlen(sm.value) + hpack_constants::kEntryOverhead,
234
- [](absl::string_view, const Slice&) {
235
- abort(); // not expecting to see this
236
- });
231
+ return HPackTable::Memento{
232
+ grpc_metadata_batch::Parse(
233
+ sm.key, Slice::FromStaticString(sm.value),
234
+ strlen(sm.key) + strlen(sm.value) + hpack_constants::kEntryOverhead,
235
+ [](absl::string_view, const Slice&) {
236
+ abort(); // not expecting to see this
237
+ }),
238
+ absl::OkStatus()};
237
239
  }
238
240
 
239
241
  } // namespace
@@ -25,6 +25,8 @@
25
25
 
26
26
  #include <vector>
27
27
 
28
+ #include "absl/status/status.h"
29
+
28
30
  #include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
29
31
  #include "src/core/lib/gprpp/no_destruct.h"
30
32
  #include "src/core/lib/iomgr/error.h"
@@ -45,7 +47,10 @@ class HPackTable {
45
47
  void SetMaxBytes(uint32_t max_bytes);
46
48
  grpc_error_handle SetCurrentTableSize(uint32_t bytes);
47
49
 
48
- using Memento = ParsedMetadata<grpc_metadata_batch>;
50
+ struct Memento {
51
+ ParsedMetadata<grpc_metadata_batch> md;
52
+ absl::Status parse_status;
53
+ };
49
54
 
50
55
  // Lookup, but don't ref.
51
56
  const Memento* Lookup(uint32_t index) const {
@@ -68,6 +73,9 @@ class HPackTable {
68
73
  // Current entry count in the table.
69
74
  uint32_t num_entries() const { return entries_.num_entries(); }
70
75
 
76
+ // Current size of the table.
77
+ uint32_t test_only_table_size() const { return mem_used_; }
78
+
71
79
  private:
72
80
  struct StaticMementos {
73
81
  StaticMementos();
@@ -20,10 +20,10 @@
20
20
  namespace grpc_event_engine {
21
21
  namespace experimental {
22
22
 
23
- constexpr EventEngine::TaskHandle EventEngine::TaskHandle::kInvalid = {-1, -1};
24
- constexpr EventEngine::ConnectionHandle
25
- EventEngine::ConnectionHandle::kInvalid = {-1, -1};
26
- constexpr EventEngine::DNSResolver::LookupTaskHandle
23
+ const EventEngine::TaskHandle EventEngine::TaskHandle::kInvalid = {-1, -1};
24
+ const EventEngine::ConnectionHandle EventEngine::ConnectionHandle::kInvalid = {
25
+ -1, -1};
26
+ const EventEngine::DNSResolver::LookupTaskHandle
27
27
  EventEngine::DNSResolver::LookupTaskHandle::kInvalid = {-1, -1};
28
28
 
29
29
  bool operator==(const EventEngine::TaskHandle& lhs,
@@ -21,46 +21,20 @@
21
21
  #include "src/core/lib/surface/validate_metadata.h"
22
22
 
23
23
  #include "absl/status/status.h"
24
+ #include "absl/strings/escaping.h"
25
+ #include "absl/strings/str_cat.h"
24
26
  #include "absl/strings/string_view.h"
25
27
 
26
28
  #include <grpc/grpc.h>
27
29
 
28
- #include "src/core/lib/gpr/string.h"
29
30
  #include "src/core/lib/gprpp/bitset.h"
30
- #include "src/core/lib/gprpp/memory.h"
31
- #include "src/core/lib/gprpp/status_helper.h"
32
31
  #include "src/core/lib/iomgr/error.h"
32
+ #include "src/core/lib/slice/slice_internal.h"
33
33
 
34
- static grpc_error_handle conforms_to(const grpc_slice& slice,
35
- const grpc_core::BitSet<256>& legal_bits,
36
- const char* err_desc) {
37
- const uint8_t* p = GRPC_SLICE_START_PTR(slice);
38
- const uint8_t* e = GRPC_SLICE_END_PTR(slice);
39
- for (; p != e; p++) {
40
- if (!legal_bits.is_set(*p)) {
41
- size_t len;
42
- grpc_core::UniquePtr<char> ptr(gpr_dump_return_len(
43
- reinterpret_cast<const char*> GRPC_SLICE_START_PTR(slice),
44
- GRPC_SLICE_LENGTH(slice), GPR_DUMP_HEX | GPR_DUMP_ASCII, &len));
45
- grpc_error_handle error = grpc_error_set_str(
46
- grpc_error_set_int(GRPC_ERROR_CREATE(err_desc),
47
- grpc_core::StatusIntProperty::kOffset,
48
- p - GRPC_SLICE_START_PTR(slice)),
49
- grpc_core::StatusStrProperty::kRawBytes,
50
- absl::string_view(ptr.get(), len));
51
- return error;
52
- }
53
- }
54
- return absl::OkStatus();
55
- }
56
-
57
- static int error2int(grpc_error_handle error) {
58
- int r = (error.ok());
59
- return r;
60
- }
34
+ namespace grpc_core {
61
35
 
62
36
  namespace {
63
- class LegalHeaderKeyBits : public grpc_core::BitSet<256> {
37
+ class LegalHeaderKeyBits : public BitSet<256> {
64
38
  public:
65
39
  constexpr LegalHeaderKeyBits() {
66
40
  for (int i = 'a'; i <= 'z'; i++) set(i);
@@ -71,19 +45,45 @@ class LegalHeaderKeyBits : public grpc_core::BitSet<256> {
71
45
  }
72
46
  };
73
47
  constexpr LegalHeaderKeyBits g_legal_header_key_bits;
74
- } // namespace
75
48
 
76
- grpc_error_handle grpc_validate_header_key_is_legal(const grpc_slice& slice) {
77
- if (GRPC_SLICE_LENGTH(slice) == 0) {
78
- return GRPC_ERROR_CREATE("Metadata keys cannot be zero length");
49
+ GPR_ATTRIBUTE_NOINLINE
50
+ absl::Status DoesNotConformTo(absl::string_view x, const char* err_desc) {
51
+ return absl::InternalError(absl::StrCat(err_desc, ": ", x, " (hex ",
52
+ absl::BytesToHexString(x), ")"));
53
+ }
54
+
55
+ absl::Status ConformsTo(absl::string_view x, const BitSet<256>& legal_bits,
56
+ const char* err_desc) {
57
+ for (uint8_t c : x) {
58
+ if (!legal_bits.is_set(c)) {
59
+ return DoesNotConformTo(x, err_desc);
60
+ }
79
61
  }
80
- if (GRPC_SLICE_LENGTH(slice) > UINT32_MAX) {
81
- return GRPC_ERROR_CREATE("Metadata keys cannot be larger than UINT32_MAX");
62
+ return absl::OkStatus();
63
+ }
64
+ } // namespace
65
+
66
+ absl::Status ValidateHeaderKeyIsLegal(absl::string_view key) {
67
+ if (key.empty()) {
68
+ return absl::InternalError("Metadata keys cannot be zero length");
82
69
  }
83
- if (GRPC_SLICE_START_PTR(slice)[0] == ':') {
84
- return GRPC_ERROR_CREATE("Metadata keys cannot start with :");
70
+ if (key.size() > UINT32_MAX) {
71
+ return absl::InternalError(
72
+ "Metadata keys cannot be larger than UINT32_MAX");
85
73
  }
86
- return conforms_to(slice, g_legal_header_key_bits, "Illegal header key");
74
+ return ConformsTo(key, g_legal_header_key_bits, "Illegal header key");
75
+ }
76
+
77
+ } // namespace grpc_core
78
+
79
+ static int error2int(grpc_error_handle error) {
80
+ int r = (error.ok());
81
+ return r;
82
+ }
83
+
84
+ grpc_error_handle grpc_validate_header_key_is_legal(const grpc_slice& slice) {
85
+ return grpc_core::ValidateHeaderKeyIsLegal(
86
+ grpc_core::StringViewFromSlice(slice));
87
87
  }
88
88
 
89
89
  int grpc_header_key_is_legal(grpc_slice slice) {
@@ -104,8 +104,9 @@ constexpr LegalHeaderNonBinValueBits g_legal_header_non_bin_value_bits;
104
104
 
105
105
  grpc_error_handle grpc_validate_header_nonbin_value_is_legal(
106
106
  const grpc_slice& slice) {
107
- return conforms_to(slice, g_legal_header_non_bin_value_bits,
108
- "Illegal header value");
107
+ return grpc_core::ConformsTo(grpc_core::StringViewFromSlice(slice),
108
+ g_legal_header_non_bin_value_bits,
109
+ "Illegal header value");
109
110
  }
110
111
 
111
112
  int grpc_header_nonbin_value_is_legal(grpc_slice slice) {
@@ -25,11 +25,20 @@
25
25
 
26
26
  #include <cstring>
27
27
 
28
+ #include "absl/status/status.h"
29
+ #include "absl/strings/string_view.h"
30
+
28
31
  #include <grpc/slice.h>
29
32
  #include <grpc/support/log.h>
30
33
 
31
34
  #include "src/core/lib/iomgr/error.h"
32
35
 
36
+ namespace grpc_core {
37
+
38
+ absl::Status ValidateHeaderKeyIsLegal(absl::string_view key);
39
+
40
+ }
41
+
33
42
  grpc_error_handle grpc_validate_header_key_is_legal(const grpc_slice& slice);
34
43
  grpc_error_handle grpc_validate_header_nonbin_value_is_legal(
35
44
  const grpc_slice& slice);
@@ -50,6 +50,50 @@
50
50
 
51
51
  namespace grpc_core {
52
52
 
53
+ ///////////////////////////////////////////////////////////////////////////////
54
+ // Compression traits.
55
+ //
56
+ // Each metadata trait exposes exactly one compression trait.
57
+ // This type directs how transports might choose to compress the metadata.
58
+ // Adding a value here typically involves editing all transports to support the
59
+ // trait, and so should not be done lightly.
60
+
61
+ // No compression.
62
+ struct NoCompressionCompressor {};
63
+
64
+ // Expect a single value for this metadata key, but we don't know apriori its
65
+ // value.
66
+ // It's ok if it changes over time, but it should be mostly stable.
67
+ // This is used for things like user-agent, which is expected to be the same
68
+ // for all requests.
69
+ struct StableValueCompressor {};
70
+
71
+ // Expect a single value for this metadata key, and we know apriori its value.
72
+ template <typename T, T value>
73
+ struct KnownValueCompressor {};
74
+
75
+ // Values are uncompressible, but expect the key to be in most requests and try
76
+ // and compress that.
77
+ struct FrequentKeyWithNoValueCompressionCompressor {};
78
+
79
+ // Expect a small set of values for this metadata key.
80
+ struct SmallSetOfValuesCompressor {};
81
+
82
+ // Expect integral values up to N for this metadata key.
83
+ template <size_t N>
84
+ struct SmallIntegralValuesCompressor {};
85
+
86
+ // Specialty compressor for grpc-timeout metadata.
87
+ struct TimeoutCompressor {};
88
+
89
+ // Specialty compressors for HTTP/2 psuedo headers.
90
+ struct HttpSchemeCompressor {};
91
+ struct HttpMethodCompressor {};
92
+ struct HttpStatusCompressor {};
93
+
94
+ ///////////////////////////////////////////////////////////////////////////////
95
+ // Metadata traits
96
+
53
97
  // Given a metadata key and a value, return the encoded size.
54
98
  // Defaults to calling the key's Encode() method and then calculating the size
55
99
  // of that, but can be overridden for specific keys if there's a better way of
@@ -71,6 +115,7 @@ struct GrpcTimeoutMetadata {
71
115
  static constexpr bool kRepeatable = false;
72
116
  using ValueType = Timestamp;
73
117
  using MementoType = Duration;
118
+ using CompressionTraits = TimeoutCompressor;
74
119
  static absl::string_view key() { return "grpc-timeout"; }
75
120
  static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error);
76
121
  static ValueType MementoToValue(MementoType timeout);
@@ -90,6 +135,7 @@ struct TeMetadata {
90
135
  kInvalid,
91
136
  };
92
137
  using MementoType = ValueType;
138
+ using CompressionTraits = KnownValueCompressor<ValueType, kTrailers>;
93
139
  static absl::string_view key() { return "te"; }
94
140
  static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error);
95
141
  static ValueType MementoToValue(MementoType te) { return te; }
@@ -117,6 +163,7 @@ struct ContentTypeMetadata {
117
163
  kInvalid,
118
164
  };
119
165
  using MementoType = ValueType;
166
+ using CompressionTraits = KnownValueCompressor<ValueType, kApplicationGrpc>;
120
167
  static absl::string_view key() { return "content-type"; }
121
168
  static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error);
122
169
  static ValueType MementoToValue(MementoType content_type) {
@@ -139,6 +186,7 @@ struct HttpSchemeMetadata {
139
186
  kInvalid,
140
187
  };
141
188
  using MementoType = ValueType;
189
+ using CompressionTraits = HttpSchemeCompressor;
142
190
  static absl::string_view key() { return ":scheme"; }
143
191
  static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error) {
144
192
  return Parse(value.as_string_view(), on_error);
@@ -167,6 +215,7 @@ struct HttpMethodMetadata {
167
215
  kInvalid,
168
216
  };
169
217
  using MementoType = ValueType;
218
+ using CompressionTraits = HttpMethodCompressor;
170
219
  static absl::string_view key() { return ":method"; }
171
220
  static MementoType ParseMemento(Slice value, MetadataParseErrorFn on_error);
172
221
  static ValueType MementoToValue(MementoType content_type) {
@@ -203,12 +252,15 @@ struct CompressionAlgorithmBasedMetadata {
203
252
  // grpc-encoding metadata trait.
204
253
  struct GrpcEncodingMetadata : public CompressionAlgorithmBasedMetadata {
205
254
  static constexpr bool kRepeatable = false;
255
+ using CompressionTraits =
256
+ SmallIntegralValuesCompressor<GRPC_COMPRESS_ALGORITHMS_COUNT>;
206
257
  static absl::string_view key() { return "grpc-encoding"; }
207
258
  };
208
259
 
209
260
  // grpc-internal-encoding-request metadata trait.
210
261
  struct GrpcInternalEncodingRequest : public CompressionAlgorithmBasedMetadata {
211
262
  static constexpr bool kRepeatable = false;
263
+ using CompressionTraits = NoCompressionCompressor;
212
264
  static absl::string_view key() { return "grpc-internal-encoding-request"; }
213
265
  };
214
266
 
@@ -218,6 +270,7 @@ struct GrpcAcceptEncodingMetadata {
218
270
  static absl::string_view key() { return "grpc-accept-encoding"; }
219
271
  using ValueType = CompressionAlgorithmSet;
220
272
  using MementoType = ValueType;
273
+ using CompressionTraits = StableValueCompressor;
221
274
  static MementoType ParseMemento(Slice value, MetadataParseErrorFn) {
222
275
  return CompressionAlgorithmSet::FromString(value.as_string_view());
223
276
  }
@@ -248,54 +301,63 @@ struct SimpleSliceBasedMetadata {
248
301
  // user-agent metadata trait.
249
302
  struct UserAgentMetadata : public SimpleSliceBasedMetadata {
250
303
  static constexpr bool kRepeatable = false;
304
+ using CompressionTraits = StableValueCompressor;
251
305
  static absl::string_view key() { return "user-agent"; }
252
306
  };
253
307
 
254
308
  // grpc-message metadata trait.
255
309
  struct GrpcMessageMetadata : public SimpleSliceBasedMetadata {
256
310
  static constexpr bool kRepeatable = false;
311
+ using CompressionTraits = NoCompressionCompressor;
257
312
  static absl::string_view key() { return "grpc-message"; }
258
313
  };
259
314
 
260
315
  // host metadata trait.
261
316
  struct HostMetadata : public SimpleSliceBasedMetadata {
262
317
  static constexpr bool kRepeatable = false;
318
+ using CompressionTraits = NoCompressionCompressor;
263
319
  static absl::string_view key() { return "host"; }
264
320
  };
265
321
 
266
322
  // endpoint-load-metrics-bin metadata trait.
267
323
  struct EndpointLoadMetricsBinMetadata : public SimpleSliceBasedMetadata {
268
324
  static constexpr bool kRepeatable = false;
325
+ using CompressionTraits = NoCompressionCompressor;
269
326
  static absl::string_view key() { return "endpoint-load-metrics-bin"; }
270
327
  };
271
328
 
272
329
  // grpc-server-stats-bin metadata trait.
273
330
  struct GrpcServerStatsBinMetadata : public SimpleSliceBasedMetadata {
274
331
  static constexpr bool kRepeatable = false;
332
+ using CompressionTraits = NoCompressionCompressor;
275
333
  static absl::string_view key() { return "grpc-server-stats-bin"; }
276
334
  };
277
335
 
278
336
  // grpc-trace-bin metadata trait.
279
337
  struct GrpcTraceBinMetadata : public SimpleSliceBasedMetadata {
280
338
  static constexpr bool kRepeatable = false;
339
+ using CompressionTraits = FrequentKeyWithNoValueCompressionCompressor;
281
340
  static absl::string_view key() { return "grpc-trace-bin"; }
282
341
  };
283
342
 
284
343
  // grpc-tags-bin metadata trait.
285
344
  struct GrpcTagsBinMetadata : public SimpleSliceBasedMetadata {
286
345
  static constexpr bool kRepeatable = false;
346
+ using CompressionTraits = FrequentKeyWithNoValueCompressionCompressor;
287
347
  static absl::string_view key() { return "grpc-tags-bin"; }
288
348
  };
289
349
 
290
350
  // :authority metadata trait.
291
351
  struct HttpAuthorityMetadata : public SimpleSliceBasedMetadata {
292
352
  static constexpr bool kRepeatable = false;
353
+ using CompressionTraits = SmallSetOfValuesCompressor;
293
354
  static absl::string_view key() { return ":authority"; }
294
355
  };
295
356
 
296
357
  // :path metadata trait.
297
358
  struct HttpPathMetadata : public SimpleSliceBasedMetadata {
298
359
  static constexpr bool kRepeatable = false;
360
+ using CompressionTraits = SmallSetOfValuesCompressor;
299
361
  static absl::string_view key() { return ":path"; }
300
362
  };
301
363
 
@@ -329,6 +391,7 @@ struct SimpleIntBasedMetadata : public SimpleIntBasedMetadataBase<Int> {
329
391
  struct GrpcStatusMetadata
330
392
  : public SimpleIntBasedMetadata<grpc_status_code, GRPC_STATUS_UNKNOWN> {
331
393
  static constexpr bool kRepeatable = false;
394
+ using CompressionTraits = SmallIntegralValuesCompressor<16>;
332
395
  static absl::string_view key() { return "grpc-status"; }
333
396
  };
334
397
 
@@ -336,6 +399,7 @@ struct GrpcStatusMetadata
336
399
  struct GrpcPreviousRpcAttemptsMetadata
337
400
  : public SimpleIntBasedMetadata<uint32_t, 0> {
338
401
  static constexpr bool kRepeatable = false;
402
+ using CompressionTraits = NoCompressionCompressor;
339
403
  static absl::string_view key() { return "grpc-previous-rpc-attempts"; }
340
404
  };
341
405
 
@@ -345,6 +409,7 @@ struct GrpcRetryPushbackMsMetadata {
345
409
  static absl::string_view key() { return "grpc-retry-pushback-ms"; }
346
410
  using ValueType = Duration;
347
411
  using MementoType = Duration;
412
+ using CompressionTraits = NoCompressionCompressor;
348
413
  static ValueType MementoToValue(MementoType x) { return x; }
349
414
  static Slice Encode(Duration x) { return Slice::FromInt64(x.millis()); }
350
415
  static int64_t DisplayValue(Duration x) { return x.millis(); }
@@ -356,6 +421,7 @@ struct GrpcRetryPushbackMsMetadata {
356
421
  // TODO(ctiller): consider moving to uint16_t
357
422
  struct HttpStatusMetadata : public SimpleIntBasedMetadata<uint32_t, 0> {
358
423
  static constexpr bool kRepeatable = false;
424
+ using CompressionTraits = HttpStatusCompressor;
359
425
  static absl::string_view key() { return ":status"; }
360
426
  };
361
427
 
@@ -368,6 +434,7 @@ struct GrpcLbClientStatsMetadata {
368
434
  static absl::string_view key() { return "grpclb_client_stats"; }
369
435
  using ValueType = GrpcLbClientStats*;
370
436
  using MementoType = ValueType;
437
+ using CompressionTraits = NoCompressionCompressor;
371
438
  static ValueType MementoToValue(MementoType value) { return value; }
372
439
  static Slice Encode(ValueType) { abort(); }
373
440
  static const char* DisplayValue(ValueType) { return "<internal-lb-stats>"; }
@@ -387,6 +454,7 @@ inline size_t EncodedSizeOfKey(GrpcLbClientStatsMetadata,
387
454
  // lb-token metadata
388
455
  struct LbTokenMetadata : public SimpleSliceBasedMetadata {
389
456
  static constexpr bool kRepeatable = false;
457
+ using CompressionTraits = NoCompressionCompressor;
390
458
  static absl::string_view key() { return "lb-token"; }
391
459
  };
392
460
 
@@ -399,6 +467,7 @@ struct LbCostBinMetadata {
399
467
  std::string name;
400
468
  };
401
469
  using MementoType = ValueType;
470
+ using CompressionTraits = NoCompressionCompressor;
402
471
  static ValueType MementoToValue(MementoType value) { return value; }
403
472
  static Slice Encode(const ValueType& x);
404
473
  static std::string DisplayValue(ValueType x);
@@ -576,8 +645,9 @@ class ParseHelper {
576
645
 
577
646
  GPR_ATTRIBUTE_NOINLINE ParsedMetadata<Container> NotFound(
578
647
  absl::string_view key) {
579
- return ParsedMetadata<Container>(Slice::FromCopiedString(key),
580
- std::move(value_));
648
+ return ParsedMetadata<Container>(
649
+ typename ParsedMetadata<Container>::FromSlicePair{},
650
+ Slice::FromCopiedString(key), std::move(value_), transport_size_);
581
651
  }
582
652
 
583
653
  private:
@@ -993,6 +1063,35 @@ class UnknownMap {
993
1063
  ChunkedVector<std::pair<Slice, Slice>, 10> unknown_;
994
1064
  };
995
1065
 
1066
+ // Given a factory template Factory, construct a type that derives from
1067
+ // Factory<MetadataTrait, MetadataTrait::CompressionTraits> for all
1068
+ // MetadataTraits. Useful for transports in defining the stateful parts of their
1069
+ // compression algorithm.
1070
+ template <template <typename, typename> class Factory,
1071
+ typename... MetadataTraits>
1072
+ struct StatefulCompressor;
1073
+
1074
+ template <template <typename, typename> class Factory, typename MetadataTrait,
1075
+ bool kEncodable = IsEncodableTrait<MetadataTrait>::value>
1076
+ struct SpecificStatefulCompressor;
1077
+
1078
+ template <template <typename, typename> class Factory, typename MetadataTrait>
1079
+ struct SpecificStatefulCompressor<Factory, MetadataTrait, true>
1080
+ : public Factory<MetadataTrait, typename MetadataTrait::CompressionTraits> {
1081
+ };
1082
+
1083
+ template <template <typename, typename> class Factory, typename MetadataTrait>
1084
+ struct SpecificStatefulCompressor<Factory, MetadataTrait, false> {};
1085
+
1086
+ template <template <typename, typename> class Factory, typename MetadataTrait,
1087
+ typename... MetadataTraits>
1088
+ struct StatefulCompressor<Factory, MetadataTrait, MetadataTraits...>
1089
+ : public SpecificStatefulCompressor<Factory, MetadataTrait>,
1090
+ public StatefulCompressor<Factory, MetadataTraits...> {};
1091
+
1092
+ template <template <typename, typename> class Factory>
1093
+ struct StatefulCompressor<Factory> {};
1094
+
996
1095
  } // namespace metadata_detail
997
1096
 
998
1097
  // Helper function for encoders
@@ -1111,6 +1210,15 @@ class MetadataMap {
1111
1210
  explicit MetadataMap(Arena* arena);
1112
1211
  ~MetadataMap();
1113
1212
 
1213
+ // Given a compressor factory - template taking <MetadataTrait,
1214
+ // CompressionTrait>, StatefulCompressor<Factory> provides a type
1215
+ // derived from all Encodable traits in this MetadataMap.
1216
+ // This can be used by transports to delegate compression to the appropriate
1217
+ // compression algorithm.
1218
+ template <template <typename, typename> class Factory>
1219
+ using StatefulCompressor =
1220
+ metadata_detail::StatefulCompressor<Factory, Traits...>;
1221
+
1114
1222
  MetadataMap(const MetadataMap&) = delete;
1115
1223
  MetadataMap& operator=(const MetadataMap&) = delete;
1116
1224
  MetadataMap(MetadataMap&&) noexcept;
@@ -26,6 +26,7 @@
26
26
 
27
27
  #include "absl/functional/function_ref.h"
28
28
  #include "absl/meta/type_traits.h"
29
+ #include "absl/strings/escaping.h"
29
30
  #include "absl/strings/match.h"
30
31
  #include "absl/strings/str_cat.h"
31
32
  #include "absl/strings/string_view.h"
@@ -151,9 +152,14 @@ class ParsedMetadata {
151
152
  value_.slice = value.TakeCSlice();
152
153
  }
153
154
  // Construct metadata from a string key, slice value pair.
154
- ParsedMetadata(Slice key, Slice value)
155
+ // FromSlicePair() is used to adjust the overload set so that we don't
156
+ // inadvertently match against any of the previous overloads.
157
+ // TODO(ctiller): re-evaluate the overload functions here so and maybe
158
+ // introduce some factory functions?
159
+ struct FromSlicePair {};
160
+ ParsedMetadata(FromSlicePair, Slice key, Slice value, uint32_t transport_size)
155
161
  : vtable_(ParsedMetadata::KeyValueVTable(key.as_string_view())),
156
- transport_size_(static_cast<uint32_t>(key.size() + value.size() + 32)) {
162
+ transport_size_(transport_size) {
157
163
  value_.pointer =
158
164
  new std::pair<Slice, Slice>(std::move(key), std::move(value));
159
165
  }
@@ -187,14 +193,13 @@ class ParsedMetadata {
187
193
  // HTTP2 defined storage size of this metadatum.
188
194
  uint32_t transport_size() const { return transport_size_; }
189
195
  // Create a new parsed metadata with the same key but a different value.
190
- ParsedMetadata WithNewValue(Slice value,
196
+ ParsedMetadata WithNewValue(Slice value, uint32_t value_wire_size,
191
197
  MetadataParseErrorFn on_error) const {
192
198
  ParsedMetadata result;
193
199
  result.vtable_ = vtable_;
194
200
  result.value_ = value_;
195
201
  result.transport_size_ =
196
- TransportSize(static_cast<uint32_t>(key().length()),
197
- static_cast<uint32_t>(value.length()));
202
+ TransportSize(static_cast<uint32_t>(key().length()), value_wire_size);
198
203
  vtable_->with_new_value(&value, on_error, &result);
199
204
  return result;
200
205
  }
@@ -395,12 +400,17 @@ ParsedMetadata<MetadataContainer>::KeyValueVTable(absl::string_view key) {
395
400
  return absl::StrCat(p->first.as_string_view(), ": ",
396
401
  p->second.as_string_view());
397
402
  };
403
+ static const auto binary_debug_string = [](const Buffer& value) {
404
+ auto* p = static_cast<KV*>(value.pointer);
405
+ return absl::StrCat(p->first.as_string_view(), ": \"",
406
+ absl::CEscape(p->second.as_string_view()), "\"");
407
+ };
398
408
  static const auto key_fn = [](const Buffer& value) {
399
409
  return static_cast<KV*>(value.pointer)->first.as_string_view();
400
410
  };
401
411
  static const VTable vtable[2] = {
402
412
  {false, destroy, set, with_new_value, debug_string, "", key_fn},
403
- {true, destroy, set, with_new_value, debug_string, "", key_fn},
413
+ {true, destroy, set, with_new_value, binary_debug_string, "", key_fn},
404
414
  };
405
415
  return &vtable[absl::EndsWith(key, "-bin")];
406
416
  }
@@ -14,5 +14,5 @@
14
14
 
15
15
  # GRPC contains the General RPC module.
16
16
  module GRPC
17
- VERSION = '1.54.0'
17
+ VERSION = '1.54.2'
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.54.0
4
+ version: 1.54.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - gRPC Authors
8
8
  autorequire:
9
9
  bindir: src/ruby/bin
10
10
  cert_chain: []
11
- date: 2023-04-13 00:00:00.000000000 Z
11
+ date: 2023-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf