Chromium Code Reviews

Side by Side Diff: content/child/multipart_response_delegate.cc

Issue 1166953002: Use net's response header parser for parsing multipart headers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Improved comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/child/multipart_response_delegate.h" 5 #include "content/child/multipart_response_delegate.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "net/base/net_util.h" 10 #include "net/base/net_util.h"
11 #include "net/http/http_response_headers.h"
11 #include "net/http/http_util.h" 12 #include "net/http/http_util.h"
12 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" 13 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
13 #include "third_party/WebKit/public/platform/WebString.h" 14 #include "third_party/WebKit/public/platform/WebString.h"
14 #include "third_party/WebKit/public/platform/WebURL.h" 15 #include "third_party/WebKit/public/platform/WebURL.h"
15 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" 16 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
16 17
17 using blink::WebHTTPHeaderVisitor; 18 using blink::WebHTTPHeaderVisitor;
18 using blink::WebString; 19 using blink::WebString;
19 using blink::WebURLLoader; 20 using blink::WebURLLoader;
20 using blink::WebURLLoaderClient; 21 using blink::WebURLLoaderClient;
(...skipping 181 matching lines...)
202 int offset = 0; 203 int offset = 0;
203 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { 204 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) {
204 ++offset; 205 ++offset;
205 if (pos + 1 < data.length() && data[pos + 1] == '\n') 206 if (pos + 1 < data.length() && data[pos + 1] == '\n')
206 ++offset; 207 ++offset;
207 } 208 }
208 return offset; 209 return offset;
209 } 210 }
210 211
211 bool MultipartResponseDelegate::ParseHeaders() { 212 bool MultipartResponseDelegate::ParseHeaders() {
212 int line_feed_increment = 1; 213 int headers_end_pos = -1;
213 214
214 // Grab the headers being liberal about line endings. 215 size_t i = 0;
215 size_t line_start_pos = 0; 216 while ((data_[i] == '\r' || data_[i] == '\n') && i < data_.size())
216 size_t line_end_pos = data_.find('\n'); 217 i++;
mmenke 2015/06/05 16:01:42 This isn't correct (If we have a bunch of LFs or C
haavardm 2015/06/09 15:12:35 agh, of course..
217 while (line_end_pos != std::string::npos) { 218
218 // Handle CRLF 219 if (i > 0)
219 if (line_end_pos > line_start_pos && data_[line_end_pos - 1] == '\r') { 220 headers_end_pos = i;
220 line_feed_increment = 2; 221 else
221 --line_end_pos; 222 headers_end_pos =
222 } else { 223 net::HttpUtil::LocateEndOfHeaders(data_.c_str(), data_.size(), 0);
223 line_feed_increment = 1; 224
224 } 225 if (headers_end_pos < 0)
225 if (line_start_pos == line_end_pos) {
226 // A blank line, end of headers
227 line_end_pos += line_feed_increment;
228 break;
229 }
230 // Find the next header line.
231 line_start_pos = line_end_pos + line_feed_increment;
232 line_end_pos = data_.find('\n', line_start_pos);
233 }
234 // Truncated in the middle of a header, stop parsing.
235 if (line_end_pos == std::string::npos)
236 return false; 226 return false;
237 227
238 // Eat headers 228 // Eat headers and prepend a status line as is required by
239 std::string headers("\n"); 229 // HttpResponseHeaders.
240 headers.append(data_, 0, line_end_pos); 230 std::string headers("HTTP/1.1 200 OK\r\n");
241 data_ = data_.substr(line_end_pos); 231 headers.append(data_, 0, headers_end_pos);
232 data_ = data_.substr(headers_end_pos);
233
234 scoped_refptr<net::HttpResponseHeaders> response_headers =
mmenke 2015/06/05 16:01:42 nit: include base/ref_counted.h
haavardm 2015/06/09 15:12:34 Done.
235 new net::HttpResponseHeaders(
236 net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
mmenke 2015/06/05 16:01:42 Again, suggest a method for HttpUtil that does thi
haavardm 2015/06/09 15:12:34 I'm a bit unsure about what you suggest to add a m
mmenke 2015/06/09 20:23:37 I was thinking of making a method that does this:
242 237
243 // Create a WebURLResponse based on the original set of headers + the 238 // Create a WebURLResponse based on the original set of headers + the
244 // replacement headers. We only replace the same few headers that gecko 239 // replacement headers. We only replace the same few headers that gecko
245 // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp. 240 // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp.
246 std::string content_type = net::GetSpecificHeader(headers, "content-type"); 241 std::string content_type;
242 WebURLResponse response(original_response_.url());
243
247 std::string mime_type; 244 std::string mime_type;
245 if (response_headers->GetMimeType(&mime_type)) {
246 response.setMIMEType(WebString::fromUTF8(mime_type));
247 }
248 std::string charset; 248 std::string charset;
249 bool has_charset = false; 249 if (response_headers->GetCharset(&charset)) {
250 net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, 250 response.setTextEncodingName(WebString::fromUTF8(charset));
251 &has_charset, NULL); 251 }
mmenke 2015/06/05 16:01:42 I don't feel like I can adequately review the impl
haavardm 2015/06/09 15:12:35 I think it should handle not setting the mime or t
252 WebURLResponse response(original_response_.url());
253 response.setMIMEType(WebString::fromUTF8(mime_type));
254 response.setTextEncodingName(WebString::fromUTF8(charset));
255 252
253 // Copy the response headers from the original response.
256 HeaderCopier copier(&response); 254 HeaderCopier copier(&response);
257 original_response_.visitHTTPHeaderFields(&copier); 255 original_response_.visitHTTPHeaderFields(&copier);
258 256
257 // Replace original headers with multipart headers listed in kReplaceHeaders.
259 for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) { 258 for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) {
260 std::string name(kReplaceHeaders[i]); 259 std::string name(kReplaceHeaders[i]);
261 std::string value = net::GetSpecificHeader(headers, name); 260 std::string value;
262 if (!value.empty()) { 261 if (response_headers->EnumerateHeader(NULL, name, &value)) {
263 response.setHTTPHeaderField(WebString::fromUTF8(name), 262 response.setHTTPHeaderField(WebString::fromUTF8(name),
264 WebString::fromUTF8(value)); 263 WebString::fromUTF8(value));
265 } 264 }
266 } 265 }
267 // To avoid recording every multipart load as a separate visit in 266 // To avoid recording every multipart load as a separate visit in
268 // the history database, we want to keep track of whether the response 267 // the history database, we want to keep track of whether the response
269 // is part of a multipart payload. We do want to record the first visit, 268 // is part of a multipart payload. We do want to record the first visit,
270 // so we only set isMultipartPayload to true after the first visit. 269 // so we only set isMultipartPayload to true after the first visit.
271 response.setIsMultipartPayload(has_sent_first_response_); 270 response.setIsMultipartPayload(has_sent_first_response_);
272 has_sent_first_response_ = true; 271 has_sent_first_response_ = true;
(...skipping 122 matching lines...)
395 if (!base::StringToInt64(byte_range_upper_bound, content_range_upper_bound)) 394 if (!base::StringToInt64(byte_range_upper_bound, content_range_upper_bound))
396 return false; 395 return false;
397 if (!base::StringToInt64(byte_range_instance_size, 396 if (!base::StringToInt64(byte_range_instance_size,
398 content_range_instance_size)) { 397 content_range_instance_size)) {
399 return false; 398 return false;
400 } 399 }
401 return true; 400 return true;
402 } 401 }
403 402
404 } // namespace content 403 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine