|
|
|
@ -1188,17 +1188,49 @@ class HPackParser::Parser { |
|
|
|
|
std::move(result)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class MetadataSizeLimitExceededEncoder { |
|
|
|
|
public: |
|
|
|
|
explicit MetadataSizeLimitExceededEncoder(std::string& summary) |
|
|
|
|
: summary_(summary) {} |
|
|
|
|
|
|
|
|
|
void Encode(const Slice& key, const Slice& value) { |
|
|
|
|
AddToSummary(key.as_string_view(), value.size()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename Key, typename Value> |
|
|
|
|
void Encode(Key, const Value& value) { |
|
|
|
|
AddToSummary(Key::key(), Key::Encode(value).size()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
void AddToSummary(absl::string_view key, |
|
|
|
|
size_t value_length) GPR_ATTRIBUTE_NOINLINE { |
|
|
|
|
absl::StrAppend(&summary_, " ", key, ":", |
|
|
|
|
hpack_constants::SizeForEntry(key.size(), value_length), |
|
|
|
|
"B"); |
|
|
|
|
} |
|
|
|
|
std::string& summary_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
GPR_ATTRIBUTE_NOINLINE |
|
|
|
|
bool HandleMetadataSizeLimitExceeded(const HPackTable::Memento&) { |
|
|
|
|
bool HandleMetadataSizeLimitExceeded(const HPackTable::Memento& md) { |
|
|
|
|
// Collect a summary of sizes so far for debugging
|
|
|
|
|
// Do not collect contents, for fear of exposing PII.
|
|
|
|
|
std::string summary; |
|
|
|
|
if (metadata_buffer_ != nullptr) { |
|
|
|
|
MetadataSizeLimitExceededEncoder encoder(summary); |
|
|
|
|
metadata_buffer_->Encode(&encoder); |
|
|
|
|
} |
|
|
|
|
summary = |
|
|
|
|
absl::StrCat("; adding ", md.key(), " (length ", md.transport_size(), |
|
|
|
|
"B)", summary.empty() ? "" : " to ", summary); |
|
|
|
|
if (metadata_buffer_ != nullptr) metadata_buffer_->Clear(); |
|
|
|
|
// TODO(alishananda): add debug log with metadata details
|
|
|
|
|
return input_->MaybeSetErrorAndReturn( |
|
|
|
|
[this] { |
|
|
|
|
[this, summary = std::move(summary)] { |
|
|
|
|
return grpc_error_set_int( |
|
|
|
|
GRPC_ERROR_CREATE(absl::StrFormat( |
|
|
|
|
"received initial metadata size exceeds limit (%" PRIu32 |
|
|
|
|
" vs. %" PRIu32 ")", |
|
|
|
|
*frame_length_, metadata_size_limit_)), |
|
|
|
|
GRPC_ERROR_CREATE(absl::StrCat( |
|
|
|
|
"received initial metadata size exceeds limit (", |
|
|
|
|
*frame_length_, " vs. ", metadata_size_limit_, ")", summary)), |
|
|
|
|
StatusIntProperty::kRpcStatus, GRPC_STATUS_RESOURCE_EXHAUSTED); |
|
|
|
|
}, |
|
|
|
|
false); |
|
|
|
|