Index: net/quic/spdy_utils.cc |
diff --git a/net/quic/spdy_utils.cc b/net/quic/spdy_utils.cc |
index 468c9823e1af1656036d4e5e758ccf913354d885..1d16b9c92827ca4fcccd2a4811dd9cb4fc4abfe0 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) { |
ramant (doing other things)
2016/04/11 18:11:57
nit: consider adding this to strings/string_util.h
|
+ 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."; |
ramant (doing other things)
2016/04/11 18:11:57
nit: indent line# 127
Zhongyi Shi
2016/04/11 18:27:31
Already fixed in final.
|
+ 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"); |