Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: net/quic/core/spdy_utils.cc

Issue 2611613003: Add quic_logging (Closed)
Patch Set: fix failed test? Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/core/quic_versions.cc ('k') | net/quic/platform/api/quic_logging.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/core/spdy_utils.h" 5 #include "net/quic/core/spdy_utils.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "net/quic/platform/api/quic_logging.h"
11 #include "net/quic/platform/api/quic_text_utils.h" 12 #include "net/quic/platform/api/quic_text_utils.h"
12 #include "net/spdy/spdy_flags.h" 13 #include "net/spdy/spdy_flags.h"
13 #include "net/spdy/spdy_frame_builder.h" 14 #include "net/spdy/spdy_frame_builder.h"
14 #include "net/spdy/spdy_framer.h" 15 #include "net/spdy/spdy_framer.h"
15 #include "net/spdy/spdy_protocol.h" 16 #include "net/spdy/spdy_protocol.h"
16 #include "url/gurl.h" 17 #include "url/gurl.h"
17 18
18 using base::StringPiece; 19 using base::StringPiece;
19 using base::ContainsKey; 20 using base::ContainsKey;
20 using std::string; 21 using std::string;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 if (it == headers->end()) { 57 if (it == headers->end()) {
57 return false; 58 return false;
58 } else { 59 } else {
59 // Check whether multiple values are consistent. 60 // Check whether multiple values are consistent.
60 StringPiece content_length_header = it->second; 61 StringPiece content_length_header = it->second;
61 std::vector<StringPiece> values = 62 std::vector<StringPiece> values =
62 QuicTextUtils::Split(content_length_header, '\0'); 63 QuicTextUtils::Split(content_length_header, '\0');
63 for (const StringPiece& value : values) { 64 for (const StringPiece& value : values) {
64 int64_t new_value; 65 int64_t new_value;
65 if (!base::StringToInt64(value, &new_value) || new_value < 0) { 66 if (!base::StringToInt64(value, &new_value) || new_value < 0) {
66 DLOG(ERROR) << "Content length was either unparseable or negative."; 67 QUIC_DLOG(ERROR)
68 << "Content length was either unparseable or negative.";
67 return false; 69 return false;
68 } 70 }
69 if (*content_length < 0) { 71 if (*content_length < 0) {
70 *content_length = new_value; 72 *content_length = new_value;
71 continue; 73 continue;
72 } 74 }
73 if (new_value != *content_length) { 75 if (new_value != *content_length) {
74 DLOG(ERROR) << "Parsed content length " << new_value << " is " 76 QUIC_DLOG(ERROR)
75 << "inconsistent with previously detected content length " 77 << "Parsed content length " << new_value << " is "
76 << *content_length; 78 << "inconsistent with previously detected content length "
79 << *content_length;
77 return false; 80 return false;
78 } 81 }
79 } 82 }
80 return true; 83 return true;
81 } 84 }
82 } 85 }
83 86
84 // static 87 // static
85 bool SpdyUtils::ParseTrailers(const char* data, 88 bool SpdyUtils::ParseTrailers(const char* data,
86 uint32_t data_len, 89 uint32_t data_len,
87 size_t* final_byte_offset, 90 size_t* final_byte_offset,
88 SpdyHeaderBlock* trailers) { 91 SpdyHeaderBlock* trailers) {
89 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION); 92 SpdyFramer framer(SpdyFramer::ENABLE_COMPRESSION);
90 if (!framer.ParseHeaderBlockInBuffer(data, data_len, trailers) || 93 if (!framer.ParseHeaderBlockInBuffer(data, data_len, trailers) ||
91 trailers->empty()) { 94 trailers->empty()) {
92 DVLOG(1) << "Request Trailers are invalid."; 95 QUIC_DVLOG(1) << "Request Trailers are invalid.";
93 return false; // Trailers were invalid. 96 return false; // Trailers were invalid.
94 } 97 }
95 98
96 // Pull out the final offset pseudo header which indicates the number of 99 // Pull out the final offset pseudo header which indicates the number of
97 // response body bytes expected. 100 // response body bytes expected.
98 auto it = trailers->find(kFinalOffsetHeaderKey); 101 auto it = trailers->find(kFinalOffsetHeaderKey);
99 if (it == trailers->end() || 102 if (it == trailers->end() ||
100 !base::StringToSizeT(it->second, final_byte_offset)) { 103 !base::StringToSizeT(it->second, final_byte_offset)) {
101 DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey << "' not present"; 104 QUIC_DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey
105 << "' not present";
102 return false; 106 return false;
103 } 107 }
104 // The final offset header is no longer needed. 108 // The final offset header is no longer needed.
105 trailers->erase(it->first); 109 trailers->erase(it->first);
106 110
107 // Trailers must not have empty keys, and must not contain pseudo headers. 111 // Trailers must not have empty keys, and must not contain pseudo headers.
108 for (const auto& trailer : *trailers) { 112 for (const auto& trailer : *trailers) {
109 StringPiece key = trailer.first; 113 StringPiece key = trailer.first;
110 StringPiece value = trailer.second; 114 StringPiece value = trailer.second;
111 if (QuicTextUtils::StartsWith(key, ":")) { 115 if (QuicTextUtils::StartsWith(key, ":")) {
112 DVLOG(1) << "Trailers must not contain pseudo-header: '" << key << "','" 116 QUIC_DVLOG(1) << "Trailers must not contain pseudo-header: '" << key
113 << value << "'."; 117 << "','" << value << "'.";
114 return false; 118 return false;
115 } 119 }
116 120
117 // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec. 121 // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
118 } 122 }
119 123
120 DVLOG(1) << "Successfully parsed Trailers."; 124 QUIC_DVLOG(1) << "Successfully parsed Trailers.";
121 return true; 125 return true;
122 } 126 }
123 127
124 bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list, 128 bool SpdyUtils::CopyAndValidateHeaders(const QuicHeaderList& header_list,
125 int64_t* content_length, 129 int64_t* content_length,
126 SpdyHeaderBlock* headers) { 130 SpdyHeaderBlock* headers) {
127 for (const auto& p : header_list) { 131 for (const auto& p : header_list) {
128 const string& name = p.first; 132 const string& name = p.first;
129 if (name.empty()) { 133 if (name.empty()) {
130 DVLOG(1) << "Header name must not be empty."; 134 QUIC_DVLOG(1) << "Header name must not be empty.";
131 return false; 135 return false;
132 } 136 }
133 137
134 if (QuicTextUtils::ContainsUpperCase(name)) { 138 if (QuicTextUtils::ContainsUpperCase(name)) {
135 DVLOG(1) << "Malformed header: Header name " << name 139 QUIC_DLOG(ERROR) << "Malformed header: Header name " << name
136 << " contains upper-case characters."; 140 << " contains upper-case characters.";
137 return false; 141 return false;
138 } 142 }
139 143
140 headers->AppendValueOrAddHeader(name, p.second); 144 headers->AppendValueOrAddHeader(name, p.second);
141 } 145 }
142 146
143 if (ContainsKey(*headers, "content-length") && 147 if (ContainsKey(*headers, "content-length") &&
144 !ExtractContentLengthFromHeaders(content_length, headers)) { 148 !ExtractContentLengthFromHeaders(content_length, headers)) {
145 return false; 149 return false;
146 } 150 }
147 151
148 DVLOG(1) << "Successfully parsed headers: " << headers->DebugString(); 152 QUIC_DVLOG(1) << "Successfully parsed headers: " << headers->DebugString();
149 return true; 153 return true;
150 } 154 }
151 155
152 bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list, 156 bool SpdyUtils::CopyAndValidateTrailers(const QuicHeaderList& header_list,
153 size_t* final_byte_offset, 157 size_t* final_byte_offset,
154 SpdyHeaderBlock* trailers) { 158 SpdyHeaderBlock* trailers) {
155 bool found_final_byte_offset = false; 159 bool found_final_byte_offset = false;
156 for (const auto& p : header_list) { 160 for (const auto& p : header_list) {
157 const string& name = p.first; 161 const string& name = p.first;
158 162
159 // Pull out the final offset pseudo header which indicates the number of 163 // Pull out the final offset pseudo header which indicates the number of
160 // response body bytes expected. 164 // response body bytes expected.
161 int offset; 165 int offset;
162 if (!found_final_byte_offset && name == kFinalOffsetHeaderKey && 166 if (!found_final_byte_offset && name == kFinalOffsetHeaderKey &&
163 base::StringToInt(p.second, &offset)) { 167 base::StringToInt(p.second, &offset)) {
164 *final_byte_offset = offset; 168 *final_byte_offset = offset;
165 found_final_byte_offset = true; 169 found_final_byte_offset = true;
166 continue; 170 continue;
167 } 171 }
168 172
169 if (name.empty() || name[0] == ':') { 173 if (name.empty() || name[0] == ':') {
170 DVLOG(1) << "Trailers must not be empty, and must not contain pseudo-" 174 QUIC_DVLOG(1)
171 << "headers. Found: '" << name << "'"; 175 << "Trailers must not be empty, and must not contain pseudo-"
176 << "headers. Found: '" << name << "'";
172 return false; 177 return false;
173 } 178 }
174 179
175 if (QuicTextUtils::ContainsUpperCase(name)) { 180 if (QuicTextUtils::ContainsUpperCase(name)) {
176 DVLOG(1) << "Malformed header: Header name " << name 181 QUIC_DLOG(INFO) << "Malformed header: Header name " << name
177 << " contains upper-case characters."; 182 << " contains upper-case characters.";
178 return false; 183 return false;
179 } 184 }
180 185
181 if (trailers->find(name) != trailers->end()) { 186 if (trailers->find(name) != trailers->end()) {
182 DVLOG(1) << "Duplicate header '" << name << "' found in trailers."; 187 QUIC_DLOG(INFO) << "Duplicate header '" << name << "' found in trailers.";
183 return false; 188 return false;
184 } 189 }
185 190
186 (*trailers)[name] = p.second; 191 (*trailers)[name] = p.second;
187 } 192 }
188 193
189 if (!found_final_byte_offset) { 194 if (!found_final_byte_offset) {
190 DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey << "' not present"; 195 QUIC_DVLOG(1) << "Required key '" << kFinalOffsetHeaderKey
196 << "' not present";
191 return false; 197 return false;
192 } 198 }
193 199
194 // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec. 200 // TODO(rjshade): Check for other forbidden keys, following the HTTP/2 spec.
195 201
196 DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString(); 202 QUIC_DVLOG(1) << "Successfully parsed Trailers: " << trailers->DebugString();
197 return true; 203 return true;
198 } 204 }
199 205
200 // static 206 // static
201 string SpdyUtils::GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers) { 207 string SpdyUtils::GetUrlFromHeaderBlock(const SpdyHeaderBlock& headers) {
202 SpdyHeaderBlock::const_iterator it = headers.find(":scheme"); 208 SpdyHeaderBlock::const_iterator it = headers.find(":scheme");
203 if (it == headers.end()) { 209 if (it == headers.end()) {
204 return ""; 210 return "";
205 } 211 }
206 std::string url = it->second.as_string(); 212 std::string url = it->second.as_string();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 (*headers)[":authority"] = url.substr(start); 253 (*headers)[":authority"] = url.substr(start);
248 (*headers)[":path"] = "/"; 254 (*headers)[":path"] = "/";
249 return true; 255 return true;
250 } 256 }
251 (*headers)[":authority"] = url.substr(start, pos - start); 257 (*headers)[":authority"] = url.substr(start, pos - start);
252 (*headers)[":path"] = url.substr(pos); 258 (*headers)[":path"] = url.substr(pos);
253 return true; 259 return true;
254 } 260 }
255 261
256 } // namespace net 262 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_versions.cc ('k') | net/quic/platform/api/quic_logging.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698