| Index: net/quic/spdy_utils.cc
|
| diff --git a/net/quic/spdy_utils.cc b/net/quic/spdy_utils.cc
|
| index 468c9823e1af1656036d4e5e758ccf913354d885..fc6eb9fd4b90293c68aeedb00a5213d281331220 100644
|
| --- a/net/quic/spdy_utils.cc
|
| +++ b/net/quic/spdy_utils.cc
|
| @@ -20,6 +20,10 @@ using std::vector;
|
|
|
| namespace net {
|
|
|
| +bool ascii_isupper(unsigned char c) {
|
| + return c >= 'A' && c <= 'Z';
|
| +}
|
| +
|
| // static
|
| string SpdyUtils::SerializeUncompressedHeaders(const SpdyHeaderBlock& headers) {
|
| SpdyMajorVersion spdy_version = HTTP2;
|
| @@ -107,6 +111,52 @@ bool SpdyUtils::ParseTrailers(const char* data,
|
| return true;
|
| }
|
|
|
| +bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
|
| + size_t* final_byte_offset,
|
| + SpdyHeaderBlock* trailers) {
|
| + for (const auto& p : header_list) {
|
| + const string& name = p.first;
|
| + if (name.empty() || name[0] == ':') {
|
| + DVLOG(1) << "Trailers must not be empty, and must not contain pseudo-"
|
| + << "headers. Found: '" << name << "'";
|
| + return false;
|
| + }
|
| +
|
| + if (std::any_of(name.begin(), name.end(), ascii_isupper)) {
|
| + DVLOG(1) << "Malformed header: Header name " << name
|
| + << " contains upper-case characters.";
|
| + return false;
|
| + }
|
| +
|
| + if (trailers->find(name) != trailers->end()) {
|
| + DVLOG(1) << "Duplicate header '" << name << "' found in trailers.";
|
| + return false;
|
| + }
|
| +
|
| + (*trailers)[name] = p.second;
|
| + }
|
| +
|
| + if (trailers->empty()) {
|
| + DVLOG(1) << "Request Trailers are invalid.";
|
| + return false; // Trailers were invalid.
|
| + }
|
| +
|
| + // Pull out the final offset pseudo header which indicates the number of
|
| + // response body bytes expected.
|
| + auto it = trailers->find(kFinalOffsetHeaderKey);
|
| + if (it == trailers->end() || !StringToSizeT(it->second, final_byte_offset)) {
|
| + DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey << "' not present";
|
| + return false;
|
| + }
|
| + // The final offset header is no longer needed.
|
| + trailers->erase(it->first);
|
| +
|
| + // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
|
| +
|
| + DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
|
| + return true;
|
| +}
|
| +
|
| // static
|
| string SpdyUtils::GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers) {
|
| SpdyHeaderBlock::const_iterator it = headers.find(":scheme");
|
|
|