| 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/memory/ref_counted.h" |
| 8 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 10 #include "net/base/net_util.h" | 11 #include "net/base/net_util.h" |
| 12 #include "net/http/http_response_headers.h" |
| 11 #include "net/http/http_util.h" | 13 #include "net/http/http_util.h" |
| 12 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" | 14 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" |
| 13 #include "third_party/WebKit/public/platform/WebString.h" | 15 #include "third_party/WebKit/public/platform/WebString.h" |
| 14 #include "third_party/WebKit/public/platform/WebURL.h" | 16 #include "third_party/WebKit/public/platform/WebURL.h" |
| 15 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" | 17 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" |
| 16 | 18 |
| 17 using blink::WebHTTPHeaderVisitor; | 19 using blink::WebHTTPHeaderVisitor; |
| 18 using blink::WebString; | 20 using blink::WebString; |
| 19 using blink::WebURLLoader; | 21 using blink::WebURLLoader; |
| 20 using blink::WebURLLoaderClient; | 22 using blink::WebURLLoaderClient; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 int offset = 0; | 204 int offset = 0; |
| 203 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { | 205 if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { |
| 204 ++offset; | 206 ++offset; |
| 205 if (pos + 1 < data.length() && data[pos + 1] == '\n') | 207 if (pos + 1 < data.length() && data[pos + 1] == '\n') |
| 206 ++offset; | 208 ++offset; |
| 207 } | 209 } |
| 208 return offset; | 210 return offset; |
| 209 } | 211 } |
| 210 | 212 |
| 211 bool MultipartResponseDelegate::ParseHeaders() { | 213 bool MultipartResponseDelegate::ParseHeaders() { |
| 212 int line_feed_increment = 1; | 214 int headers_end_pos = net::HttpUtil::LocateEndOfAdditionalHeaders( |
| 215 data_.c_str(), data_.size(), 0); |
| 213 | 216 |
| 214 // Grab the headers being liberal about line endings. | 217 if (headers_end_pos < 0) |
| 215 size_t line_start_pos = 0; | |
| 216 size_t line_end_pos = data_.find('\n'); | |
| 217 while (line_end_pos != std::string::npos) { | |
| 218 // Handle CRLF | |
| 219 if (line_end_pos > line_start_pos && data_[line_end_pos - 1] == '\r') { | |
| 220 line_feed_increment = 2; | |
| 221 --line_end_pos; | |
| 222 } else { | |
| 223 line_feed_increment = 1; | |
| 224 } | |
| 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; | 218 return false; |
| 237 | 219 |
| 238 // Eat headers | 220 // Eat headers and prepend a status line as is required by |
| 239 std::string headers("\n"); | 221 // HttpResponseHeaders. |
| 240 headers.append(data_, 0, line_end_pos); | 222 std::string headers("HTTP/1.1 200 OK\r\n"); |
| 241 data_ = data_.substr(line_end_pos); | 223 headers.append(data_, 0, headers_end_pos); |
| 224 data_ = data_.substr(headers_end_pos); |
| 225 |
| 226 scoped_refptr<net::HttpResponseHeaders> response_headers = |
| 227 new net::HttpResponseHeaders( |
| 228 net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size())); |
| 242 | 229 |
| 243 // Create a WebURLResponse based on the original set of headers + the | 230 // Create a WebURLResponse based on the original set of headers + the |
| 244 // replacement headers. We only replace the same few headers that gecko | 231 // replacement headers. We only replace the same few headers that gecko |
| 245 // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp. | 232 // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp. |
| 246 std::string content_type = net::GetSpecificHeader(headers, "content-type"); | 233 WebURLResponse response(original_response_.url()); |
| 234 |
| 247 std::string mime_type; | 235 std::string mime_type; |
| 236 response_headers->GetMimeType(&mime_type); |
| 237 response.setMIMEType(WebString::fromUTF8(mime_type)); |
| 238 |
| 248 std::string charset; | 239 std::string charset; |
| 249 bool has_charset = false; | 240 response_headers->GetCharset(&charset); |
| 250 net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, | |
| 251 &has_charset, NULL); | |
| 252 WebURLResponse response(original_response_.url()); | |
| 253 response.setMIMEType(WebString::fromUTF8(mime_type)); | |
| 254 response.setTextEncodingName(WebString::fromUTF8(charset)); | 241 response.setTextEncodingName(WebString::fromUTF8(charset)); |
| 255 | 242 |
| 243 // Copy the response headers from the original response. |
| 256 HeaderCopier copier(&response); | 244 HeaderCopier copier(&response); |
| 257 original_response_.visitHTTPHeaderFields(&copier); | 245 original_response_.visitHTTPHeaderFields(&copier); |
| 258 | 246 |
| 247 // Replace original headers with multipart headers listed in kReplaceHeaders. |
| 259 for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) { | 248 for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) { |
| 260 std::string name(kReplaceHeaders[i]); | 249 std::string name(kReplaceHeaders[i]); |
| 261 std::string value = net::GetSpecificHeader(headers, name); | 250 std::string value; |
| 262 if (!value.empty()) { | 251 void* iterator = nullptr; |
| 263 response.setHTTPHeaderField(WebString::fromUTF8(name), | 252 while (response_headers->EnumerateHeader(&iterator, name, &value)) { |
| 264 WebString::fromUTF8(value)); | 253 response.addHTTPHeaderField(WebString::fromLatin1(name), |
| 254 WebString::fromLatin1(value)); |
| 265 } | 255 } |
| 266 } | 256 } |
| 267 // To avoid recording every multipart load as a separate visit in | 257 // To avoid recording every multipart load as a separate visit in |
| 268 // the history database, we want to keep track of whether the response | 258 // 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, | 259 // 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. | 260 // so we only set isMultipartPayload to true after the first visit. |
| 271 response.setIsMultipartPayload(has_sent_first_response_); | 261 response.setIsMultipartPayload(has_sent_first_response_); |
| 272 has_sent_first_response_ = true; | 262 has_sent_first_response_ = true; |
| 273 // Send the response! | 263 // Send the response! |
| 274 if (client_) | 264 if (client_) |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 if (!base::StringToInt64(byte_range_upper_bound, content_range_upper_bound)) | 385 if (!base::StringToInt64(byte_range_upper_bound, content_range_upper_bound)) |
| 396 return false; | 386 return false; |
| 397 if (!base::StringToInt64(byte_range_instance_size, | 387 if (!base::StringToInt64(byte_range_instance_size, |
| 398 content_range_instance_size)) { | 388 content_range_instance_size)) { |
| 399 return false; | 389 return false; |
| 400 } | 390 } |
| 401 return true; | 391 return true; |
| 402 } | 392 } |
| 403 | 393 |
| 404 } // namespace content | 394 } // namespace content |
| OLD | NEW |