OLD | NEW |
---|---|
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...) Loading... | |
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...) Loading... | |
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 |
OLD | NEW |