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

Unified Diff: webkit/glue/multipart_response_delegate.cc

Issue 20003004: reland crrev.com/212927 Move webkitplatformsupport_impl and related from glue to child (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase & allocator dep for components_unittests in shared_library2 Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/glue/multipart_response_delegate.h ('k') | webkit/glue/multipart_response_delegate_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/glue/multipart_response_delegate.cc
diff --git a/webkit/glue/multipart_response_delegate.cc b/webkit/glue/multipart_response_delegate.cc
deleted file mode 100644
index 325caf9103e0a50a6b88f6b66d3753b83c3d68b3..0000000000000000000000000000000000000000
--- a/webkit/glue/multipart_response_delegate.cc
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "webkit/glue/multipart_response_delegate.h"
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "net/base/net_util.h"
-#include "net/http/http_util.h"
-#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebURL.h"
-#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
-
-using WebKit::WebHTTPHeaderVisitor;
-using WebKit::WebString;
-using WebKit::WebURLLoader;
-using WebKit::WebURLLoaderClient;
-using WebKit::WebURLResponse;
-
-namespace webkit_glue {
-
-namespace {
-
-// The list of response headers that we do not copy from the original
-// response when generating a WebURLResponse for a MIME payload.
-const char* kReplaceHeaders[] = {
- "content-type",
- "content-length",
- "content-disposition",
- "content-range",
- "range",
- "set-cookie"
-};
-
-class HeaderCopier : public WebHTTPHeaderVisitor {
- public:
- HeaderCopier(WebURLResponse* response)
- : response_(response) {
- }
- virtual void visitHeader(const WebString& name, const WebString& value) {
- const std::string& name_utf8 = name.utf8();
- for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) {
- if (LowerCaseEqualsASCII(name_utf8, kReplaceHeaders[i]))
- return;
- }
- response_->setHTTPHeaderField(name, value);
- }
- private:
- WebURLResponse* response_;
-};
-
-} // namespace
-
-MultipartResponseDelegate::MultipartResponseDelegate(
- WebURLLoaderClient* client,
- WebURLLoader* loader,
- const WebURLResponse& response,
- const std::string& boundary)
- : client_(client),
- loader_(loader),
- original_response_(response),
- encoded_data_length_(0),
- boundary_("--"),
- first_received_data_(true),
- processing_headers_(false),
- stop_sending_(false),
- has_sent_first_response_(false) {
- // Some servers report a boundary prefixed with "--". See bug 5786.
- if (StartsWithASCII(boundary, "--", true)) {
- boundary_.assign(boundary);
- } else {
- boundary_.append(boundary);
- }
-}
-
-void MultipartResponseDelegate::OnReceivedData(const char* data,
- int data_len,
- int encoded_data_length) {
- // stop_sending_ means that we've already received the final boundary token.
- // The server should stop sending us data at this point, but if it does, we
- // just throw it away.
- if (stop_sending_)
- return;
-
- data_.append(data, data_len);
- encoded_data_length_ += encoded_data_length;
- if (first_received_data_) {
- // Some servers don't send a boundary token before the first chunk of
- // data. We handle this case anyway (Gecko does too).
- first_received_data_ = false;
-
- // Eat leading \r\n
- int pos = PushOverLine(data_, 0);
- if (pos)
- data_ = data_.substr(pos);
-
- if (data_.length() < boundary_.length() + 2) {
- // We don't have enough data yet to make a boundary token. Just wait
- // until the next chunk of data arrives.
- first_received_data_ = true;
- return;
- }
-
- if (0 != data_.compare(0, boundary_.length(), boundary_)) {
- data_ = boundary_ + "\n" + data_;
- }
- }
- DCHECK(!first_received_data_);
-
- // Headers
- if (processing_headers_) {
- // Eat leading \r\n
- int pos = PushOverLine(data_, 0);
- if (pos)
- data_ = data_.substr(pos);
-
- if (ParseHeaders()) {
- // Successfully parsed headers.
- processing_headers_ = false;
- } else {
- // Get more data before trying again.
- return;
- }
- }
- DCHECK(!processing_headers_);
-
- size_t boundary_pos;
- while ((boundary_pos = FindBoundary()) != std::string::npos) {
- if (client_) {
- // Strip out trailing \n\r characters in the buffer preceding the
- // boundary on the same lines as Firefox.
- size_t data_length = boundary_pos;
- if (boundary_pos > 0 && data_[boundary_pos - 1] == '\n') {
- data_length--;
- if (boundary_pos > 1 && data_[boundary_pos - 2] == '\r') {
- data_length--;
- }
- }
- if (data_length > 0) {
- // Send the last data chunk.
- client_->didReceiveData(loader_,
- data_.data(),
- static_cast<int>(data_length),
- encoded_data_length_);
- encoded_data_length_ = 0;
- }
- }
- size_t boundary_end_pos = boundary_pos + boundary_.length();
- if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) {
- // This was the last boundary so we can stop processing.
- stop_sending_ = true;
- data_.clear();
- return;
- }
-
- // We can now throw out data up through the boundary
- int offset = PushOverLine(data_, boundary_end_pos);
- data_ = data_.substr(boundary_end_pos + offset);
-
- // Ok, back to parsing headers
- if (!ParseHeaders()) {
- processing_headers_ = true;
- break;
- }
- }
-
- // At this point, we should send over any data we have, but keep enough data
- // buffered to handle a boundary that may have been truncated.
- if (!processing_headers_ && data_.length() > boundary_.length()) {
- // If the last character is a new line character, go ahead and just send
- // everything we have buffered. This matches an optimization in Gecko.
- int send_length = data_.length() - boundary_.length();
- if (data_[data_.length() - 1] == '\n')
- send_length = data_.length();
- if (client_)
- client_->didReceiveData(loader_,
- data_.data(),
- send_length,
- encoded_data_length_);
- data_ = data_.substr(send_length);
- encoded_data_length_ = 0;
- }
-}
-
-void MultipartResponseDelegate::OnCompletedRequest() {
- // If we have any pending data and we're not in a header, go ahead and send
- // it to WebCore.
- if (!processing_headers_ && !data_.empty() && !stop_sending_ && client_) {
- client_->didReceiveData(loader_,
- data_.data(),
- static_cast<int>(data_.length()),
- encoded_data_length_);
- encoded_data_length_ = 0;
- }
-}
-
-int MultipartResponseDelegate::PushOverLine(const std::string& data,
- size_t pos) {
- int offset = 0;
- if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) {
- ++offset;
- if (pos + 1 < data.length() && data[pos + 1] == '\n')
- ++offset;
- }
- return offset;
-}
-
-bool MultipartResponseDelegate::ParseHeaders() {
- int line_feed_increment = 1;
-
- // Grab the headers being liberal about line endings.
- size_t line_start_pos = 0;
- size_t line_end_pos = data_.find('\n');
- while (line_end_pos != std::string::npos) {
- // Handle CRLF
- if (line_end_pos > line_start_pos && data_[line_end_pos - 1] == '\r') {
- line_feed_increment = 2;
- --line_end_pos;
- } else {
- line_feed_increment = 1;
- }
- if (line_start_pos == line_end_pos) {
- // A blank line, end of headers
- line_end_pos += line_feed_increment;
- break;
- }
- // Find the next header line.
- line_start_pos = line_end_pos + line_feed_increment;
- line_end_pos = data_.find('\n', line_start_pos);
- }
- // Truncated in the middle of a header, stop parsing.
- if (line_end_pos == std::string::npos)
- return false;
-
- // Eat headers
- std::string headers("\n");
- headers.append(data_, 0, line_end_pos);
- data_ = data_.substr(line_end_pos);
-
- // Create a WebURLResponse based on the original set of headers + the
- // replacement headers. We only replace the same few headers that gecko
- // does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp.
- std::string content_type = net::GetSpecificHeader(headers, "content-type");
- std::string mime_type;
- std::string charset;
- bool has_charset = false;
- net::HttpUtil::ParseContentType(content_type, &mime_type, &charset,
- &has_charset, NULL);
- WebURLResponse response(original_response_.url());
- response.setMIMEType(WebString::fromUTF8(mime_type));
- response.setTextEncodingName(WebString::fromUTF8(charset));
-
- HeaderCopier copier(&response);
- original_response_.visitHTTPHeaderFields(&copier);
-
- for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) {
- std::string name(kReplaceHeaders[i]);
- std::string value = net::GetSpecificHeader(headers, name);
- if (!value.empty()) {
- response.setHTTPHeaderField(WebString::fromUTF8(name),
- WebString::fromUTF8(value));
- }
- }
- // To avoid recording every multipart load as a separate visit in
- // the history database, we want to keep track of whether the response
- // is part of a multipart payload. We do want to record the first visit,
- // so we only set isMultipartPayload to true after the first visit.
- response.setIsMultipartPayload(has_sent_first_response_);
- has_sent_first_response_ = true;
- // Send the response!
- if (client_)
- client_->didReceiveResponse(loader_, response);
-
- return true;
-}
-
-// Boundaries are supposed to be preceeded with --, but it looks like gecko
-// doesn't require the dashes to exist. See nsMultiMixedConv::FindToken.
-size_t MultipartResponseDelegate::FindBoundary() {
- size_t boundary_pos = data_.find(boundary_);
- if (boundary_pos != std::string::npos) {
- // Back up over -- for backwards compat
- // TODO(tc): Don't we only want to do this once? Gecko code doesn't seem
- // to care.
- if (boundary_pos >= 2) {
- if ('-' == data_[boundary_pos - 1] && '-' == data_[boundary_pos - 2]) {
- boundary_pos -= 2;
- boundary_ = "--" + boundary_;
- }
- }
- }
- return boundary_pos;
-}
-
-bool MultipartResponseDelegate::ReadMultipartBoundary(
- const WebURLResponse& response,
- std::string* multipart_boundary) {
- std::string content_type =
- response.httpHeaderField(WebString::fromUTF8("Content-Type")).utf8();
-
- size_t boundary_start_offset = content_type.find("boundary=");
- if (boundary_start_offset == std::string::npos)
- return false;
-
- boundary_start_offset += strlen("boundary=");
-
- size_t boundary_end_offset = content_type.find(';', boundary_start_offset);
-
- if (boundary_end_offset == std::string::npos)
- boundary_end_offset = content_type.length();
-
- size_t boundary_length = boundary_end_offset - boundary_start_offset;
-
- *multipart_boundary =
- content_type.substr(boundary_start_offset, boundary_length);
- // The byte range response can have quoted boundary strings. This is legal
- // as per MIME specifications. Individual data fragements however don't
- // contain quoted boundary strings.
- TrimString(*multipart_boundary, "\"", multipart_boundary);
- return true;
-}
-
-bool MultipartResponseDelegate::ReadContentRanges(
- const WebURLResponse& response,
- int64* content_range_lower_bound,
- int64* content_range_upper_bound,
- int64* content_range_instance_size) {
-
- std::string content_range = response.httpHeaderField("Content-Range").utf8();
- if (content_range.empty()) {
- content_range = response.httpHeaderField("Range").utf8();
- }
-
- if (content_range.empty()) {
- DLOG(WARNING) << "Failed to read content range from response.";
- return false;
- }
-
- size_t byte_range_lower_bound_start_offset = content_range.find(" ");
- if (byte_range_lower_bound_start_offset == std::string::npos) {
- return false;
- }
-
- // Skip over the initial space.
- byte_range_lower_bound_start_offset++;
-
- // Find the lower bound.
- size_t byte_range_lower_bound_end_offset =
- content_range.find("-", byte_range_lower_bound_start_offset);
- if (byte_range_lower_bound_end_offset == std::string::npos) {
- return false;
- }
-
- size_t byte_range_lower_bound_characters =
- byte_range_lower_bound_end_offset - byte_range_lower_bound_start_offset;
- std::string byte_range_lower_bound =
- content_range.substr(byte_range_lower_bound_start_offset,
- byte_range_lower_bound_characters);
-
- // Find the upper bound.
- size_t byte_range_upper_bound_start_offset =
- byte_range_lower_bound_end_offset + 1;
-
- size_t byte_range_upper_bound_end_offset =
- content_range.find("/", byte_range_upper_bound_start_offset);
- if (byte_range_upper_bound_end_offset == std::string::npos) {
- return false;
- }
-
- size_t byte_range_upper_bound_characters =
- byte_range_upper_bound_end_offset - byte_range_upper_bound_start_offset;
- std::string byte_range_upper_bound =
- content_range.substr(byte_range_upper_bound_start_offset,
- byte_range_upper_bound_characters);
-
- // Find the instance size.
- size_t byte_range_instance_size_start_offset =
- byte_range_upper_bound_end_offset + 1;
-
- size_t byte_range_instance_size_end_offset =
- content_range.length();
-
- size_t byte_range_instance_size_characters =
- byte_range_instance_size_end_offset -
- byte_range_instance_size_start_offset;
- std::string byte_range_instance_size =
- content_range.substr(byte_range_instance_size_start_offset,
- byte_range_instance_size_characters);
-
- if (!base::StringToInt64(byte_range_lower_bound, content_range_lower_bound))
- return false;
- if (!base::StringToInt64(byte_range_upper_bound, content_range_upper_bound))
- return false;
- if (!base::StringToInt64(byte_range_instance_size,
- content_range_instance_size)) {
- return false;
- }
- return true;
-}
-
-} // namespace webkit_glue
« no previous file with comments | « webkit/glue/multipart_response_delegate.h ('k') | webkit/glue/multipart_response_delegate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698