| Index: net/quic/spdy_utils.cc
|
| diff --git a/net/quic/spdy_utils.cc b/net/quic/spdy_utils.cc
|
| index b0e948b45ac755a63b7f697c767d48a1380a1ead..6cfdc1e7a2649d63231b15daf2befd5dae6bcbc3 100644
|
| --- a/net/quic/spdy_utils.cc
|
| +++ b/net/quic/spdy_utils.cc
|
| @@ -65,4 +65,44 @@ bool SpdyUtils::ParseHeaders(const char* data,
|
| return true;
|
| }
|
|
|
| +// static
|
| +bool SpdyUtils::ParseTrailers(const char* data,
|
| + uint32 data_len,
|
| + size_t* final_byte_offset,
|
| + SpdyHeaderBlock* trailers) {
|
| + SpdyFramer framer(HTTP2);
|
| + if (!framer.ParseHeaderBlockInBuffer(data, data_len, trailers) ||
|
| + 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(":final-offset");
|
| + if (it == trailers->end() ||
|
| + !base::StringToSizeT(it->second, final_byte_offset)) {
|
| + DVLOG(1) << ":final-offset not present";
|
| + return false; // :final-offset key must be present.
|
| + }
|
| + // :final-offset header is no longer used.
|
| + trailers->erase(it->first);
|
| +
|
| + // Trailers must not have empty keys, and must not contain pseudo headers.
|
| + for (const auto& trailer : *trailers) {
|
| + base::StringPiece key = trailer.first;
|
| + base::StringPiece value = trailer.second;
|
| + if (key.starts_with(":")) {
|
| + DVLOG(1) << "Trailers must not contain pseudo-header: '" << key << "','"
|
| + << value << "'.";
|
| + return false;
|
| + }
|
| +
|
| + // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
|
| + }
|
| +
|
| + DVLOG(1) << "Successfully parsed Trailers.";
|
| + return true;
|
| +}
|
| +
|
| } // namespace net
|
|
|