From 756fbde6911d40d376680c7ab9b576620f64c108 Mon Sep 17 00:00:00 2001 From: "scottmg@chromium.org" Date: Mon, 22 Jul 2013 18:31:42 +0000 Subject: Move webkitplatformsupport_impl and related from glue to child Picking up Ananta's change. Move the webkitplatformsupport_impl.cc/.h files out of webkit\glue to webkit\child. This requires moving the following files out of webkit\glue to webkit\child: 1. weburlloader_impl.cc/.h 2. weburlrequest_extradata_impl.cc/.h 3. websocketstreamhandle_impl.cc/.h 4. weburlresponse_extradata_impl.cc/.h 5. websocketstreamhandle_delegate.h 6. ftp_directory_listing_response_delegate.cc/.h 7. multipart_response_delegate.cc/.h 8. multipart_response_delegate_unittest.cc 9. resource_loader_bridge.cc/.h The following files have been moved to webkit\common: 2. resource_type.cc/.h Move MemoryUsageKB out of webkit_glue.cc/h to webkit/child/webkit_child_helpers. I added an include rule to content\common\DEPS to allow including webkit\child\websocketstreamhandle_delegate.h. This will be removed in a followup. TBR=jam@chromium.org, jamesr@chromium.org, jschuh@chromium.org BUG=237249 Review URL: https://codereview.chromium.org/19673002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212927 0039d316-1c4b-4281-b951-d872f2087c98 --- webkit/browser/appcache/appcache_host.h | 2 +- webkit/browser/appcache/appcache_interceptor.h | 2 +- webkit/browser/appcache/appcache_request_handler.h | 2 +- webkit/child/DEPS | 11 +- .../ftp_directory_listing_response_delegate.cc | 123 +++ .../ftp_directory_listing_response_delegate.h | 53 ++ webkit/child/multipart_response_delegate.cc | 404 +++++++++ webkit/child/multipart_response_delegate.h | 153 ++++ .../child/multipart_response_delegate_unittest.cc | 675 +++++++++++++++ webkit/child/resource_loader_bridge.cc | 37 + webkit/child/resource_loader_bridge.h | 232 ++++++ webkit/child/webkit_child_helpers.cc | 53 ++ webkit/child/webkit_child_helpers.h | 21 + webkit/child/webkitplatformsupport_child_impl.h | 2 +- webkit/child/webkitplatformsupport_impl.cc | 904 +++++++++++++++++++++ webkit/child/webkitplatformsupport_impl.h | 155 ++++ webkit/child/websocketstreamhandle_delegate.h | 44 + webkit/child/websocketstreamhandle_impl.cc | 196 +++++ webkit/child/websocketstreamhandle_impl.h | 40 + webkit/child/weburlloader_impl.cc | 854 +++++++++++++++++++ webkit/child/weburlloader_impl.h | 44 + webkit/child/weburlrequest_extradata_impl.cc | 22 + webkit/child/weburlrequest_extradata_impl.h | 45 + webkit/child/weburlresponse_extradata_impl.cc | 19 + webkit/child/weburlresponse_extradata_impl.h | 96 +++ webkit/common/resource_request_body.h | 2 +- webkit/common/resource_type.cc | 47 ++ webkit/common/resource_type.h | 70 ++ webkit/common/webkit_common.gyp | 6 +- .../ftp_directory_listing_response_delegate.cc | 123 --- .../glue/ftp_directory_listing_response_delegate.h | 53 -- webkit/glue/multipart_response_delegate.cc | 404 --------- webkit/glue/multipart_response_delegate.h | 153 ---- .../glue/multipart_response_delegate_unittest.cc | 675 --------------- webkit/glue/resource_loader_bridge.cc | 36 - webkit/glue/resource_loader_bridge.h | 232 ------ webkit/glue/resource_type.cc | 47 -- webkit/glue/resource_type.h | 70 -- webkit/glue/webkit_glue.cc | 35 - webkit/glue/webkit_glue.gypi | 44 +- webkit/glue/webkit_glue.h | 6 - webkit/glue/webkit_glue_common.gyp | 6 - webkit/glue/webkit_glue_unittest.cc | 2 +- webkit/glue/webkitplatformsupport_impl.cc | 901 -------------------- webkit/glue/webkitplatformsupport_impl.h | 155 ---- webkit/glue/websocketstreamhandle_delegate.h | 44 - webkit/glue/websocketstreamhandle_impl.cc | 196 ----- webkit/glue/websocketstreamhandle_impl.h | 40 - webkit/glue/weburlloader_impl.cc | 854 ------------------- webkit/glue/weburlloader_impl.h | 45 - webkit/glue/weburlrequest_extradata_impl.cc | 22 - webkit/glue/weburlrequest_extradata_impl.h | 45 - webkit/glue/weburlresponse_extradata_impl.cc | 19 - webkit/glue/weburlresponse_extradata_impl.h | 96 --- webkit/mocks/mock_weburlloader.h | 2 +- webkit/plugins/ppapi/url_request_info_util.cc | 2 +- webkit/plugins/webkit_plugins.gypi | 1 + webkit/support/test_webkit_platform_support.cc | 14 +- webkit/support/webkit_support.cc | 2 +- 59 files changed, 4342 insertions(+), 4296 deletions(-) create mode 100644 webkit/child/ftp_directory_listing_response_delegate.cc create mode 100644 webkit/child/ftp_directory_listing_response_delegate.h create mode 100644 webkit/child/multipart_response_delegate.cc create mode 100644 webkit/child/multipart_response_delegate.h create mode 100644 webkit/child/multipart_response_delegate_unittest.cc create mode 100644 webkit/child/resource_loader_bridge.cc create mode 100644 webkit/child/resource_loader_bridge.h create mode 100644 webkit/child/webkit_child_helpers.cc create mode 100644 webkit/child/webkit_child_helpers.h create mode 100644 webkit/child/webkitplatformsupport_impl.cc create mode 100644 webkit/child/webkitplatformsupport_impl.h create mode 100644 webkit/child/websocketstreamhandle_delegate.h create mode 100644 webkit/child/websocketstreamhandle_impl.cc create mode 100644 webkit/child/websocketstreamhandle_impl.h create mode 100644 webkit/child/weburlloader_impl.cc create mode 100644 webkit/child/weburlloader_impl.h create mode 100644 webkit/child/weburlrequest_extradata_impl.cc create mode 100644 webkit/child/weburlrequest_extradata_impl.h create mode 100644 webkit/child/weburlresponse_extradata_impl.cc create mode 100644 webkit/child/weburlresponse_extradata_impl.h create mode 100644 webkit/common/resource_type.cc create mode 100644 webkit/common/resource_type.h delete mode 100644 webkit/glue/ftp_directory_listing_response_delegate.cc delete mode 100644 webkit/glue/ftp_directory_listing_response_delegate.h delete mode 100644 webkit/glue/multipart_response_delegate.cc delete mode 100644 webkit/glue/multipart_response_delegate.h delete mode 100644 webkit/glue/multipart_response_delegate_unittest.cc delete mode 100644 webkit/glue/resource_loader_bridge.cc delete mode 100644 webkit/glue/resource_loader_bridge.h delete mode 100644 webkit/glue/resource_type.cc delete mode 100644 webkit/glue/resource_type.h delete mode 100644 webkit/glue/webkitplatformsupport_impl.cc delete mode 100644 webkit/glue/webkitplatformsupport_impl.h delete mode 100644 webkit/glue/websocketstreamhandle_delegate.h delete mode 100644 webkit/glue/websocketstreamhandle_impl.cc delete mode 100644 webkit/glue/websocketstreamhandle_impl.h delete mode 100644 webkit/glue/weburlloader_impl.cc delete mode 100644 webkit/glue/weburlloader_impl.h delete mode 100644 webkit/glue/weburlrequest_extradata_impl.cc delete mode 100644 webkit/glue/weburlrequest_extradata_impl.h delete mode 100644 webkit/glue/weburlresponse_extradata_impl.cc delete mode 100644 webkit/glue/weburlresponse_extradata_impl.h (limited to 'webkit') diff --git a/webkit/browser/appcache/appcache_host.h b/webkit/browser/appcache/appcache_host.h index fdc97d0..4242bc1 100644 --- a/webkit/browser/appcache/appcache_host.h +++ b/webkit/browser/appcache/appcache_host.h @@ -15,7 +15,7 @@ #include "webkit/browser/appcache/appcache_storage.h" #include "webkit/browser/webkit_storage_browser_export.h" #include "webkit/common/appcache/appcache_interfaces.h" -#include "webkit/glue/resource_type.h" +#include "webkit/common/resource_type.h" namespace net { class URLRequest; diff --git a/webkit/browser/appcache/appcache_interceptor.h b/webkit/browser/appcache/appcache_interceptor.h index 10ae84d..b1db1c0 100644 --- a/webkit/browser/appcache/appcache_interceptor.h +++ b/webkit/browser/appcache/appcache_interceptor.h @@ -9,7 +9,7 @@ #include "net/url_request/url_request.h" #include "url/gurl.h" #include "webkit/browser/webkit_storage_browser_export.h" -#include "webkit/glue/resource_type.h" +#include "webkit/common/resource_type.h" namespace appcache { diff --git a/webkit/browser/appcache/appcache_request_handler.h b/webkit/browser/appcache/appcache_request_handler.h index 1b7753c..606d6cf 100644 --- a/webkit/browser/appcache/appcache_request_handler.h +++ b/webkit/browser/appcache/appcache_request_handler.h @@ -10,7 +10,7 @@ #include "webkit/browser/appcache/appcache_entry.h" #include "webkit/browser/appcache/appcache_host.h" #include "webkit/browser/webkit_storage_browser_export.h" -#include "webkit/glue/resource_type.h" +#include "webkit/common/resource_type.h" namespace net { class NetworkDelegate; diff --git a/webkit/child/DEPS b/webkit/child/DEPS index 552b168..64d1c38 100644 --- a/webkit/child/DEPS +++ b/webkit/child/DEPS @@ -1,5 +1,6 @@ -include_rules = [ - "+jni", # Needed for Android's java-generated bindings. - "+ui/base", - "+ui/native_theme", -] +include_rules = [ + "+content/public/common", + "+jni", # Needed for Android's java-generated bindings. + "+ui/base", + "+ui/native_theme", +] diff --git a/webkit/child/ftp_directory_listing_response_delegate.cc b/webkit/child/ftp_directory_listing_response_delegate.cc new file mode 100644 index 0000000..d84ada6 --- /dev/null +++ b/webkit/child/ftp_directory_listing_response_delegate.cc @@ -0,0 +1,123 @@ +// 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/child/ftp_directory_listing_response_delegate.h" + +#include + +#include "base/i18n/icu_encoding_detection.h" +#include "base/i18n/icu_string_conversions.h" +#include "base/logging.h" +#include "base/strings/string_util.h" +#include "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "net/base/escape.h" +#include "net/base/net_errors.h" +#include "net/base/net_util.h" +#include "net/ftp/ftp_directory_listing_parser.h" +#include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" +#include "webkit/child/weburlresponse_extradata_impl.h" + +using net::FtpDirectoryListingEntry; + +using WebKit::WebURLLoader; +using WebKit::WebURLLoaderClient; +using WebKit::WebURLResponse; + +namespace { + +base::string16 ConvertPathToUTF16(const std::string& path) { + // Per RFC 2640, FTP servers should use UTF-8 or its proper subset ASCII, + // but many old FTP servers use legacy encodings. Try UTF-8 first. + if (IsStringUTF8(path)) + return UTF8ToUTF16(path); + + // Try detecting the encoding. The sample is rather small though, so it may + // fail. + std::string encoding; + if (base::DetectEncoding(path, &encoding) && !encoding.empty()) { + base::string16 path_utf16; + if (base::CodepageToUTF16(path, encoding.c_str(), + base::OnStringConversionError::SUBSTITUTE, + &path_utf16)) { + return path_utf16; + } + } + + // Use system native encoding as the last resort. + return WideToUTF16Hack(base::SysNativeMBToWide(path)); +} + +} // namespace + +namespace webkit_glue { + +FtpDirectoryListingResponseDelegate::FtpDirectoryListingResponseDelegate( + WebURLLoaderClient* client, + WebURLLoader* loader, + const WebURLResponse& response) + : client_(client), + loader_(loader) { + if (response.extraData()) { + // extraData can be NULL during tests. + WebURLResponseExtraDataImpl* extra_data = + static_cast(response.extraData()); + extra_data->set_is_ftp_directory_listing(true); + } + Init(response.url()); +} + +void FtpDirectoryListingResponseDelegate::OnReceivedData(const char* data, + int data_len) { + buffer_.append(data, data_len); +} + +void FtpDirectoryListingResponseDelegate::OnCompletedRequest() { + std::vector entries; + int rv = net::ParseFtpDirectoryListing(buffer_, base::Time::Now(), &entries); + if (rv != net::OK) { + SendDataToClient("\n"); + return; + } + for (size_t i = 0; i < entries.size(); i++) { + FtpDirectoryListingEntry entry = entries[i]; + + // Skip the current and parent directory entries in the listing. Our header + // always includes them. + if (EqualsASCII(entry.name, ".") || EqualsASCII(entry.name, "..")) + continue; + + bool is_directory = (entry.type == FtpDirectoryListingEntry::DIRECTORY); + int64 size = entry.size; + if (entry.type != FtpDirectoryListingEntry::FILE) + size = 0; + SendDataToClient(net::GetDirectoryListingEntry( + entry.name, entry.raw_name, is_directory, size, entry.last_modified)); + } +} + +void FtpDirectoryListingResponseDelegate::Init(const GURL& response_url) { + net::UnescapeRule::Type unescape_rules = net::UnescapeRule::SPACES | + net::UnescapeRule::URL_SPECIAL_CHARS; + std::string unescaped_path = net::UnescapeURLComponent(response_url.path(), + unescape_rules); + SendDataToClient(net::GetDirectoryListingHeader( + ConvertPathToUTF16(unescaped_path))); + + // If this isn't top level directory (i.e. the path isn't "/",) + // add a link to the parent directory. + if (response_url.path().length() > 1) { + SendDataToClient(net::GetDirectoryListingEntry( + ASCIIToUTF16(".."), std::string(), false, 0, base::Time())); + } +} + +void FtpDirectoryListingResponseDelegate::SendDataToClient( + const std::string& data) { + client_->didReceiveData(loader_, data.data(), data.length(), -1); +} + +} // namespace webkit_glue diff --git a/webkit/child/ftp_directory_listing_response_delegate.h b/webkit/child/ftp_directory_listing_response_delegate.h new file mode 100644 index 0000000..efcbb21 --- /dev/null +++ b/webkit/child/ftp_directory_listing_response_delegate.h @@ -0,0 +1,53 @@ +// Copyright (c) 2011 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. +// +// A delegate class of WebURLLoaderImpl that handles text/vnd.chromium.ftp-dir +// data. + +#ifndef WEBKIT_CHILD_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_ +#define WEBKIT_CHILD_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_ + +#include + +#include "base/basictypes.h" +#include "third_party/WebKit/public/platform/WebURLResponse.h" + +namespace WebKit { +class WebURLLoader; +class WebURLLoaderClient; +} + +class GURL; + +namespace webkit_glue { + +class FtpDirectoryListingResponseDelegate { + public: + FtpDirectoryListingResponseDelegate(WebKit::WebURLLoaderClient* client, + WebKit::WebURLLoader* loader, + const WebKit::WebURLResponse& response); + + // Passed through from ResourceHandleInternal + void OnReceivedData(const char* data, int data_len); + void OnCompletedRequest(); + + private: + void Init(const GURL& response_url); + + void SendDataToClient(const std::string& data); + + // Pointers to the client and associated loader so we can make callbacks as + // we parse pieces of data. + WebKit::WebURLLoaderClient* client_; + WebKit::WebURLLoader* loader_; + + // Buffer for data received from the network. + std::string buffer_; + + DISALLOW_COPY_AND_ASSIGN(FtpDirectoryListingResponseDelegate); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_ diff --git a/webkit/child/multipart_response_delegate.cc b/webkit/child/multipart_response_delegate.cc new file mode 100644 index 0000000..06af916 --- /dev/null +++ b/webkit/child/multipart_response_delegate.cc @@ -0,0 +1,404 @@ +// 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/child/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(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(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 diff --git a/webkit/child/multipart_response_delegate.h b/webkit/child/multipart_response_delegate.h new file mode 100644 index 0000000..f85c1cf --- /dev/null +++ b/webkit/child/multipart_response_delegate.h @@ -0,0 +1,153 @@ +// Copyright (c) 2011 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. +// +// A delegate class of WebURLLoaderImpl that handles multipart/x-mixed-replace +// data. We special case multipart/x-mixed-replace because WebCore expects a +// separate didReceiveResponse for each new message part. +// +// Most of the logic and edge case handling are based on the Mozilla's +// implementation in netwerk/streamconv/converters/nsMultiMixedConv.cpp. +// This seems like a derivative work, so here's the original license: + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef WEBKIT_CHILD_MULTIPART_RESPONSE_DELEGATE_H_ +#define WEBKIT_CHILD_MULTIPART_RESPONSE_DELEGATE_H_ + +#include + +#include "base/basictypes.h" +#include "third_party/WebKit/public/platform/WebURLResponse.h" +#include "webkit/child/webkit_child_export.h" + +namespace WebKit { +class WebURLLoader; +class WebURLLoaderClient; +} + +namespace webkit_glue { + +// Used by unit tests to access private members. +class MultipartResponseDelegateTester; + +class WEBKIT_CHILD_EXPORT MultipartResponseDelegate { + public: + MultipartResponseDelegate(WebKit::WebURLLoaderClient* client, + WebKit::WebURLLoader* loader, + const WebKit::WebURLResponse& response, + const std::string& boundary); + + // Passed through from ResourceHandleInternal + void OnReceivedData(const char* data, int data_len, int encoded_data_length); + void OnCompletedRequest(); + + // The request has been canceled, so stop making calls to the client. + void Cancel() { + client_ = NULL; + loader_ = NULL; + } + + // Returns the multi part boundary string from the Content-type header + // in the response. + // Returns true on success. + static bool ReadMultipartBoundary(const WebKit::WebURLResponse& response, + std::string* multipart_boundary); + + // Returns the lower and higher content ranges from an individual multipart + // in a multipart response. + // Returns true on success. + static bool ReadContentRanges( + const WebKit::WebURLResponse& response, + int64* content_range_lower_bound, + int64* content_range_upper_bound, + int64* content_range_instance_size); + + private: + friend class MultipartResponseDelegateTester; // For unittests. + + // Pointers to the client and associated loader so we can make callbacks as + // we parse pieces of data. + WebKit::WebURLLoaderClient* client_; + WebKit::WebURLLoader* loader_; + + // The original resource response for this request. We use this as a + // starting point for each parts response. + WebKit::WebURLResponse original_response_; + + // Checks to see if data[pos] character is a line break; handles crlf, lflf, + // lf, or cr. Returns the number of characters to skip over (0, 1 or 2). + int PushOverLine(const std::string& data, size_t pos); + + // Tries to parse http headers from the start of data_. Returns true if it + // succeeds and sends a didReceiveResponse to m_client. Returns false if + // the header is incomplete (in which case we just wait for more data). + bool ParseHeaders(); + + // Find the next boundary in data_. Returns std::string::npos if there's no + // full token. + size_t FindBoundary(); + + // Transferred data size accumulated between client callbacks. + int encoded_data_length_; + + // A temporary buffer to hold data between reads for multipart data that + // gets split in the middle of a header. + std::string data_; + + // Multipart boundary token + std::string boundary_; + + // true until we get our first on received data call + bool first_received_data_; + + // true if we're truncated in the middle of a header + bool processing_headers_; + + // true when we're done sending information. At that point, we stop + // processing AddData requests. + bool stop_sending_; + + // true after we've sent our first response to the WebURLLoaderClient. + bool has_sent_first_response_; + + DISALLOW_COPY_AND_ASSIGN(MultipartResponseDelegate); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_MULTIPART_RESPONSE_DELEGATE_H_ diff --git a/webkit/child/multipart_response_delegate_unittest.cc b/webkit/child/multipart_response_delegate_unittest.cc new file mode 100644 index 0000000..34ea209 --- /dev/null +++ b/webkit/child/multipart_response_delegate_unittest.cc @@ -0,0 +1,675 @@ +// Copyright (c) 2011 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 + +#include "base/basictypes.h" +#include "testing/gtest/include/gtest/gtest.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" +#include "third_party/WebKit/public/platform/WebURLResponse.h" +#include "webkit/child/multipart_response_delegate.h" + +using std::string; +using WebKit::WebString; +using WebKit::WebURL; +using WebKit::WebURLError; +using WebKit::WebURLLoader; +using WebKit::WebURLLoaderClient; +using WebKit::WebURLRequest; +using WebKit::WebURLResponse; +using webkit_glue::MultipartResponseDelegate; +using webkit_glue::MultipartResponseDelegateTester; + +namespace webkit_glue { + +class MultipartResponseDelegateTester { + public: + MultipartResponseDelegateTester(MultipartResponseDelegate* delegate) + : delegate_(delegate) { + } + + int PushOverLine(const std::string& data, size_t pos) { + return delegate_->PushOverLine(data, pos); + } + + bool ParseHeaders() { return delegate_->ParseHeaders(); } + size_t FindBoundary() { return delegate_->FindBoundary(); } + std::string& boundary() { return delegate_->boundary_; } + std::string& data() { return delegate_->data_; } + + private: + MultipartResponseDelegate* delegate_; +}; + +} // namespace webkit_glue + +namespace { + +class MultipartResponseTest : public testing::Test { +}; + +class MockWebURLLoaderClient : public WebURLLoaderClient { + public: + MockWebURLLoaderClient() { Reset(); } + + virtual void willSendRequest( + WebURLLoader*, WebURLRequest&, const WebURLResponse&) {} + virtual void didSendData( + WebURLLoader*, unsigned long long, unsigned long long) {} + + virtual void didReceiveResponse(WebURLLoader* loader, + const WebURLResponse& response) { + ++received_response_; + response_ = response; + data_.clear(); + } + virtual void didReceiveData( + WebKit::WebURLLoader* loader, + const char* data, + int data_length, + int encoded_data_length) { + ++received_data_; + data_.append(data, data_length); + total_encoded_data_length_ += encoded_data_length; + } + virtual void didFinishLoading(WebURLLoader*, double finishTime) {} + virtual void didFail(WebURLLoader*, const WebURLError&) {} + + void Reset() { + received_response_ = received_data_ = total_encoded_data_length_ = 0; + data_.clear(); + response_.reset(); + } + + string GetResponseHeader(const char* name) const { + return string(response_.httpHeaderField(WebString::fromUTF8(name)).utf8()); + } + + int received_response_, received_data_, total_encoded_data_length_; + string data_; + WebURLResponse response_; +}; + +// We can't put this in an anonymous function because it's a friend class for +// access to private members. +TEST(MultipartResponseTest, Functions) { + // PushOverLine tests + + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Foo", "Bar"); + response.setHTTPHeaderField("Content-type", "text/plain"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "bound"); + MultipartResponseDelegateTester delegate_tester(&delegate); + + struct { + const char* input; + const int position; + const int expected; + } line_tests[] = { + { "Line", 0, 0 }, + { "Line", 2, 0 }, + { "Line", 10, 0 }, + { "\r\nLine", 0, 2 }, + { "\nLine", 0, 1 }, + { "\n\nLine", 0, 2 }, + { "\rLine", 0, 1 }, + { "Line\r\nLine", 4, 2 }, + { "Line\nLine", 4, 1 }, + { "Line\n\nLine", 4, 2 }, + { "Line\rLine", 4, 1 }, + { "Line\r\rLine", 4, 1 }, + }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(line_tests); ++i) { + EXPECT_EQ(line_tests[i].expected, + delegate_tester.PushOverLine(line_tests[i].input, + line_tests[i].position)); + } + + // ParseHeaders tests + struct { + const char* data; + const bool rv; + const int received_response_calls; + const char* newdata; + } header_tests[] = { + { "This is junk", false, 0, "This is junk" }, + { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" }, + { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" }, + { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" }, + { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" }, + { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" }, + { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" }, + { "\r\n", true, 1, "" }, + }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(header_tests); ++i) { + client.Reset(); + delegate_tester.data().assign(header_tests[i].data); + EXPECT_EQ(header_tests[i].rv, + delegate_tester.ParseHeaders()); + EXPECT_EQ(header_tests[i].received_response_calls, + client.received_response_); + EXPECT_EQ(string(header_tests[i].newdata), + delegate_tester.data()); + } + // Test that the resource response is filled in correctly when parsing + // headers. + client.Reset(); + string test_header("content-type: image/png\ncontent-length: 10\n\n"); + delegate_tester.data().assign(test_header); + EXPECT_TRUE(delegate_tester.ParseHeaders()); + EXPECT_TRUE(delegate_tester.data().length() == 0); + EXPECT_EQ(string("image/png"), client.GetResponseHeader("Content-Type")); + EXPECT_EQ(string("10"), client.GetResponseHeader("content-length")); + // This header is passed from the original request. + EXPECT_EQ(string("Bar"), client.GetResponseHeader("foo")); + + // Make sure we parse the right mime-type if a charset is provided. + client.Reset(); + string test_header2("content-type: text/html; charset=utf-8\n\n"); + delegate_tester.data().assign(test_header2); + EXPECT_TRUE(delegate_tester.ParseHeaders()); + EXPECT_TRUE(delegate_tester.data().length() == 0); + EXPECT_EQ(string("text/html; charset=utf-8"), + client.GetResponseHeader("Content-Type")); + EXPECT_EQ(string("utf-8"), + string(client.response_.textEncodingName().utf8())); + + // FindBoundary tests + struct { + const char* boundary; + const char* data; + const size_t position; + } boundary_tests[] = { + { "bound", "bound", 0 }, + { "bound", "--bound", 0 }, + { "bound", "junkbound", 4 }, + { "bound", "junk--bound", 4 }, + { "foo", "bound", string::npos }, + { "bound", "--boundbound", 0 }, + }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(boundary_tests); ++i) { + delegate_tester.boundary().assign(boundary_tests[i].boundary); + delegate_tester.data().assign(boundary_tests[i].data); + EXPECT_EQ(boundary_tests[i].position, + delegate_tester.FindBoundary()); + } +} + +TEST(MultipartResponseTest, MissingBoundaries) { + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Foo", "Bar"); + response.setHTTPHeaderField("Content-type", "text/plain"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "bound"); + + // No start boundary + string no_start_boundary( + "Content-type: text/plain\n\n" + "This is a sample response\n" + "--bound--" + "ignore junk after end token --bound\n\nTest2\n"); + delegate.OnReceivedData(no_start_boundary.c_str(), + static_cast(no_start_boundary.length()), + static_cast(no_start_boundary.length())); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); + EXPECT_EQ(string("This is a sample response"), client.data_); + EXPECT_EQ(static_cast(no_start_boundary.length()), + client.total_encoded_data_length_); + + delegate.OnCompletedRequest(); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); + + // No end boundary + client.Reset(); + MultipartResponseDelegate delegate2(&client, NULL, response, "bound"); + string no_end_boundary( + "bound\nContent-type: text/plain\n\n" + "This is a sample response\n"); + delegate2.OnReceivedData(no_end_boundary.c_str(), + static_cast(no_end_boundary.length()), + static_cast(no_end_boundary.length())); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); + EXPECT_EQ("This is a sample response\n", client.data_); + EXPECT_EQ(static_cast(no_end_boundary.length()), + client.total_encoded_data_length_); + + delegate2.OnCompletedRequest(); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); + EXPECT_EQ(string("This is a sample response\n"), client.data_); + EXPECT_EQ(static_cast(no_end_boundary.length()), + client.total_encoded_data_length_); + + // Neither boundary + client.Reset(); + MultipartResponseDelegate delegate3(&client, NULL, response, "bound"); + string no_boundaries( + "Content-type: text/plain\n\n" + "This is a sample response\n"); + delegate3.OnReceivedData(no_boundaries.c_str(), + static_cast(no_boundaries.length()), + static_cast(no_boundaries.length())); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); + EXPECT_EQ("This is a sample response\n", client.data_); + EXPECT_EQ(static_cast(no_boundaries.length()), + client.total_encoded_data_length_); + + delegate3.OnCompletedRequest(); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); + EXPECT_EQ(string("This is a sample response\n"), client.data_); + EXPECT_EQ(static_cast(no_boundaries.length()), + client.total_encoded_data_length_); +} + +TEST(MultipartResponseTest, MalformedBoundary) { + // Some servers send a boundary that is prefixed by "--". See bug 5786. + + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Foo", "Bar"); + response.setHTTPHeaderField("Content-type", "text/plain"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "--bound"); + + string data( + "--bound\n" + "Content-type: text/plain\n\n" + "This is a sample response\n" + "--bound--" + "ignore junk after end token --bound\n\nTest2\n"); + delegate.OnReceivedData(data.c_str(), + static_cast(data.length()), + static_cast(data.length())); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); + EXPECT_EQ(string("This is a sample response"), client.data_); + EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); + + delegate.OnCompletedRequest(); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(1, client.received_data_); +} + + +// Used in for tests that break the data in various places. +struct TestChunk { + const int start_pos; // offset in data + const int end_pos; // end offset in data + const int expected_responses; + const int expected_received_data; + const char* expected_data; + const int expected_encoded_data_length; +}; + +void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size, + int responses, int received_data, + const char* completed_data, + int completed_encoded_data_length) { + const string data( + "--bound\n" // 0-7 + "Content-type: image/png\n\n" // 8-32 + "datadatadatadatadata" // 33-52 + "--bound\n" // 53-60 + "Content-type: image/jpg\n\n" // 61-85 + "foofoofoofoofoo" // 86-100 + "--bound--"); // 101-109 + + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "bound"); + + for (int i = 0; i < chunks_size; ++i) { + ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos); + string chunk = data.substr(chunks[i].start_pos, + chunks[i].end_pos - chunks[i].start_pos); + delegate.OnReceivedData( + chunk.c_str(), + static_cast(chunk.length()), + static_cast(chunk.length())); + EXPECT_EQ(chunks[i].expected_responses, client.received_response_); + EXPECT_EQ(chunks[i].expected_received_data, client.received_data_); + EXPECT_EQ(string(chunks[i].expected_data), client.data_); + EXPECT_EQ(chunks[i].expected_encoded_data_length, + client.total_encoded_data_length_); + } + // Check final state + delegate.OnCompletedRequest(); + EXPECT_EQ(responses, client.received_response_); + EXPECT_EQ(received_data, client.received_data_); + string completed_data_string(completed_data); + EXPECT_EQ(completed_data_string, client.data_); + EXPECT_EQ(completed_encoded_data_length, client.total_encoded_data_length_); +} + +TEST(MultipartResponseTest, BreakInBoundary) { + // Break in the first boundary + const TestChunk bound1[] = { + { 0, 4, 0, 0, "", 0 }, + { 4, 110, 2, 2, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(bound1, arraysize(bound1), + 2, 2, "foofoofoofoofoo", 110); + + // Break in first and second + const TestChunk bound2[] = { + { 0, 4, 0, 0, "", 0 }, + { 4, 55, 1, 1, "datadatadatadat", 55 }, + { 55, 65, 1, 2, "datadatadatadatadata", 65 }, + { 65, 110, 2, 3, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(bound2, arraysize(bound2), + 2, 3, "foofoofoofoofoo", 110); + + // Break in second only + const TestChunk bound3[] = { + { 0, 55, 1, 1, "datadatadatadat", 55 }, + { 55, 110, 2, 3, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(bound3, arraysize(bound3), + 2, 3, "foofoofoofoofoo", 110); +} + +TEST(MultipartResponseTest, BreakInHeaders) { + // Break in first header + const TestChunk header1[] = { + { 0, 10, 0, 0, "", 0 }, + { 10, 35, 1, 0, "", 0 }, + { 35, 110, 2, 2, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(header1, arraysize(header1), + 2, 2, "foofoofoofoofoo", 110); + + // Break in both headers + const TestChunk header2[] = { + { 0, 10, 0, 0, "", 0 }, + { 10, 65, 1, 1, "datadatadatadatadata", 65 }, + { 65, 110, 2, 2, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(header2, arraysize(header2), + 2, 2, "foofoofoofoofoo", 110); + + // Break at end of a header + const TestChunk header3[] = { + { 0, 33, 1, 0, "", 0 }, + { 33, 65, 1, 1, "datadatadatadatadata", 65 }, + { 65, 110, 2, 2, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(header3, arraysize(header3), + 2, 2, "foofoofoofoofoo", 110); +} + +TEST(MultipartResponseTest, BreakInData) { + // All data as one chunk + const TestChunk data1[] = { + { 0, 110, 2, 2, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(data1, arraysize(data1), + 2, 2, "foofoofoofoofoo", 110); + + // breaks in data segment + const TestChunk data2[] = { + { 0, 35, 1, 0, "", 0 }, + { 35, 65, 1, 1, "datadatadatadatadata", 65 }, + { 65, 90, 2, 1, "", 65 }, + { 90, 110, 2, 2, "foofoofoofoofoo", 110 }, + }; + VariousChunkSizesTest(data2, arraysize(data2), + 2, 2, "foofoofoofoofoo", 110); + + // Incomplete send + const TestChunk data3[] = { + { 0, 35, 1, 0, "", 0 }, + { 35, 90, 2, 1, "", 90 }, + }; + VariousChunkSizesTest(data3, arraysize(data3), + 2, 2, "foof", 90); +} + +TEST(MultipartResponseTest, SmallChunk) { + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + response.setHTTPHeaderField("Content-type", "text/plain"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "bound"); + + // Test chunks of size 1, 2, and 0. + string data( + "--boundContent-type: text/plain\n\n" + "\n--boundContent-type: text/plain\n\n" + "\n\n--boundContent-type: text/plain\n\n" + "--boundContent-type: text/plain\n\n" + "end--bound--"); + delegate.OnReceivedData(data.c_str(), + static_cast(data.length()), + static_cast(data.length())); + EXPECT_EQ(4, client.received_response_); + EXPECT_EQ(2, client.received_data_); + EXPECT_EQ(string("end"), client.data_); + EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); + + delegate.OnCompletedRequest(); + EXPECT_EQ(4, client.received_response_); + EXPECT_EQ(2, client.received_data_); +} + +TEST(MultipartResponseTest, MultipleBoundaries) { + // Test multiple boundaries back to back + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "bound"); + + string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--"); + delegate.OnReceivedData(data.c_str(), + static_cast(data.length()), + static_cast(data.length())); + EXPECT_EQ(2, client.received_response_); + EXPECT_EQ(1, client.received_data_); + EXPECT_EQ(string("foofoo"), client.data_); + EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); +} + +TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { + // Test multipart/byteranges based boundary parsing. + WebURLResponse response1; + response1.initialize(); + response1.setMIMEType("multipart/x-mixed-replace"); + response1.setHTTPHeaderField("Content-Length", "200"); + response1.setHTTPHeaderField("Content-type", + "multipart/byteranges; boundary=--bound--"); + + std::string multipart_boundary; + bool result = MultipartResponseDelegate::ReadMultipartBoundary( + response1, &multipart_boundary); + EXPECT_EQ(result, true); + EXPECT_EQ(string("--bound--"), + multipart_boundary); + + WebURLResponse response2; + response2.initialize(); + response2.setMIMEType("image/png"); + + response2.setHTTPHeaderField("Content-Length", "300"); + response2.setHTTPHeaderField("Last-Modified", + "Mon, 04 Apr 2005 20:36:01 GMT"); + response2.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT"); + + multipart_boundary.clear(); + result = MultipartResponseDelegate::ReadMultipartBoundary( + response2, &multipart_boundary); + EXPECT_EQ(result, false); + + WebURLResponse response3; + response3.initialize(); + response3.setMIMEType("multipart/byteranges"); + + response3.setHTTPHeaderField("Content-Length", "300"); + response3.setHTTPHeaderField("Last-Modified", + "Mon, 04 Apr 2005 20:36:01 GMT"); + response3.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT"); + response3.setHTTPHeaderField("Content-type", "multipart/byteranges"); + + multipart_boundary.clear(); + result = MultipartResponseDelegate::ReadMultipartBoundary( + response3, &multipart_boundary); + EXPECT_EQ(result, false); + EXPECT_EQ(multipart_boundary.length(), 0U); + + WebURLResponse response4; + response4.initialize(); + response4.setMIMEType("multipart/byteranges"); + response4.setHTTPHeaderField("Content-Length", "200"); + response4.setHTTPHeaderField("Content-type", + "multipart/byteranges; boundary=--bound--; charSet=utf8"); + + multipart_boundary.clear(); + + result = MultipartResponseDelegate::ReadMultipartBoundary( + response4, &multipart_boundary); + EXPECT_EQ(result, true); + EXPECT_EQ(string("--bound--"), multipart_boundary); + + WebURLResponse response5; + response5.initialize(); + response5.setMIMEType("multipart/byteranges"); + response5.setHTTPHeaderField("Content-Length", "200"); + response5.setHTTPHeaderField("Content-type", + "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8"); + + multipart_boundary.clear(); + + result = MultipartResponseDelegate::ReadMultipartBoundary( + response5, &multipart_boundary); + EXPECT_EQ(result, true); + EXPECT_EQ(string("--bound--"), multipart_boundary); +} + +TEST(MultipartResponseTest, MultipartContentRangesTest) { + WebURLResponse response1; + response1.initialize(); + response1.setMIMEType("application/pdf"); + response1.setHTTPHeaderField("Content-Length", "200"); // Ignored! + // Use intentionally >32bit values to check they are handled correctly. + response1.setHTTPHeaderField("Content-Range", + "bytes 5000000000-5000000050/6000000000"); + + int64 content_range_lower_bound = 0; + int64 content_range_upper_bound = 0; + int64 content_range_instance_size = 0; + + bool result = MultipartResponseDelegate::ReadContentRanges( + response1, &content_range_lower_bound, + &content_range_upper_bound, + &content_range_instance_size); + + EXPECT_EQ(result, true); + EXPECT_EQ(content_range_lower_bound, 5e9); + EXPECT_EQ(content_range_upper_bound, 5e9+50); + EXPECT_EQ(content_range_instance_size, 6e9); + + WebURLResponse response2; + response2.initialize(); + response2.setMIMEType("application/pdf"); + response2.setHTTPHeaderField("Content-Length", "200"); + response2.setHTTPHeaderField("Content-Range", "bytes 1000/1050"); + + content_range_lower_bound = 0; + content_range_upper_bound = 0; + content_range_instance_size = 0; + + result = MultipartResponseDelegate::ReadContentRanges( + response2, &content_range_lower_bound, + &content_range_upper_bound, + &content_range_instance_size); + + EXPECT_EQ(result, false); + + WebURLResponse response3; + response3.initialize(); + response3.setMIMEType("application/pdf"); + response3.setHTTPHeaderField("Content-Length", "200"); + response3.setHTTPHeaderField("Range", "bytes 1000-1050/5000"); + + content_range_lower_bound = 0; + content_range_upper_bound = 0; + content_range_instance_size = 0; + + result = MultipartResponseDelegate::ReadContentRanges( + response3, &content_range_lower_bound, + &content_range_upper_bound, + &content_range_instance_size); + + EXPECT_EQ(result, true); + EXPECT_EQ(content_range_lower_bound, 1000); + EXPECT_EQ(content_range_upper_bound, 1050); + + WebURLResponse response4; + response4.initialize(); + response4.setMIMEType("application/pdf"); + response4.setHTTPHeaderField("Content-Length", "200"); + + content_range_lower_bound = 0; + content_range_upper_bound = 0; + content_range_instance_size = 0; + + result = MultipartResponseDelegate::ReadContentRanges( + response4, &content_range_lower_bound, + &content_range_upper_bound, + &content_range_instance_size); + + EXPECT_EQ(result, false); +} + +TEST(MultipartResponseTest, MultipartPayloadSet) { + WebURLResponse response; + response.initialize(); + response.setMIMEType("multipart/x-mixed-replace"); + MockWebURLLoaderClient client; + MultipartResponseDelegate delegate(&client, NULL, response, "bound"); + + string data( + "--bound\n" + "Content-type: text/plain\n\n" + "response data\n" + "--bound\n"); + delegate.OnReceivedData(data.c_str(), + static_cast(data.length()), + static_cast(data.length())); + EXPECT_EQ(1, client.received_response_); + EXPECT_EQ(string("response data"), client.data_); + EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); + EXPECT_FALSE(client.response_.isMultipartPayload()); + + string data2( + "Content-type: text/plain\n\n" + "response data2\n" + "--bound\n"); + delegate.OnReceivedData(data2.c_str(), + static_cast(data2.length()), + static_cast(data2.length())); + EXPECT_EQ(2, client.received_response_); + EXPECT_EQ(string("response data2"), client.data_); + EXPECT_EQ(static_cast(data.length()) + static_cast(data2.length()), + client.total_encoded_data_length_); + EXPECT_TRUE(client.response_.isMultipartPayload()); +} + +} // namespace diff --git a/webkit/child/resource_loader_bridge.cc b/webkit/child/resource_loader_bridge.cc new file mode 100644 index 0000000..077f557 --- /dev/null +++ b/webkit/child/resource_loader_bridge.cc @@ -0,0 +1,37 @@ +// 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/child/resource_loader_bridge.h" + +#include "net/http/http_response_headers.h" +#include "webkit/common/appcache/appcache_interfaces.h" +#include "webkit/common/resource_response_info.h" + +namespace webkit_glue { + +ResourceLoaderBridge::RequestInfo::RequestInfo() + : referrer_policy(WebKit::WebReferrerPolicyDefault), + load_flags(0), + requestor_pid(0), + request_type(ResourceType::MAIN_FRAME), + priority(net::LOW), + request_context(0), + appcache_host_id(0), + routing_id(0), + download_to_file(false), + has_user_gesture(false), + extra_data(NULL) { +} + +ResourceLoaderBridge::RequestInfo::~RequestInfo() {} + +ResourceLoaderBridge::SyncLoadResponse::SyncLoadResponse() {} + +ResourceLoaderBridge::SyncLoadResponse::~SyncLoadResponse() {} + +ResourceLoaderBridge::ResourceLoaderBridge() {} + +ResourceLoaderBridge::~ResourceLoaderBridge() {} + +} // namespace webkit_glue diff --git a/webkit/child/resource_loader_bridge.h b/webkit/child/resource_loader_bridge.h new file mode 100644 index 0000000..9d51b62 --- /dev/null +++ b/webkit/child/resource_loader_bridge.h @@ -0,0 +1,232 @@ +// 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. +// +// The intent of this file is to provide a type-neutral abstraction between +// Chrome and WebKit for resource loading. This pure-virtual interface is +// implemented by the embedder. +// +// One of these objects will be created by WebKit for each request. WebKit +// will own the pointer to the bridge, and will delete it when the request is +// no longer needed. +// +// In turn, the bridge's owner on the WebKit end will implement the Peer +// interface, which we will use to communicate notifications back. + +#ifndef WEBKIT_CHILD_RESOURCE_LOADER_BRIDGE_H_ +#define WEBKIT_CHILD_RESOURCE_LOADER_BRIDGE_H_ + +#include + +#include "build/build_config.h" +#if defined(OS_POSIX) +#include "base/file_descriptor_posix.h" +#endif +#include "base/memory/ref_counted.h" +#include "base/platform_file.h" +#include "base/values.h" +#include "net/base/request_priority.h" +#include "third_party/WebKit/public/platform/WebReferrerPolicy.h" +#include "third_party/WebKit/public/platform/WebURLRequest.h" +#include "url/gurl.h" +#include "webkit/child/webkit_child_export.h" +#include "webkit/common/resource_response_info.h" +#include "webkit/common/resource_type.h" + +namespace webkit_glue { +class ResourceRequestBody; + +class ResourceLoaderBridge { + public: + // Structure used when calling + // WebKitPlatformSupportImpl::CreateResourceLoader(). + struct WEBKIT_CHILD_EXPORT RequestInfo { + RequestInfo(); + ~RequestInfo(); + + // HTTP-style method name (e.g., "GET" or "POST"). + std::string method; + + // Absolute URL encoded in ASCII per the rules of RFC-2396. + GURL url; + + // URL of the document in the top-level window, which may be checked by the + // third-party cookie blocking policy. + GURL first_party_for_cookies; + + // Optional parameter, a URL with similar constraints in how it must be + // encoded as the url member. + GURL referrer; + + // The referrer policy that applies to the referrer. + WebKit::WebReferrerPolicy referrer_policy; + + // For HTTP(S) requests, the headers parameter can be a \r\n-delimited and + // \r\n-terminated list of MIME headers. They should be ASCII-encoded using + // the standard MIME header encoding rules. The headers parameter can also + // be null if no extra request headers need to be set. + std::string headers; + + // Composed of the values defined in url_request_load_flags.h. + int load_flags; + + // Process id of the process making the request. + int requestor_pid; + + // Indicates if the current request is the main frame load, a sub-frame + // load, or a sub objects load. + ResourceType::Type request_type; + + // Indicates the priority of this request, as determined by WebKit. + net::RequestPriority priority; + + // Used for plugin to browser requests. + uint32 request_context; + + // Identifies what appcache host this request is associated with. + int appcache_host_id; + + // Used to associated the bridge with a frame's network context. + int routing_id; + + // If true, then the response body will be downloaded to a file and the + // path to that file will be provided in ResponseInfo::download_file_path. + bool download_to_file; + + // True if the request was user initiated. + bool has_user_gesture; + + // Extra data associated with this request. We do not own this pointer. + WebKit::WebURLRequest::ExtraData* extra_data; + + private: + DISALLOW_COPY_AND_ASSIGN(RequestInfo); + }; + + // See the SyncLoad method declared below. (The name of this struct is not + // suffixed with "Info" because it also contains the response data.) + struct SyncLoadResponse : ResourceResponseInfo { + WEBKIT_CHILD_EXPORT SyncLoadResponse(); + WEBKIT_CHILD_EXPORT ~SyncLoadResponse(); + + // The response error code. + int error_code; + + // The final URL of the response. This may differ from the request URL in + // the case of a server redirect. + GURL url; + + // The response data. + std::string data; + }; + + // Generated by the bridge. This is implemented by our custom resource loader + // within webkit. The Peer and it's bridge should have identical lifetimes + // as they represent each end of a communication channel. + // + // These callbacks mirror net::URLRequest::Delegate and the order and + // conditions in which they will be called are identical. See url_request.h + // for more information. + class Peer { + public: + // Called as upload progress is made. + // note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set + virtual void OnUploadProgress(uint64 position, uint64 size) = 0; + + // Called when a redirect occurs. The implementation may return false to + // suppress the redirect. The given ResponseInfo provides complete + // information about the redirect, and new_url is the URL that will be + // loaded if this method returns true. If this method returns true, the + // output parameter *has_new_first_party_for_cookies indicates whether the + // output parameter *new_first_party_for_cookies contains the new URL that + // should be consulted for the third-party cookie blocking policy. + virtual bool OnReceivedRedirect(const GURL& new_url, + const ResourceResponseInfo& info, + bool* has_new_first_party_for_cookies, + GURL* new_first_party_for_cookies) = 0; + + // Called when response headers are available (after all redirects have + // been followed). + virtual void OnReceivedResponse(const ResourceResponseInfo& info) = 0; + + // Called when a chunk of response data is downloaded. This method may be + // called multiple times or not at all if an error occurs. This method is + // only called if RequestInfo::download_to_file was set to true, and in + // that case, OnReceivedData will not be called. + virtual void OnDownloadedData(int len) = 0; + + // Called when a chunk of response data is available. This method may + // be called multiple times or not at all if an error occurs. + // The encoded_data_length is the length of the encoded data transferred + // over the network, which could be different from data length (e.g. for + // gzipped content), or -1 if if unknown. + virtual void OnReceivedData(const char* data, + int data_length, + int encoded_data_length) = 0; + + // Called when metadata generated by the renderer is retrieved from the + // cache. This method may be called zero or one times. + virtual void OnReceivedCachedMetadata(const char* data, int len) { } + + // Called when the response is complete. This method signals completion of + // the resource load. + virtual void OnCompletedRequest( + int error_code, + bool was_ignored_by_handler, + const std::string& security_info, + const base::TimeTicks& completion_time) = 0; + + protected: + virtual ~Peer() {} + }; + + // use WebKitPlatformSupportImpl::CreateResourceLoader() for construction, but + // anybody can delete at any time, INCLUDING during processing of callbacks. + WEBKIT_CHILD_EXPORT virtual ~ResourceLoaderBridge(); + + // Call this method before calling Start() to set the request body. + // May only be used with HTTP(S) POST requests. + virtual void SetRequestBody(ResourceRequestBody* request_body) = 0; + + // Call this method to initiate the request. If this method succeeds, then + // the peer's methods will be called asynchronously to report various events. + virtual bool Start(Peer* peer) = 0; + + // Call this method to cancel a request that is in progress. This method + // causes the request to immediately transition into the 'done' state. The + // OnCompletedRequest method will be called asynchronously; this assumes + // the peer is still valid. + virtual void Cancel() = 0; + + // Call this method to suspend or resume a load that is in progress. This + // method may only be called after a successful call to the Start method. + virtual void SetDefersLoading(bool value) = 0; + + // Call this method when the priority of the requested resource changes after + // Start() has been called. This method may only be called after a successful + // call to the Start method. + virtual void DidChangePriority(net::RequestPriority new_priority) = 0; + + // Call this method to load the resource synchronously (i.e., in one shot). + // This is an alternative to the Start method. Be warned that this method + // will block the calling thread until the resource is fully downloaded or an + // error occurs. It could block the calling thread for a long time, so only + // use this if you really need it! There is also no way for the caller to + // interrupt this method. Errors are reported via the status field of the + // response parameter. + virtual void SyncLoad(SyncLoadResponse* response) = 0; + + protected: + // Construction must go through + // WebKitPlatformSupportImpl::CreateResourceLoader() + // For HTTP(S) POST requests, the AppendDataToUpload and AppendFileToUpload + // methods may be called to construct the body of the request. + WEBKIT_CHILD_EXPORT ResourceLoaderBridge(); + + private: + DISALLOW_COPY_AND_ASSIGN(ResourceLoaderBridge); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_RESOURCE_LOADER_BRIDGE_H_ diff --git a/webkit/child/webkit_child_helpers.cc b/webkit/child/webkit_child_helpers.cc new file mode 100644 index 0000000..6777955 --- /dev/null +++ b/webkit/child/webkit_child_helpers.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2013 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/child/webkit_child_helpers.h" + +#if defined(OS_LINUX) +#include +#endif + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/process_util.h" +#include "v8/include/v8.h" + +namespace webkit_glue { + +#if defined(OS_LINUX) || defined(OS_ANDROID) +size_t MemoryUsageKB() { + struct mallinfo minfo = mallinfo(); + uint64_t mem_usage = +#if defined(USE_TCMALLOC) + minfo.uordblks +#else + (minfo.hblkhd + minfo.arena) +#endif + >> 10; + + v8::HeapStatistics stat; + // TODO(svenpanne) The call below doesn't take web workers into account, this + // has to be done manually by iterating over all Isolates involved. + v8::Isolate::GetCurrent()->GetHeapStatistics(&stat); + return mem_usage + (static_cast(stat.total_heap_size()) >> 10); +} +#elif defined(OS_MACOSX) +size_t MemoryUsageKB() { + scoped_ptr process_metrics( + // The default port provider is sufficient to get data for the current + // process. + base::ProcessMetrics::CreateProcessMetrics( + base::GetCurrentProcessHandle(), NULL)); + return process_metrics->GetWorkingSetSize() >> 10; +} +#else +size_t MemoryUsageKB() { + scoped_ptr process_metrics( + base::ProcessMetrics::CreateProcessMetrics( + base::GetCurrentProcessHandle())); + return process_metrics->GetPagefileUsage() >> 10; +} +#endif + +} // webkit_glue diff --git a/webkit/child/webkit_child_helpers.h b/webkit/child/webkit_child_helpers.h new file mode 100644 index 0000000..3262fa2 --- /dev/null +++ b/webkit/child/webkit_child_helpers.h @@ -0,0 +1,21 @@ +// Copyright (c) 2013 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. + +#ifndef WEBKIT_CHILD_WEBKIT_CHILD_HELPERS_H_ +#define WEBKIT_CHILD_WEBKIT_CHILD_HELPERS_H_ + +#include "base/basictypes.h" +#include "webkit/child/webkit_child_export.h" + +namespace webkit_glue { + +// Returns an estimate of the memory usage of the renderer process. Different +// platforms implement this function differently, and count in different +// allocations. Results are not comparable across platforms. The estimate is +// computed inside the sandbox and thus its not always accurate. +WEBKIT_CHILD_EXPORT size_t MemoryUsageKB(); + +} // webkit_glue + +#endif // WEBKIT_CHILD_WEBKIT_CHILD_HELPERS_H_ diff --git a/webkit/child/webkitplatformsupport_child_impl.h b/webkit/child/webkitplatformsupport_child_impl.h index abb6338..5ba71d8 100644 --- a/webkit/child/webkitplatformsupport_child_impl.h +++ b/webkit/child/webkitplatformsupport_child_impl.h @@ -8,7 +8,7 @@ #include "base/threading/thread_local_storage.h" #include "webkit/child/webfallbackthemeengine_impl.h" #include "webkit/child/webkit_child_export.h" -#include "webkit/glue/webkitplatformsupport_impl.h" +#include "webkit/child/webkitplatformsupport_impl.h" #if defined(USE_DEFAULT_RENDER_THEME) #include "webkit/child/webthemeengine_impl_default.h" diff --git a/webkit/child/webkitplatformsupport_impl.cc b/webkit/child/webkitplatformsupport_impl.cc new file mode 100644 index 0000000..31a355e0 --- /dev/null +++ b/webkit/child/webkitplatformsupport_impl.cc @@ -0,0 +1,904 @@ +// 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/child/webkitplatformsupport_impl.h" + +#include + +#include + +#include "base/allocator/allocator_extension.h" +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/singleton.h" +#include "base/message_loop/message_loop.h" +#include "base/metrics/histogram.h" +#include "base/metrics/sparse_histogram.h" +#include "base/metrics/stats_counters.h" +#include "base/platform_file.h" +#include "base/process_util.h" +#include "base/rand_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/synchronization/lock.h" +#include "base/sys_info.h" +#include "base/time/time.h" +#include "content/public/common/webplugininfo.h" +#include "grit/webkit_chromium_resources.h" +#include "grit/webkit_resources.h" +#include "grit/webkit_strings.h" +#include "net/base/data_url.h" +#include "net/base/mime_util.h" +#include "net/base/net_errors.h" +#include "third_party/WebKit/public/platform/WebCookie.h" +#include "third_party/WebKit/public/platform/WebData.h" +#include "third_party/WebKit/public/platform/WebDiscardableMemory.h" +#include "third_party/WebKit/public/platform/WebGestureCurve.h" +#include "third_party/WebKit/public/platform/WebPluginListBuilder.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/web/WebFrameClient.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" +#include "third_party/WebKit/public/web/WebScreenInfo.h" +#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" +#include "ui/base/layout.h" +#include "webkit/child/webkit_child_helpers.h" +#include "webkit/child/websocketstreamhandle_impl.h" +#include "webkit/child/weburlloader_impl.h" +#include "webkit/common/user_agent/user_agent.h" +#include "webkit/glue/webkit_glue.h" + +using WebKit::WebAudioBus; +using WebKit::WebCookie; +using WebKit::WebData; +using WebKit::WebLocalizedString; +using WebKit::WebPluginListBuilder; +using WebKit::WebString; +using WebKit::WebSocketStreamHandle; +using WebKit::WebURL; +using WebKit::WebURLError; +using WebKit::WebURLLoader; +using WebKit::WebVector; + +namespace { + +// A simple class to cache the memory usage for a given amount of time. +class MemoryUsageCache { + public: + // Retrieves the Singleton. + static MemoryUsageCache* GetInstance() { + return Singleton::get(); + } + + MemoryUsageCache() : memory_value_(0) { Init(); } + ~MemoryUsageCache() {} + + void Init() { + const unsigned int kCacheSeconds = 1; + cache_valid_time_ = base::TimeDelta::FromSeconds(kCacheSeconds); + } + + // Returns true if the cached value is fresh. + // Returns false if the cached value is stale, or if |cached_value| is NULL. + bool IsCachedValueValid(size_t* cached_value) { + base::AutoLock scoped_lock(lock_); + if (!cached_value) + return false; + if (base::Time::Now() - last_updated_time_ > cache_valid_time_) + return false; + *cached_value = memory_value_; + return true; + }; + + // Setter for |memory_value_|, refreshes |last_updated_time_|. + void SetMemoryValue(const size_t value) { + base::AutoLock scoped_lock(lock_); + memory_value_ = value; + last_updated_time_ = base::Time::Now(); + } + + private: + // The cached memory value. + size_t memory_value_; + + // How long the cached value should remain valid. + base::TimeDelta cache_valid_time_; + + // The last time the cached value was updated. + base::Time last_updated_time_; + + base::Lock lock_; +}; + +} // anonymous namespace + +namespace webkit_glue { + +static int ToMessageID(WebLocalizedString::Name name) { + switch (name) { + case WebLocalizedString::AXAMPMFieldText: + return IDS_AX_AM_PM_FIELD_TEXT; + case WebLocalizedString::AXButtonActionVerb: + return IDS_AX_BUTTON_ACTION_VERB; + case WebLocalizedString::AXCheckedCheckBoxActionVerb: + return IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB; + case WebLocalizedString::AXDateTimeFieldEmptyValueText: + return IDS_AX_DATE_TIME_FIELD_EMPTY_VALUE_TEXT; + case WebLocalizedString::AXDayOfMonthFieldText: + return IDS_AX_DAY_OF_MONTH_FIELD_TEXT; + case WebLocalizedString::AXHeadingText: + return IDS_AX_ROLE_HEADING; + case WebLocalizedString::AXHourFieldText: + return IDS_AX_HOUR_FIELD_TEXT; + case WebLocalizedString::AXImageMapText: + return IDS_AX_ROLE_IMAGE_MAP; + case WebLocalizedString::AXLinkActionVerb: + return IDS_AX_LINK_ACTION_VERB; + case WebLocalizedString::AXLinkText: + return IDS_AX_ROLE_LINK; + case WebLocalizedString::AXListMarkerText: + return IDS_AX_ROLE_LIST_MARKER; + case WebLocalizedString::AXMediaDefault: + return IDS_AX_MEDIA_DEFAULT; + case WebLocalizedString::AXMediaAudioElement: + return IDS_AX_MEDIA_AUDIO_ELEMENT; + case WebLocalizedString::AXMediaVideoElement: + return IDS_AX_MEDIA_VIDEO_ELEMENT; + case WebLocalizedString::AXMediaMuteButton: + return IDS_AX_MEDIA_MUTE_BUTTON; + case WebLocalizedString::AXMediaUnMuteButton: + return IDS_AX_MEDIA_UNMUTE_BUTTON; + case WebLocalizedString::AXMediaPlayButton: + return IDS_AX_MEDIA_PLAY_BUTTON; + case WebLocalizedString::AXMediaPauseButton: + return IDS_AX_MEDIA_PAUSE_BUTTON; + case WebLocalizedString::AXMediaSlider: + return IDS_AX_MEDIA_SLIDER; + case WebLocalizedString::AXMediaSliderThumb: + return IDS_AX_MEDIA_SLIDER_THUMB; + case WebLocalizedString::AXMediaRewindButton: + return IDS_AX_MEDIA_REWIND_BUTTON; + case WebLocalizedString::AXMediaReturnToRealTime: + return IDS_AX_MEDIA_RETURN_TO_REALTIME_BUTTON; + case WebLocalizedString::AXMediaCurrentTimeDisplay: + return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY; + case WebLocalizedString::AXMediaTimeRemainingDisplay: + return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY; + case WebLocalizedString::AXMediaStatusDisplay: + return IDS_AX_MEDIA_STATUS_DISPLAY; + case WebLocalizedString::AXMediaEnterFullscreenButton: + return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON; + case WebLocalizedString::AXMediaExitFullscreenButton: + return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON; + case WebLocalizedString::AXMediaSeekForwardButton: + return IDS_AX_MEDIA_SEEK_FORWARD_BUTTON; + case WebLocalizedString::AXMediaSeekBackButton: + return IDS_AX_MEDIA_SEEK_BACK_BUTTON; + case WebLocalizedString::AXMediaShowClosedCaptionsButton: + return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON; + case WebLocalizedString::AXMediaHideClosedCaptionsButton: + return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON; + case WebLocalizedString::AXMediaAudioElementHelp: + return IDS_AX_MEDIA_AUDIO_ELEMENT_HELP; + case WebLocalizedString::AXMediaVideoElementHelp: + return IDS_AX_MEDIA_VIDEO_ELEMENT_HELP; + case WebLocalizedString::AXMediaMuteButtonHelp: + return IDS_AX_MEDIA_MUTE_BUTTON_HELP; + case WebLocalizedString::AXMediaUnMuteButtonHelp: + return IDS_AX_MEDIA_UNMUTE_BUTTON_HELP; + case WebLocalizedString::AXMediaPlayButtonHelp: + return IDS_AX_MEDIA_PLAY_BUTTON_HELP; + case WebLocalizedString::AXMediaPauseButtonHelp: + return IDS_AX_MEDIA_PAUSE_BUTTON_HELP; + case WebLocalizedString::AXMediaSliderHelp: + return IDS_AX_MEDIA_SLIDER_HELP; + case WebLocalizedString::AXMediaSliderThumbHelp: + return IDS_AX_MEDIA_SLIDER_THUMB_HELP; + case WebLocalizedString::AXMediaRewindButtonHelp: + return IDS_AX_MEDIA_REWIND_BUTTON_HELP; + case WebLocalizedString::AXMediaReturnToRealTimeHelp: + return IDS_AX_MEDIA_RETURN_TO_REALTIME_BUTTON_HELP; + case WebLocalizedString::AXMediaCurrentTimeDisplayHelp: + return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP; + case WebLocalizedString::AXMediaTimeRemainingDisplayHelp: + return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY_HELP; + case WebLocalizedString::AXMediaStatusDisplayHelp: + return IDS_AX_MEDIA_STATUS_DISPLAY_HELP; + case WebLocalizedString::AXMediaEnterFullscreenButtonHelp: + return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP; + case WebLocalizedString::AXMediaExitFullscreenButtonHelp: + return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP; + case WebLocalizedString::AXMediaSeekForwardButtonHelp: + return IDS_AX_MEDIA_SEEK_FORWARD_BUTTON_HELP; + case WebLocalizedString::AXMediaSeekBackButtonHelp: + return IDS_AX_MEDIA_SEEK_BACK_BUTTON_HELP; + case WebLocalizedString::AXMediaShowClosedCaptionsButtonHelp: + return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP; + case WebLocalizedString::AXMediaHideClosedCaptionsButtonHelp: + return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON_HELP; + case WebLocalizedString::AXMillisecondFieldText: + return IDS_AX_MILLISECOND_FIELD_TEXT; + case WebLocalizedString::AXMinuteFieldText: + return IDS_AX_MINUTE_FIELD_TEXT; + case WebLocalizedString::AXMonthFieldText: + return IDS_AX_MONTH_FIELD_TEXT; + case WebLocalizedString::AXRadioButtonActionVerb: + return IDS_AX_RADIO_BUTTON_ACTION_VERB; + case WebLocalizedString::AXSecondFieldText: + return IDS_AX_SECOND_FIELD_TEXT; + case WebLocalizedString::AXTextFieldActionVerb: + return IDS_AX_TEXT_FIELD_ACTION_VERB; + case WebLocalizedString::AXUncheckedCheckBoxActionVerb: + return IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB; + case WebLocalizedString::AXWebAreaText: + return IDS_AX_ROLE_WEB_AREA; + case WebLocalizedString::AXWeekOfYearFieldText: + return IDS_AX_WEEK_OF_YEAR_FIELD_TEXT; + case WebLocalizedString::AXYearFieldText: + return IDS_AX_YEAR_FIELD_TEXT; + case WebLocalizedString::CalendarClear: + return IDS_FORM_CALENDAR_CLEAR; + case WebLocalizedString::CalendarToday: + return IDS_FORM_CALENDAR_TODAY; + case WebLocalizedString::DateFormatDayInMonthLabel: + return IDS_FORM_DATE_FORMAT_DAY_IN_MONTH; + case WebLocalizedString::DateFormatMonthLabel: + return IDS_FORM_DATE_FORMAT_MONTH; + case WebLocalizedString::DateFormatYearLabel: + return IDS_FORM_DATE_FORMAT_YEAR; + case WebLocalizedString::DetailsLabel: + return IDS_DETAILS_WITHOUT_SUMMARY_LABEL; + case WebLocalizedString::FileButtonChooseFileLabel: + return IDS_FORM_FILE_BUTTON_LABEL; + case WebLocalizedString::FileButtonChooseMultipleFilesLabel: + return IDS_FORM_MULTIPLE_FILES_BUTTON_LABEL; + case WebLocalizedString::FileButtonNoFileSelectedLabel: + return IDS_FORM_FILE_NO_FILE_LABEL; + case WebLocalizedString::InputElementAltText: + return IDS_FORM_INPUT_ALT; + case WebLocalizedString::KeygenMenuHighGradeKeySize: + return IDS_KEYGEN_HIGH_GRADE_KEY; + case WebLocalizedString::KeygenMenuMediumGradeKeySize: + return IDS_KEYGEN_MED_GRADE_KEY; + case WebLocalizedString::MissingPluginText: + return IDS_PLUGIN_INITIALIZATION_ERROR; + case WebLocalizedString::MultipleFileUploadText: + return IDS_FORM_FILE_MULTIPLE_UPLOAD; + case WebLocalizedString::OtherColorLabel: + return IDS_FORM_OTHER_COLOR_LABEL; + case WebLocalizedString::OtherDateLabel: + return IDS_FORM_OTHER_DATE_LABEL; + case WebLocalizedString::OtherMonthLabel: + return IDS_FORM_OTHER_MONTH_LABEL; + case WebLocalizedString::OtherTimeLabel: + return IDS_FORM_OTHER_TIME_LABEL; + case WebLocalizedString::OtherWeekLabel: + return IDS_FORM_OTHER_WEEK_LABEL; + case WebLocalizedString::PlaceholderForDayOfMonthField: + return IDS_FORM_PLACEHOLDER_FOR_DAY_OF_MONTH_FIELD; + case WebLocalizedString::PlaceholderForMonthField: + return IDS_FORM_PLACEHOLDER_FOR_MONTH_FIELD; + case WebLocalizedString::PlaceholderForYearField: + return IDS_FORM_PLACEHOLDER_FOR_YEAR_FIELD; + case WebLocalizedString::ResetButtonDefaultLabel: + return IDS_FORM_RESET_LABEL; + case WebLocalizedString::SearchableIndexIntroduction: + return IDS_SEARCHABLE_INDEX_INTRO; + case WebLocalizedString::SearchMenuClearRecentSearchesText: + return IDS_RECENT_SEARCHES_CLEAR; + case WebLocalizedString::SearchMenuNoRecentSearchesText: + return IDS_RECENT_SEARCHES_NONE; + case WebLocalizedString::SearchMenuRecentSearchesText: + return IDS_RECENT_SEARCHES; + case WebLocalizedString::SubmitButtonDefaultLabel: + return IDS_FORM_SUBMIT_LABEL; + case WebLocalizedString::ThisMonthButtonLabel: + return IDS_FORM_THIS_MONTH_LABEL; + case WebLocalizedString::ThisWeekButtonLabel: + return IDS_FORM_THIS_WEEK_LABEL; + case WebLocalizedString::ValidationBadInputForDateTime: + return IDS_FORM_VALIDATION_BAD_INPUT_DATETIME; + case WebLocalizedString::ValidationBadInputForNumber: + return IDS_FORM_VALIDATION_BAD_INPUT_NUMBER; + case WebLocalizedString::ValidationPatternMismatch: + return IDS_FORM_VALIDATION_PATTERN_MISMATCH; + case WebLocalizedString::ValidationRangeOverflow: + return IDS_FORM_VALIDATION_RANGE_OVERFLOW; + case WebLocalizedString::ValidationRangeUnderflow: + return IDS_FORM_VALIDATION_RANGE_UNDERFLOW; + case WebLocalizedString::ValidationStepMismatch: + return IDS_FORM_VALIDATION_STEP_MISMATCH; + case WebLocalizedString::ValidationTooLong: + return IDS_FORM_VALIDATION_TOO_LONG; + case WebLocalizedString::ValidationTypeMismatch: + return IDS_FORM_VALIDATION_TYPE_MISMATCH; + case WebLocalizedString::ValidationTypeMismatchForEmail: + return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL; + case WebLocalizedString::ValidationTypeMismatchForMultipleEmail: + return IDS_FORM_VALIDATION_TYPE_MISMATCH_MULTIPLE_EMAIL; + case WebLocalizedString::ValidationTypeMismatchForURL: + return IDS_FORM_VALIDATION_TYPE_MISMATCH_URL; + case WebLocalizedString::ValidationValueMissing: + return IDS_FORM_VALIDATION_VALUE_MISSING; + case WebLocalizedString::ValidationValueMissingForCheckbox: + return IDS_FORM_VALIDATION_VALUE_MISSING_CHECKBOX; + case WebLocalizedString::ValidationValueMissingForFile: + return IDS_FORM_VALIDATION_VALUE_MISSING_FILE; + case WebLocalizedString::ValidationValueMissingForMultipleFile: + return IDS_FORM_VALIDATION_VALUE_MISSING_MULTIPLE_FILE; + case WebLocalizedString::ValidationValueMissingForRadio: + return IDS_FORM_VALIDATION_VALUE_MISSING_RADIO; + case WebLocalizedString::ValidationValueMissingForSelect: + return IDS_FORM_VALIDATION_VALUE_MISSING_SELECT; + case WebLocalizedString::WeekFormatTemplate: + return IDS_FORM_INPUT_WEEK_TEMPLATE; + case WebLocalizedString::WeekNumberLabel: + return IDS_FORM_WEEK_NUMBER_LABEL; + // This "default:" line exists to avoid compile warnings about enum + // coverage when we add a new symbol to WebLocalizedString.h in WebKit. + // After a planned WebKit patch is landed, we need to add a case statement + // for the added symbol here. + default: + break; + } + return -1; +} + +WebKitPlatformSupportImpl::WebKitPlatformSupportImpl() + : main_loop_(base::MessageLoop::current()), + shared_timer_func_(NULL), + shared_timer_fire_time_(0.0), + shared_timer_fire_time_was_set_while_suspended_(false), + shared_timer_suspended_(0) {} + +WebKitPlatformSupportImpl::~WebKitPlatformSupportImpl() { +} + +WebURLLoader* WebKitPlatformSupportImpl::createURLLoader() { + return new WebURLLoaderImpl(this); +} + +WebSocketStreamHandle* WebKitPlatformSupportImpl::createSocketStreamHandle() { + return new WebSocketStreamHandleImpl(this); +} + +WebString WebKitPlatformSupportImpl::userAgent(const WebURL& url) { + return WebString::fromUTF8(webkit_glue::GetUserAgent(url)); +} + +WebData WebKitPlatformSupportImpl::parseDataURL( + const WebURL& url, + WebString& mimetype_out, + WebString& charset_out) { + std::string mime_type, char_set, data; + if (net::DataURL::Parse(url, &mime_type, &char_set, &data) + && net::IsSupportedMimeType(mime_type)) { + mimetype_out = WebString::fromUTF8(mime_type); + charset_out = WebString::fromUTF8(char_set); + return data; + } + return WebData(); +} + +WebURLError WebKitPlatformSupportImpl::cancelledError( + const WebURL& unreachableURL) const { + return WebURLLoaderImpl::CreateError(unreachableURL, net::ERR_ABORTED); +} + +void WebKitPlatformSupportImpl::decrementStatsCounter(const char* name) { + base::StatsCounter(name).Decrement(); +} + +void WebKitPlatformSupportImpl::incrementStatsCounter(const char* name) { + base::StatsCounter(name).Increment(); +} + +void WebKitPlatformSupportImpl::histogramCustomCounts( + const char* name, int sample, int min, int max, int bucket_count) { + // Copied from histogram macro, but without the static variable caching + // the histogram because name is dynamic. + base::HistogramBase* counter = + base::Histogram::FactoryGet(name, min, max, bucket_count, + base::HistogramBase::kUmaTargetedHistogramFlag); + DCHECK_EQ(name, counter->histogram_name()); + counter->Add(sample); +} + +void WebKitPlatformSupportImpl::histogramEnumeration( + const char* name, int sample, int boundary_value) { + // Copied from histogram macro, but without the static variable caching + // the histogram because name is dynamic. + base::HistogramBase* counter = + base::LinearHistogram::FactoryGet(name, 1, boundary_value, + boundary_value + 1, base::HistogramBase::kUmaTargetedHistogramFlag); + DCHECK_EQ(name, counter->histogram_name()); + counter->Add(sample); +} + +void WebKitPlatformSupportImpl::histogramSparse(const char* name, int sample) { + // For sparse histograms, we can use the macro, as it does not incorporate a + // static. + UMA_HISTOGRAM_SPARSE_SLOWLY(name, sample); +} + +const unsigned char* WebKitPlatformSupportImpl::getTraceCategoryEnabledFlag( + const char* category_group) { + return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); +} + +long* WebKitPlatformSupportImpl::getTraceSamplingState( + const unsigned thread_bucket) { + switch (thread_bucket) { + case 0: + return reinterpret_cast(&TRACE_EVENT_API_THREAD_BUCKET(0)); + case 1: + return reinterpret_cast(&TRACE_EVENT_API_THREAD_BUCKET(1)); + case 2: + return reinterpret_cast(&TRACE_EVENT_API_THREAD_BUCKET(2)); + default: + NOTREACHED() << "Unknown thread bucket type."; + } + return NULL; +} + +void WebKitPlatformSupportImpl::addTraceEvent( + char phase, + const unsigned char* category_group_enabled, + const char* name, + unsigned long long id, + int num_args, + const char** arg_names, + const unsigned char* arg_types, + const unsigned long long* arg_values, + unsigned char flags) { + TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name, id, + num_args, arg_names, arg_types, + arg_values, NULL, flags); +} + + +namespace { + +WebData loadAudioSpatializationResource(WebKitPlatformSupportImpl* platform, + const char* name) { +#ifdef IDR_AUDIO_SPATIALIZATION_COMPOSITE + if (!strcmp(name, "Composite")) { + base::StringPiece resource = + platform->GetDataResource(IDR_AUDIO_SPATIALIZATION_COMPOSITE, + ui::SCALE_FACTOR_NONE); + return WebData(resource.data(), resource.size()); + } +#endif + +#ifdef IDR_AUDIO_SPATIALIZATION_T000_P000 + const size_t kExpectedSpatializationNameLength = 31; + if (strlen(name) != kExpectedSpatializationNameLength) { + return WebData(); + } + + // Extract the azimuth and elevation from the resource name. + int azimuth = 0; + int elevation = 0; + int values_parsed = + sscanf(name, "IRC_Composite_C_R0195_T%3d_P%3d", &azimuth, &elevation); + if (values_parsed != 2) { + return WebData(); + } + + // The resource index values go through the elevations first, then azimuths. + const int kAngleSpacing = 15; + + // 0 <= elevation <= 90 (or 315 <= elevation <= 345) + // in increments of 15 degrees. + int elevation_index = + elevation <= 90 ? elevation / kAngleSpacing : + 7 + (elevation - 315) / kAngleSpacing; + bool is_elevation_index_good = 0 <= elevation_index && elevation_index < 10; + + // 0 <= azimuth < 360 in increments of 15 degrees. + int azimuth_index = azimuth / kAngleSpacing; + bool is_azimuth_index_good = 0 <= azimuth_index && azimuth_index < 24; + + const int kNumberOfElevations = 10; + const int kNumberOfAudioResources = 240; + int resource_index = kNumberOfElevations * azimuth_index + elevation_index; + bool is_resource_index_good = 0 <= resource_index && + resource_index < kNumberOfAudioResources; + + if (is_azimuth_index_good && is_elevation_index_good && + is_resource_index_good) { + const int kFirstAudioResourceIndex = IDR_AUDIO_SPATIALIZATION_T000_P000; + base::StringPiece resource = + platform->GetDataResource(kFirstAudioResourceIndex + resource_index, + ui::SCALE_FACTOR_NONE); + return WebData(resource.data(), resource.size()); + } +#endif // IDR_AUDIO_SPATIALIZATION_T000_P000 + + NOTREACHED(); + return WebData(); +} + +struct DataResource { + const char* name; + int id; + ui::ScaleFactor scale_factor; +}; + +const DataResource kDataResources[] = { + { "missingImage", IDR_BROKENIMAGE, ui::SCALE_FACTOR_100P }, + { "missingImage@2x", IDR_BROKENIMAGE, ui::SCALE_FACTOR_200P }, + { "mediaplayerPause", IDR_MEDIAPLAYER_PAUSE_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerPauseHover", + IDR_MEDIAPLAYER_PAUSE_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerPauseDown", + IDR_MEDIAPLAYER_PAUSE_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerPlay", IDR_MEDIAPLAYER_PLAY_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerPlayHover", + IDR_MEDIAPLAYER_PLAY_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerPlayDown", + IDR_MEDIAPLAYER_PLAY_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerPlayDisabled", + IDR_MEDIAPLAYER_PLAY_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel3", + IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel3Hover", + IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel3Down", + IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel2", + IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel2Hover", + IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel2Down", + IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel1", + IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel1Hover", + IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel1Down", + IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel0", + IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel0Hover", + IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundLevel0Down", + IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerSoundDisabled", + IDR_MEDIAPLAYER_SOUND_DISABLED, ui::SCALE_FACTOR_100P }, + { "mediaplayerSliderThumb", + IDR_MEDIAPLAYER_SLIDER_THUMB, ui::SCALE_FACTOR_100P }, + { "mediaplayerSliderThumbHover", + IDR_MEDIAPLAYER_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerSliderThumbDown", + IDR_MEDIAPLAYER_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerVolumeSliderThumb", + IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB, ui::SCALE_FACTOR_100P }, + { "mediaplayerVolumeSliderThumbHover", + IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerVolumeSliderThumbDown", + IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerVolumeSliderThumbDisabled", + IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DISABLED, ui::SCALE_FACTOR_100P }, + { "mediaplayerClosedCaption", + IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerClosedCaptionHover", + IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerClosedCaptionDown", + IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerClosedCaptionDisabled", + IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, + { "mediaplayerFullscreen", + IDR_MEDIAPLAYER_FULLSCREEN_BUTTON, ui::SCALE_FACTOR_100P }, + { "mediaplayerFullscreenHover", + IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, + { "mediaplayerFullscreenDown", + IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, + { "mediaplayerFullscreenDisabled", + IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, +#if defined(OS_ANDROID) + { "mediaplayerOverlayPlay", + IDR_MEDIAPLAYER_OVERLAY_PLAY_BUTTON, ui::SCALE_FACTOR_100P }, +#endif +#if defined(OS_MACOSX) + { "overhangPattern", IDR_OVERHANG_PATTERN, ui::SCALE_FACTOR_100P }, +#endif + { "panIcon", IDR_PAN_SCROLL_ICON, ui::SCALE_FACTOR_100P }, + { "searchCancel", IDR_SEARCH_CANCEL, ui::SCALE_FACTOR_100P }, + { "searchCancelPressed", IDR_SEARCH_CANCEL_PRESSED, ui::SCALE_FACTOR_100P }, + { "searchMagnifier", IDR_SEARCH_MAGNIFIER, ui::SCALE_FACTOR_100P }, + { "searchMagnifierResults", + IDR_SEARCH_MAGNIFIER_RESULTS, ui::SCALE_FACTOR_100P }, + { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_100P }, + { "textAreaResizeCorner@2x", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_200P }, + { "inputSpeech", IDR_INPUT_SPEECH, ui::SCALE_FACTOR_100P }, + { "inputSpeechRecording", IDR_INPUT_SPEECH_RECORDING, ui::SCALE_FACTOR_100P }, + { "inputSpeechWaiting", IDR_INPUT_SPEECH_WAITING, ui::SCALE_FACTOR_100P }, + { "americanExpressCC", IDR_AUTOFILL_CC_AMEX, ui::SCALE_FACTOR_100P }, + { "dinersCC", IDR_AUTOFILL_CC_DINERS, ui::SCALE_FACTOR_100P }, + { "discoverCC", IDR_AUTOFILL_CC_DISCOVER, ui::SCALE_FACTOR_100P }, + { "genericCC", IDR_AUTOFILL_CC_GENERIC, ui::SCALE_FACTOR_100P }, + { "jcbCC", IDR_AUTOFILL_CC_JCB, ui::SCALE_FACTOR_100P }, + { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD, ui::SCALE_FACTOR_100P }, + { "visaCC", IDR_AUTOFILL_CC_VISA, ui::SCALE_FACTOR_100P }, + { "generatePassword", IDR_PASSWORD_GENERATION_ICON, ui::SCALE_FACTOR_100P }, + { "generatePasswordHover", + IDR_PASSWORD_GENERATION_ICON_HOVER, ui::SCALE_FACTOR_100P }, + { "syntheticTouchCursor", + IDR_SYNTHETIC_TOUCH_CURSOR, ui::SCALE_FACTOR_100P }, +}; + +} // namespace + +WebData WebKitPlatformSupportImpl::loadResource(const char* name) { + // Some clients will call into this method with an empty |name| when they have + // optional resources. For example, the PopupMenuChromium code can have icons + // for some Autofill items but not for others. + if (!strlen(name)) + return WebData(); + + // Check the name prefix to see if it's an audio resource. + if (StartsWithASCII(name, "IRC_Composite", true) || + StartsWithASCII(name, "Composite", true)) + return loadAudioSpatializationResource(this, name); + + // TODO(flackr): We should use a better than linear search here, a trie would + // be ideal. + for (size_t i = 0; i < arraysize(kDataResources); ++i) { + if (!strcmp(name, kDataResources[i].name)) { + base::StringPiece resource = + GetDataResource(kDataResources[i].id, + kDataResources[i].scale_factor); + return WebData(resource.data(), resource.size()); + } + } + + NOTREACHED() << "Unknown image resource " << name; + return WebData(); +} + +WebString WebKitPlatformSupportImpl::queryLocalizedString( + WebLocalizedString::Name name) { + int message_id = ToMessageID(name); + if (message_id < 0) + return WebString(); + return GetLocalizedString(message_id); +} + +WebString WebKitPlatformSupportImpl::queryLocalizedString( + WebLocalizedString::Name name, int numeric_value) { + return queryLocalizedString(name, base::IntToString16(numeric_value)); +} + +WebString WebKitPlatformSupportImpl::queryLocalizedString( + WebLocalizedString::Name name, const WebString& value) { + int message_id = ToMessageID(name); + if (message_id < 0) + return WebString(); + return ReplaceStringPlaceholders(GetLocalizedString(message_id), value, NULL); +} + +WebString WebKitPlatformSupportImpl::queryLocalizedString( + WebLocalizedString::Name name, + const WebString& value1, + const WebString& value2) { + int message_id = ToMessageID(name); + if (message_id < 0) + return WebString(); + std::vector values; + values.reserve(2); + values.push_back(value1); + values.push_back(value2); + return ReplaceStringPlaceholders( + GetLocalizedString(message_id), values, NULL); +} + +double WebKitPlatformSupportImpl::currentTime() { + return base::Time::Now().ToDoubleT(); +} + +double WebKitPlatformSupportImpl::monotonicallyIncreasingTime() { + return base::TimeTicks::Now().ToInternalValue() / + static_cast(base::Time::kMicrosecondsPerSecond); +} + +void WebKitPlatformSupportImpl::cryptographicallyRandomValues( + unsigned char* buffer, size_t length) { + base::RandBytes(buffer, length); +} + +void WebKitPlatformSupportImpl::setSharedTimerFiredFunction(void (*func)()) { + shared_timer_func_ = func; +} + +void WebKitPlatformSupportImpl::setSharedTimerFireInterval( + double interval_seconds) { + shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime(); + if (shared_timer_suspended_) { + shared_timer_fire_time_was_set_while_suspended_ = true; + return; + } + + // By converting between double and int64 representation, we run the risk + // of losing precision due to rounding errors. Performing computations in + // microseconds reduces this risk somewhat. But there still is the potential + // of us computing a fire time for the timer that is shorter than what we + // need. + // As the event loop will check event deadlines prior to actually firing + // them, there is a risk of needlessly rescheduling events and of + // needlessly looping if sleep times are too short even by small amounts. + // This results in measurable performance degradation unless we use ceil() to + // always round up the sleep times. + int64 interval = static_cast( + ceil(interval_seconds * base::Time::kMillisecondsPerSecond) + * base::Time::kMicrosecondsPerMillisecond); + + if (interval < 0) + interval = 0; + + shared_timer_.Stop(); + shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval), + this, &WebKitPlatformSupportImpl::DoTimeout); + OnStartSharedTimer(base::TimeDelta::FromMicroseconds(interval)); +} + +void WebKitPlatformSupportImpl::stopSharedTimer() { + shared_timer_.Stop(); +} + +void WebKitPlatformSupportImpl::callOnMainThread( + void (*func)(void*), void* context) { + main_loop_->PostTask(FROM_HERE, base::Bind(func, context)); +} + +base::PlatformFile WebKitPlatformSupportImpl::databaseOpenFile( + const WebKit::WebString& vfs_file_name, int desired_flags) { + return base::kInvalidPlatformFileValue; +} + +int WebKitPlatformSupportImpl::databaseDeleteFile( + const WebKit::WebString& vfs_file_name, bool sync_dir) { + return -1; +} + +long WebKitPlatformSupportImpl::databaseGetFileAttributes( + const WebKit::WebString& vfs_file_name) { + return 0; +} + +long long WebKitPlatformSupportImpl::databaseGetFileSize( + const WebKit::WebString& vfs_file_name) { + return 0; +} + +long long WebKitPlatformSupportImpl::databaseGetSpaceAvailableForOrigin( + const WebKit::WebString& origin_identifier) { + return 0; +} + +WebKit::WebString WebKitPlatformSupportImpl::signedPublicKeyAndChallengeString( + unsigned key_size_index, + const WebKit::WebString& challenge, + const WebKit::WebURL& url) { + return WebKit::WebString(""); +} + +static scoped_ptr CurrentProcessMetrics() { + using base::ProcessMetrics; +#if defined(OS_MACOSX) + return scoped_ptr( + // The default port provider is sufficient to get data for the current + // process. + ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle(), + NULL)); +#else + return scoped_ptr( + ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle())); +#endif +} + +static size_t getMemoryUsageMB(bool bypass_cache) { + size_t current_mem_usage = 0; + MemoryUsageCache* mem_usage_cache_singleton = MemoryUsageCache::GetInstance(); + if (!bypass_cache && + mem_usage_cache_singleton->IsCachedValueValid(¤t_mem_usage)) + return current_mem_usage; + + current_mem_usage = MemoryUsageKB() >> 10; + mem_usage_cache_singleton->SetMemoryValue(current_mem_usage); + return current_mem_usage; +} + +size_t WebKitPlatformSupportImpl::memoryUsageMB() { + return getMemoryUsageMB(false); +} + +size_t WebKitPlatformSupportImpl::actualMemoryUsageMB() { + return getMemoryUsageMB(true); +} + +#if defined(OS_ANDROID) +size_t WebKitPlatformSupportImpl::lowMemoryUsageMB() { + // If memory usage is below this threshold, do not bother forcing GC. + // Allow us to use up to our memory class value before V8's GC kicks in. + // These values have been determined by experimentation. + return base::SysInfo::DalvikHeapSizeMB() / 2; +} + +size_t WebKitPlatformSupportImpl::highMemoryUsageMB() { + // If memory usage is above this threshold, force GC more aggressively. + return base::SysInfo::DalvikHeapSizeMB() * 3 / 4; +} + +size_t WebKitPlatformSupportImpl::highUsageDeltaMB() { + // If memory usage is above highMemoryUsageMB() and memory usage increased by + // more than highUsageDeltaMB() since the last GC, then force GC. + // Note that this limit should be greater than the amount of memory for V8 + // internal data structures that are released on GC and reallocated during JS + // execution (about 8MB). Otherwise, it will cause too aggressive GCs. + return base::SysInfo::DalvikHeapSizeMB() / 8; +} +#endif + +void WebKitPlatformSupportImpl::startHeapProfiling( + const WebKit::WebString& prefix) { + // FIXME(morrita): Make this built on windows. +#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) + HeapProfilerStart(prefix.utf8().data()); +#endif +} + +void WebKitPlatformSupportImpl::stopHeapProfiling() { +#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) + HeapProfilerStop(); +#endif +} + +void WebKitPlatformSupportImpl::dumpHeapProfiling( + const WebKit::WebString& reason) { +#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) + HeapProfilerDump(reason.utf8().data()); +#endif +} + +WebString WebKitPlatformSupportImpl::getHeapProfile() { +#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) + char* data = GetHeapProfile(); + WebString result = WebString::fromUTF8(std::string(data)); + free(data); + return result; +#else + return WebString(); +#endif +} + +bool WebKitPlatformSupportImpl::processMemorySizesInBytes( + size_t* private_bytes, + size_t* shared_bytes) { + return CurrentProcessMetrics()->GetMemoryBytes(private_bytes, shared_bytes); +} + +bool WebKitPlatformSupportImpl::memoryAllocatorWasteInBytes(size_t* size) { + return base::allocator::GetAllocatorWasteSize(size); +} + +void WebKitPlatformSupportImpl::SuspendSharedTimer() { + ++shared_timer_suspended_; +} + +void WebKitPlatformSupportImpl::ResumeSharedTimer() { + // The shared timer may have fired or been adjusted while we were suspended. + if (--shared_timer_suspended_ == 0 && + (!shared_timer_.IsRunning() || + shared_timer_fire_time_was_set_while_suspended_)) { + shared_timer_fire_time_was_set_while_suspended_ = false; + setSharedTimerFireInterval( + shared_timer_fire_time_ - monotonicallyIncreasingTime()); + } +} + +} // namespace webkit_glue diff --git a/webkit/child/webkitplatformsupport_impl.h b/webkit/child/webkitplatformsupport_impl.h new file mode 100644 index 0000000..e9077582 --- /dev/null +++ b/webkit/child/webkitplatformsupport_impl.h @@ -0,0 +1,155 @@ +// 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. + +#ifndef WEBKIT_CHILD_WEBKITPLATFORMSUPPORT_IMPL_H_ +#define WEBKIT_CHILD_WEBKITPLATFORMSUPPORT_IMPL_H_ + +#include "base/compiler_specific.h" +#include "base/debug/trace_event.h" +#include "base/platform_file.h" +#include "base/timer/timer.h" +#include "third_party/WebKit/public/platform/Platform.h" +#include "third_party/WebKit/public/platform/WebURLError.h" +#include "ui/base/layout.h" +#include "webkit/child/resource_loader_bridge.h" +#include "webkit/child/webkit_child_export.h" + +namespace base { +class MessageLoop; +} + +namespace WebKit { +class WebSocketStreamHandle; +} + +namespace webkit_glue { + +class WebSocketStreamHandleDelegate; +class WebSocketStreamHandleBridge; + +class WEBKIT_CHILD_EXPORT WebKitPlatformSupportImpl : + NON_EXPORTED_BASE(public WebKit::Platform) { + public: + WebKitPlatformSupportImpl(); + virtual ~WebKitPlatformSupportImpl(); + + // Platform methods (partial implementation): + virtual base::PlatformFile databaseOpenFile( + const WebKit::WebString& vfs_file_name, int desired_flags); + virtual int databaseDeleteFile(const WebKit::WebString& vfs_file_name, + bool sync_dir); + virtual long databaseGetFileAttributes( + const WebKit::WebString& vfs_file_name); + virtual long long databaseGetFileSize(const WebKit::WebString& vfs_file_name); + virtual long long databaseGetSpaceAvailableForOrigin( + const WebKit::WebString& origin_identifier); + virtual WebKit::WebString signedPublicKeyAndChallengeString( + unsigned key_size_index, const WebKit::WebString& challenge, + const WebKit::WebURL& url); + virtual size_t memoryUsageMB(); + virtual size_t actualMemoryUsageMB(); +#if defined(OS_ANDROID) // Other OSes just use the default values. + // TODO(jochen): Remove these. + virtual size_t lowMemoryUsageMB(); + virtual size_t highMemoryUsageMB(); + virtual size_t highUsageDeltaMB(); +#endif + + virtual void startHeapProfiling(const WebKit::WebString& prefix); + virtual void stopHeapProfiling() OVERRIDE; + virtual void dumpHeapProfiling(const WebKit::WebString& reason); + virtual WebKit::WebString getHeapProfile() OVERRIDE; + + virtual bool processMemorySizesInBytes(size_t* private_bytes, + size_t* shared_bytes); + virtual bool memoryAllocatorWasteInBytes(size_t* size); + virtual WebKit::WebURLLoader* createURLLoader(); + virtual WebKit::WebSocketStreamHandle* createSocketStreamHandle(); + virtual WebKit::WebString userAgent(const WebKit::WebURL& url); + virtual WebKit::WebData parseDataURL( + const WebKit::WebURL& url, WebKit::WebString& mimetype, + WebKit::WebString& charset); + virtual WebKit::WebURLError cancelledError(const WebKit::WebURL& url) const; + virtual void decrementStatsCounter(const char* name); + virtual void incrementStatsCounter(const char* name); + virtual void histogramCustomCounts( + const char* name, int sample, int min, int max, int bucket_count); + virtual void histogramEnumeration( + const char* name, int sample, int boundary_value); + virtual void histogramSparse(const char* name, int sample); + virtual const unsigned char* getTraceCategoryEnabledFlag( + const char* category_name); + virtual long* getTraceSamplingState(const unsigned thread_bucket); + virtual void addTraceEvent( + char phase, + const unsigned char* category_group_enabled, + const char* name, + unsigned long long id, + int num_args, + const char** arg_names, + const unsigned char* arg_types, + const unsigned long long* arg_values, + unsigned char flags); + virtual WebKit::WebData loadResource(const char* name); + virtual WebKit::WebString queryLocalizedString( + WebKit::WebLocalizedString::Name name); + virtual WebKit::WebString queryLocalizedString( + WebKit::WebLocalizedString::Name name, int numeric_value); + virtual WebKit::WebString queryLocalizedString( + WebKit::WebLocalizedString::Name name, const WebKit::WebString& value); + virtual WebKit::WebString queryLocalizedString( + WebKit::WebLocalizedString::Name name, + const WebKit::WebString& value1, const WebKit::WebString& value2); + virtual void suddenTerminationChanged(bool enabled) { } + virtual double currentTime(); + virtual double monotonicallyIncreasingTime(); + virtual void cryptographicallyRandomValues( + unsigned char* buffer, size_t length); + virtual void setSharedTimerFiredFunction(void (*func)()); + virtual void setSharedTimerFireInterval(double interval_seconds); + virtual void stopSharedTimer(); + virtual void callOnMainThread(void (*func)(void*), void* context); + + + // Embedder functions. The following are not implemented by the glue layer and + // need to be specialized by the embedder. + + // Gets a localized string given a message id. Returns an empty string if the + // message id is not found. + virtual base::string16 GetLocalizedString(int message_id) = 0; + + // Returns the raw data for a resource. This resource must have been + // specified as BINDATA in the relevant .rc file. + virtual base::StringPiece GetDataResource(int resource_id, + ui::ScaleFactor scale_factor) = 0; + + // Creates a ResourceLoaderBridge. + virtual ResourceLoaderBridge* CreateResourceLoader( + const ResourceLoaderBridge::RequestInfo& request_info) = 0; + // Creates a WebSocketStreamHandleBridge. + virtual WebSocketStreamHandleBridge* CreateWebSocketBridge( + WebKit::WebSocketStreamHandle* handle, + WebSocketStreamHandleDelegate* delegate) = 0; + + void SuspendSharedTimer(); + void ResumeSharedTimer(); + virtual void OnStartSharedTimer(base::TimeDelta delay) {} + + private: + void DoTimeout() { + if (shared_timer_func_ && !shared_timer_suspended_) + shared_timer_func_(); + } + + base::MessageLoop* main_loop_; + base::OneShotTimer shared_timer_; + void (*shared_timer_func_)(); + double shared_timer_fire_time_; + bool shared_timer_fire_time_was_set_while_suspended_; + int shared_timer_suspended_; // counter +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_WEBKITPLATFORMSUPPORT_IMPL_H_ diff --git a/webkit/child/websocketstreamhandle_delegate.h b/webkit/child/websocketstreamhandle_delegate.h new file mode 100644 index 0000000..ba0822e --- /dev/null +++ b/webkit/child/websocketstreamhandle_delegate.h @@ -0,0 +1,44 @@ +// 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. + +#ifndef WEBKIT_CHILD_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ +#define WEBKIT_CHILD_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ + +#include "base/strings/string16.h" + +class GURL; + +namespace WebKit { +class WebSocketStreamHandle; +} + +namespace webkit_glue { + +class WebSocketStreamHandleDelegate { + public: + WebSocketStreamHandleDelegate() {} + + virtual void WillOpenStream(WebKit::WebSocketStreamHandle* handle, + const GURL& url) {} + virtual void WillSendData(WebKit::WebSocketStreamHandle* handle, + const char* data, int len) {} + + virtual void DidOpenStream(WebKit::WebSocketStreamHandle* handle, + int max_amount_send_allowed) {} + virtual void DidSendData(WebKit::WebSocketStreamHandle* handle, + int amount_sent) {} + virtual void DidReceiveData(WebKit::WebSocketStreamHandle* handle, + const char* data, int len) {} + virtual void DidClose(WebKit::WebSocketStreamHandle*) {} + virtual void DidFail(WebKit::WebSocketStreamHandle* handle, + int error_code, + const string16& error_msg) {} + + protected: + virtual ~WebSocketStreamHandleDelegate() {} +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ diff --git a/webkit/child/websocketstreamhandle_impl.cc b/webkit/child/websocketstreamhandle_impl.cc new file mode 100644 index 0000000..f7da0e2 --- /dev/null +++ b/webkit/child/websocketstreamhandle_impl.cc @@ -0,0 +1,196 @@ +// 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. + +// An implementation of WebSocketStreamHandle. + +#include "webkit/child/websocketstreamhandle_impl.h" + +#include + +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/strings/string16.h" +#include "third_party/WebKit/public/platform/WebData.h" +#include "third_party/WebKit/public/platform/WebSocketStreamError.h" +#include "third_party/WebKit/public/platform/WebSocketStreamHandleClient.h" +#include "third_party/WebKit/public/platform/WebURL.h" +#include "webkit/child/webkitplatformsupport_impl.h" +#include "webkit/child/websocketstreamhandle_delegate.h" +#include "webkit/glue/websocketstreamhandle_bridge.h" + +using WebKit::WebData; +using WebKit::WebSocketStreamError; +using WebKit::WebSocketStreamHandle; +using WebKit::WebSocketStreamHandleClient; +using WebKit::WebURL; + +namespace webkit_glue { + +// WebSocketStreamHandleImpl::Context ----------------------------------------- + +class WebSocketStreamHandleImpl::Context + : public base::RefCounted, + public WebSocketStreamHandleDelegate { + public: + explicit Context(WebSocketStreamHandleImpl* handle); + + WebSocketStreamHandleClient* client() const { return client_; } + void set_client(WebSocketStreamHandleClient* client) { + client_ = client; + } + + void Connect(const WebURL& url, WebKitPlatformSupportImpl* platform); + bool Send(const WebData& data); + void Close(); + + // Must be called before |handle_| or |client_| is deleted. + // Once detached, it never calls |client_| back. + void Detach(); + + // WebSocketStreamHandleDelegate methods: + virtual void DidOpenStream(WebSocketStreamHandle*, int) OVERRIDE; + virtual void DidSendData(WebSocketStreamHandle*, int) OVERRIDE; + virtual void DidReceiveData(WebSocketStreamHandle*, + const char*, + int) OVERRIDE; + virtual void DidClose(WebSocketStreamHandle*) OVERRIDE; + virtual void DidFail(WebSocketStreamHandle*, int, const string16&) OVERRIDE; + + private: + friend class base::RefCounted; + virtual ~Context() { + DCHECK(!handle_); + DCHECK(!client_); + DCHECK(!bridge_.get()); + } + + WebSocketStreamHandleImpl* handle_; + WebSocketStreamHandleClient* client_; + // |bridge_| is alive from Connect to DidClose, so Context must be alive + // in the time period. + scoped_refptr bridge_; + + DISALLOW_COPY_AND_ASSIGN(Context); +}; + +WebSocketStreamHandleImpl::Context::Context(WebSocketStreamHandleImpl* handle) + : handle_(handle), + client_(NULL), + bridge_(NULL) { +} + +void WebSocketStreamHandleImpl::Context::Connect( + const WebURL& url, + WebKitPlatformSupportImpl* platform) { + VLOG(1) << "Connect url=" << url; + DCHECK(!bridge_.get()); + bridge_ = platform->CreateWebSocketBridge(handle_, this); + AddRef(); // Will be released by DidClose(). + bridge_->Connect(url); +} + +bool WebSocketStreamHandleImpl::Context::Send(const WebData& data) { + VLOG(1) << "Send data.size=" << data.size(); + DCHECK(bridge_.get()); + return bridge_->Send( + std::vector(data.data(), data.data() + data.size())); +} + +void WebSocketStreamHandleImpl::Context::Close() { + VLOG(1) << "Close"; + if (bridge_.get()) + bridge_->Close(); +} + +void WebSocketStreamHandleImpl::Context::Detach() { + handle_ = NULL; + client_ = NULL; + // If Connect was called, |bridge_| is not NULL, so that this Context closes + // the |bridge_| here. Then |bridge_| will call back DidClose, and will + // be released by itself. + // Otherwise, |bridge_| is NULL. + if (bridge_.get()) + bridge_->Close(); +} + +void WebSocketStreamHandleImpl::Context::DidOpenStream( + WebSocketStreamHandle* web_handle, int max_amount_send_allowed) { + VLOG(1) << "DidOpen"; + if (client_) + client_->didOpenStream(handle_, max_amount_send_allowed); +} + +void WebSocketStreamHandleImpl::Context::DidSendData( + WebSocketStreamHandle* web_handle, int amount_sent) { + if (client_) + client_->didSendData(handle_, amount_sent); +} + +void WebSocketStreamHandleImpl::Context::DidReceiveData( + WebSocketStreamHandle* web_handle, const char* data, int size) { + if (client_) + client_->didReceiveData(handle_, WebData(data, size)); +} + +void WebSocketStreamHandleImpl::Context::DidClose( + WebSocketStreamHandle* web_handle) { + VLOG(1) << "DidClose"; + bridge_ = NULL; + WebSocketStreamHandleImpl* handle = handle_; + handle_ = NULL; + if (client_) { + WebSocketStreamHandleClient* client = client_; + client_ = NULL; + client->didClose(handle); + } + Release(); +} + +void WebSocketStreamHandleImpl::Context::DidFail( + WebSocketStreamHandle* web_handle, + int error_code, + const string16& error_msg) { + VLOG(1) << "DidFail"; + if (client_) { + client_->didFail( + handle_, + WebSocketStreamError(error_code, error_msg)); + } +} + +// WebSocketStreamHandleImpl ------------------------------------------------ + +WebSocketStreamHandleImpl::WebSocketStreamHandleImpl( + WebKitPlatformSupportImpl* platform) + : context_(new Context(this)), + platform_(platform) { +} + +WebSocketStreamHandleImpl::~WebSocketStreamHandleImpl() { + // We won't receive any events from |context_|. + // |context_| is ref counted, and will be released when it received + // DidClose. + context_->Detach(); +} + +void WebSocketStreamHandleImpl::connect( + const WebURL& url, WebSocketStreamHandleClient* client) { + VLOG(1) << "connect url=" << url; + DCHECK(!context_->client()); + context_->set_client(client); + + context_->Connect(url, platform_); +} + +bool WebSocketStreamHandleImpl::send(const WebData& data) { + return context_->Send(data); +} + +void WebSocketStreamHandleImpl::close() { + context_->Close(); +} + +} // namespace webkit_glue diff --git a/webkit/child/websocketstreamhandle_impl.h b/webkit/child/websocketstreamhandle_impl.h new file mode 100644 index 0000000..911b83e2 --- /dev/null +++ b/webkit/child/websocketstreamhandle_impl.h @@ -0,0 +1,40 @@ +// 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. + +#ifndef WEBKIT_CHILD_WEBSOCKETSTREAMHANDLE_IMPL_H_ +#define WEBKIT_CHILD_WEBSOCKETSTREAMHANDLE_IMPL_H_ + +#include "base/memory/ref_counted.h" +#include "base/supports_user_data.h" +#include "third_party/WebKit/public/platform/WebSocketStreamHandle.h" + +namespace webkit_glue { + +class WebKitPlatformSupportImpl; + +class WebSocketStreamHandleImpl + : public base::SupportsUserData, + public WebKit::WebSocketStreamHandle { + public: + explicit WebSocketStreamHandleImpl(WebKitPlatformSupportImpl* platform); + virtual ~WebSocketStreamHandleImpl(); + + // WebSocketStreamHandle methods: + virtual void connect( + const WebKit::WebURL& url, + WebKit::WebSocketStreamHandleClient* client); + virtual bool send(const WebKit::WebData& data); + virtual void close(); + + private: + class Context; + scoped_refptr context_; + WebKitPlatformSupportImpl* platform_; + + DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleImpl); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_WEBSOCKETSTREAMHANDLE_IMPL_H_ diff --git a/webkit/child/weburlloader_impl.cc b/webkit/child/weburlloader_impl.cc new file mode 100644 index 0000000..40b15ed --- /dev/null +++ b/webkit/child/weburlloader_impl.cc @@ -0,0 +1,854 @@ +// 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. + +// An implementation of WebURLLoader in terms of ResourceLoaderBridge. + +#include "webkit/child/weburlloader_impl.h" + +#include "base/bind.h" +#include "base/files/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/process_util.h" +#include "base/strings/string_util.h" +#include "base/time/time.h" +#include "net/base/data_url.h" +#include "net/base/load_flags.h" +#include "net/base/mime_util.h" +#include "net/base/net_errors.h" +#include "net/base/net_util.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_util.h" +#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" +#include "third_party/WebKit/public/platform/WebHTTPLoadInfo.h" +#include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/platform/WebURLError.h" +#include "third_party/WebKit/public/platform/WebURLLoadTiming.h" +#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" +#include "third_party/WebKit/public/platform/WebURLRequest.h" +#include "third_party/WebKit/public/platform/WebURLResponse.h" +#include "third_party/WebKit/public/web/WebSecurityPolicy.h" +#include "webkit/child/ftp_directory_listing_response_delegate.h" +#include "webkit/child/multipart_response_delegate.h" +#include "webkit/child/resource_loader_bridge.h" +#include "webkit/child/webkitplatformsupport_impl.h" +#include "webkit/child/weburlrequest_extradata_impl.h" +#include "webkit/child/weburlresponse_extradata_impl.h" +#include "webkit/common/resource_request_body.h" + +using base::Time; +using base::TimeTicks; +using WebKit::WebData; +using WebKit::WebHTTPBody; +using WebKit::WebHTTPHeaderVisitor; +using WebKit::WebHTTPLoadInfo; +using WebKit::WebReferrerPolicy; +using WebKit::WebSecurityPolicy; +using WebKit::WebString; +using WebKit::WebURL; +using WebKit::WebURLError; +using WebKit::WebURLLoadTiming; +using WebKit::WebURLLoader; +using WebKit::WebURLLoaderClient; +using WebKit::WebURLRequest; +using WebKit::WebURLResponse; + +namespace webkit_glue { + +// Utilities ------------------------------------------------------------------ + +namespace { + +const char kThrottledErrorDescription[] = + "Request throttled. Visit http://dev.chromium.org/throttling for more " + "information."; + +class HeaderFlattener : public WebHTTPHeaderVisitor { + public: + explicit HeaderFlattener(int load_flags) + : load_flags_(load_flags), + has_accept_header_(false) { + } + + virtual void visitHeader(const WebString& name, const WebString& value) { + // TODO(darin): is UTF-8 really correct here? It is if the strings are + // already ASCII (i.e., if they are already escaped properly). + const std::string& name_utf8 = name.utf8(); + const std::string& value_utf8 = value.utf8(); + + // Skip over referrer headers found in the header map because we already + // pulled it out as a separate parameter. + if (LowerCaseEqualsASCII(name_utf8, "referer")) + return; + + // Skip over "Cache-Control: max-age=0" header if the corresponding + // load flag is already specified. FrameLoader sets both the flag and + // the extra header -- the extra header is redundant since our network + // implementation will add the necessary headers based on load flags. + // See http://code.google.com/p/chromium/issues/detail?id=3434. + if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && + LowerCaseEqualsASCII(name_utf8, "cache-control") && + LowerCaseEqualsASCII(value_utf8, "max-age=0")) + return; + + if (LowerCaseEqualsASCII(name_utf8, "accept")) + has_accept_header_ = true; + + if (!buffer_.empty()) + buffer_.append("\r\n"); + buffer_.append(name_utf8 + ": " + value_utf8); + } + + const std::string& GetBuffer() { + // In some cases, WebKit doesn't add an Accept header, but not having the + // header confuses some web servers. See bug 808613. + if (!has_accept_header_) { + if (!buffer_.empty()) + buffer_.append("\r\n"); + buffer_.append("Accept: */*"); + has_accept_header_ = true; + } + return buffer_; + } + + private: + int load_flags_; + std::string buffer_; + bool has_accept_header_; +}; + +// Extracts the information from a data: url. +bool GetInfoFromDataURL(const GURL& url, + ResourceResponseInfo* info, + std::string* data, + int* error_code) { + std::string mime_type; + std::string charset; + if (net::DataURL::Parse(url, &mime_type, &charset, data)) { + *error_code = net::OK; + // Assure same time for all time fields of data: URLs. + Time now = Time::Now(); + info->load_timing.request_start = TimeTicks::Now(); + info->load_timing.request_start_time = now; + info->request_time = now; + info->response_time = now; + info->headers = NULL; + info->mime_type.swap(mime_type); + info->charset.swap(charset); + info->security_info.clear(); + info->content_length = data->length(); + info->encoded_data_length = 0; + + return true; + } + + *error_code = net::ERR_INVALID_URL; + return false; +} + +typedef ResourceDevToolsInfo::HeadersVector HeadersVector; + +// Converts timing data from |load_timing| to the format used by WebKit. +void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, + WebURLLoadTiming* url_timing) { + DCHECK(!load_timing.request_start.is_null()); + + const TimeTicks kNullTicks; + url_timing->initialize(); + url_timing->setRequestTime( + (load_timing.request_start - kNullTicks).InSecondsF()); + url_timing->setProxyStart( + (load_timing.proxy_resolve_start - kNullTicks).InSecondsF()); + url_timing->setProxyEnd( + (load_timing.proxy_resolve_end - kNullTicks).InSecondsF()); + url_timing->setDNSStart( + (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF()); + url_timing->setDNSEnd( + (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF()); + url_timing->setConnectStart( + (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF()); + url_timing->setConnectEnd( + (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF()); + url_timing->setSSLStart( + (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF()); + url_timing->setSSLEnd( + (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF()); + url_timing->setSendStart( + (load_timing.send_start - kNullTicks).InSecondsF()); + url_timing->setSendEnd( + (load_timing.send_end - kNullTicks).InSecondsF()); + url_timing->setReceiveHeadersEnd( + (load_timing.receive_headers_end - kNullTicks).InSecondsF()); +} + +void PopulateURLResponse( + const GURL& url, + const ResourceResponseInfo& info, + WebURLResponse* response) { + response->setURL(url); + response->setResponseTime(info.response_time.ToDoubleT()); + response->setMIMEType(WebString::fromUTF8(info.mime_type)); + response->setTextEncodingName(WebString::fromUTF8(info.charset)); + response->setExpectedContentLength(info.content_length); + response->setSecurityInfo(info.security_info); + response->setAppCacheID(info.appcache_id); + response->setAppCacheManifestURL(info.appcache_manifest_url); + response->setWasCached(!info.load_timing.request_start_time.is_null() && + info.response_time < info.load_timing.request_start_time); + response->setRemoteIPAddress( + WebString::fromUTF8(info.socket_address.host())); + response->setRemotePort(info.socket_address.port()); + response->setConnectionID(info.load_timing.socket_log_id); + response->setConnectionReused(info.load_timing.socket_reused); + response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe()); + WebURLResponseExtraDataImpl* extra_data = + new WebURLResponseExtraDataImpl(info.npn_negotiated_protocol); + response->setExtraData(extra_data); + extra_data->set_was_fetched_via_spdy(info.was_fetched_via_spdy); + extra_data->set_was_npn_negotiated(info.was_npn_negotiated); + extra_data->set_was_alternate_protocol_available( + info.was_alternate_protocol_available); + extra_data->set_connection_info(info.connection_info); + extra_data->set_was_fetched_via_proxy(info.was_fetched_via_proxy); + + // If there's no received headers end time, don't set load timing. This is + // the case for non-HTTP requests, requests that don't go over the wire, and + // certain error cases. + if (!info.load_timing.receive_headers_end.is_null()) { + WebURLLoadTiming timing; + PopulateURLLoadTiming(info.load_timing, &timing); + response->setLoadTiming(timing); + } + + if (info.devtools_info.get()) { + WebHTTPLoadInfo load_info; + + load_info.setHTTPStatusCode(info.devtools_info->http_status_code); + load_info.setHTTPStatusText(WebString::fromUTF8( + info.devtools_info->http_status_text)); + load_info.setEncodedDataLength(info.encoded_data_length); + + load_info.setRequestHeadersText(WebString::fromUTF8( + info.devtools_info->request_headers_text)); + load_info.setResponseHeadersText(WebString::fromUTF8( + info.devtools_info->response_headers_text)); + const HeadersVector& request_headers = info.devtools_info->request_headers; + for (HeadersVector::const_iterator it = request_headers.begin(); + it != request_headers.end(); ++it) { + load_info.addRequestHeader(WebString::fromUTF8(it->first), + WebString::fromUTF8(it->second)); + } + const HeadersVector& response_headers = + info.devtools_info->response_headers; + for (HeadersVector::const_iterator it = response_headers.begin(); + it != response_headers.end(); ++it) { + load_info.addResponseHeader(WebString::fromUTF8(it->first), + WebString::fromUTF8(it->second)); + } + response->setHTTPLoadInfo(load_info); + } + + const net::HttpResponseHeaders* headers = info.headers.get(); + if (!headers) + return; + + WebURLResponse::HTTPVersion version = WebURLResponse::Unknown; + if (headers->GetHttpVersion() == net::HttpVersion(0, 9)) + version = WebURLResponse::HTTP_0_9; + else if (headers->GetHttpVersion() == net::HttpVersion(1, 0)) + version = WebURLResponse::HTTP_1_0; + else if (headers->GetHttpVersion() == net::HttpVersion(1, 1)) + version = WebURLResponse::HTTP_1_1; + response->setHTTPVersion(version); + response->setHTTPStatusCode(headers->response_code()); + response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText())); + + // TODO(darin): We should leverage HttpResponseHeaders for this, and this + // should be using the same code as ResourceDispatcherHost. + // TODO(jungshik): Figure out the actual value of the referrer charset and + // pass it to GetSuggestedFilename. + std::string value; + headers->EnumerateHeader(NULL, "content-disposition", &value); + response->setSuggestedFileName( + net::GetSuggestedFilename(url, + value, + std::string(), // referrer_charset + std::string(), // suggested_name + std::string(), // mime_type + std::string())); // default_name + + Time time_val; + if (headers->GetLastModifiedValue(&time_val)) + response->setLastModifiedDate(time_val.ToDoubleT()); + + // Build up the header map. + void* iter = NULL; + std::string name; + while (headers->EnumerateHeaderLines(&iter, &name, &value)) { + response->addHTTPHeaderField(WebString::fromUTF8(name), + WebString::fromUTF8(value)); + } +} + +net::RequestPriority ConvertWebKitPriorityToNetPriority( + const WebURLRequest::Priority& priority) { + switch (priority) { + case WebURLRequest::PriorityVeryHigh: + return net::HIGHEST; + + case WebURLRequest::PriorityHigh: + return net::MEDIUM; + + case WebURLRequest::PriorityMedium: + return net::LOW; + + case WebURLRequest::PriorityLow: + return net::LOWEST; + + case WebURLRequest::PriorityVeryLow: + return net::IDLE; + + case WebURLRequest::PriorityUnresolved: + default: + NOTREACHED(); + return net::LOW; + } +} + +} // namespace + +// WebURLLoaderImpl::Context -------------------------------------------------- + +// This inner class exists since the WebURLLoader may be deleted while inside a +// call to WebURLLoaderClient. The bridge requires its Peer to stay alive +// until it receives OnCompletedRequest. +class WebURLLoaderImpl::Context : public base::RefCounted, + public ResourceLoaderBridge::Peer { + public: + explicit Context(WebURLLoaderImpl* loader); + + WebURLLoaderClient* client() const { return client_; } + void set_client(WebURLLoaderClient* client) { client_ = client; } + + void Cancel(); + void SetDefersLoading(bool value); + void DidChangePriority(WebURLRequest::Priority new_priority); + void Start( + const WebURLRequest& request, + ResourceLoaderBridge::SyncLoadResponse* sync_load_response, + WebKitPlatformSupportImpl* platform); + + // ResourceLoaderBridge::Peer methods: + virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE; + virtual bool OnReceivedRedirect( + const GURL& new_url, + const ResourceResponseInfo& info, + bool* has_new_first_party_for_cookies, + GURL* new_first_party_for_cookies) OVERRIDE; + virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE; + virtual void OnDownloadedData(int len) OVERRIDE; + virtual void OnReceivedData(const char* data, + int data_length, + int encoded_data_length) OVERRIDE; + virtual void OnReceivedCachedMetadata(const char* data, int len) OVERRIDE; + virtual void OnCompletedRequest( + int error_code, + bool was_ignored_by_handler, + const std::string& security_info, + const base::TimeTicks& completion_time) OVERRIDE; + + private: + friend class base::RefCounted; + virtual ~Context() {} + + // We can optimize the handling of data URLs in most cases. + bool CanHandleDataURL(const GURL& url) const; + void HandleDataURL(); + + WebURLLoaderImpl* loader_; + WebURLRequest request_; + WebURLLoaderClient* client_; + WebReferrerPolicy referrer_policy_; + scoped_ptr bridge_; + scoped_ptr ftp_listing_delegate_; + scoped_ptr multipart_delegate_; + scoped_ptr completed_bridge_; +}; + +WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) + : loader_(loader), + client_(NULL), + referrer_policy_(WebKit::WebReferrerPolicyDefault) { +} + +void WebURLLoaderImpl::Context::Cancel() { + // The bridge will still send OnCompletedRequest, which will Release() us, so + // we don't do that here. + if (bridge_) + bridge_->Cancel(); + + // Ensure that we do not notify the multipart delegate anymore as it has + // its own pointer to the client. + if (multipart_delegate_) + multipart_delegate_->Cancel(); + + // Do not make any further calls to the client. + client_ = NULL; + loader_ = NULL; +} + +void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { + if (bridge_) + bridge_->SetDefersLoading(value); +} + +void WebURLLoaderImpl::Context::DidChangePriority( + WebURLRequest::Priority new_priority) { + if (bridge_) + bridge_->DidChangePriority( + ConvertWebKitPriorityToNetPriority(new_priority)); +} + +void WebURLLoaderImpl::Context::Start( + const WebURLRequest& request, + ResourceLoaderBridge::SyncLoadResponse* sync_load_response, + WebKitPlatformSupportImpl* platform) { + DCHECK(!bridge_.get()); + + request_ = request; // Save the request. + + GURL url = request.url(); + if (url.SchemeIs("data") && CanHandleDataURL(url)) { + if (sync_load_response) { + // This is a sync load. Do the work now. + sync_load_response->url = url; + std::string data; + GetInfoFromDataURL(sync_load_response->url, sync_load_response, + &sync_load_response->data, + &sync_load_response->error_code); + } else { + AddRef(); // Balanced in OnCompletedRequest + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(&Context::HandleDataURL, this)); + } + return; + } + + GURL referrer_url( + request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); + const std::string& method = request.httpMethod().utf8(); + + int load_flags = net::LOAD_NORMAL; + switch (request.cachePolicy()) { + case WebURLRequest::ReloadIgnoringCacheData: + // Required by LayoutTests/http/tests/misc/refresh-headers.php + load_flags |= net::LOAD_VALIDATE_CACHE; + break; + case WebURLRequest::ReturnCacheDataElseLoad: + load_flags |= net::LOAD_PREFERRING_CACHE; + break; + case WebURLRequest::ReturnCacheDataDontLoad: + load_flags |= net::LOAD_ONLY_FROM_CACHE; + break; + case WebURLRequest::UseProtocolCachePolicy: + break; + } + + if (request.reportUploadProgress()) + load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; + if (request.reportLoadTiming()) + load_flags |= net::LOAD_ENABLE_LOAD_TIMING; + if (request.reportRawHeaders()) + load_flags |= net::LOAD_REPORT_RAW_HEADERS; + + if (!request.allowCookies() || !request.allowStoredCredentials()) { + load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; + load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; + } + + if (!request.allowStoredCredentials()) + load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; + + HeaderFlattener flattener(load_flags); + request.visitHTTPHeaderFields(&flattener); + + // TODO(brettw) this should take parameter encoding into account when + // creating the GURLs. + + ResourceLoaderBridge::RequestInfo request_info; + request_info.method = method; + request_info.url = url; + request_info.first_party_for_cookies = request.firstPartyForCookies(); + request_info.referrer = referrer_url; + request_info.headers = flattener.GetBuffer(); + request_info.load_flags = load_flags; + // requestor_pid only needs to be non-zero if the request originates outside + // the render process, so we can use requestorProcessID even for requests + // from in-process plugins. + request_info.requestor_pid = request.requestorProcessID(); + request_info.request_type = + ResourceType::FromTargetType(request.targetType()); + request_info.priority = + ConvertWebKitPriorityToNetPriority(request.priority()); + request_info.appcache_host_id = request.appCacheHostID(); + request_info.routing_id = request.requestorID(); + request_info.download_to_file = request.downloadToFile(); + request_info.has_user_gesture = request.hasUserGesture(); + request_info.extra_data = request.extraData(); + if (request.extraData()) { + referrer_policy_ = static_cast( + request.extraData())->referrer_policy(); + request_info.referrer_policy = referrer_policy_; + } + bridge_.reset(platform->CreateResourceLoader(request_info)); + + if (!request.httpBody().isNull()) { + // GET and HEAD requests shouldn't have http bodies. + DCHECK(method != "GET" && method != "HEAD"); + const WebHTTPBody& httpBody = request.httpBody(); + size_t i = 0; + WebHTTPBody::Element element; + scoped_refptr request_body = new ResourceRequestBody; + while (httpBody.elementAt(i++, element)) { + switch (element.type) { + case WebHTTPBody::Element::TypeData: + if (!element.data.isEmpty()) { + // WebKit sometimes gives up empty data to append. These aren't + // necessary so we just optimize those out here. + request_body->AppendBytes( + element.data.data(), static_cast(element.data.size())); + } + break; + case WebHTTPBody::Element::TypeFile: + if (element.fileLength == -1) { + request_body->AppendFileRange( + base::FilePath::FromUTF16Unsafe(element.filePath), + 0, kuint64max, base::Time()); + } else { + request_body->AppendFileRange( + base::FilePath::FromUTF16Unsafe(element.filePath), + static_cast(element.fileStart), + static_cast(element.fileLength), + base::Time::FromDoubleT(element.modificationTime)); + } + break; + case WebHTTPBody::Element::TypeURL: { + GURL url = GURL(element.url); + DCHECK(url.SchemeIsFileSystem()); + request_body->AppendFileSystemFileRange( + url, + static_cast(element.fileStart), + static_cast(element.fileLength), + base::Time::FromDoubleT(element.modificationTime)); + break; + } + case WebHTTPBody::Element::TypeBlob: + request_body->AppendBlob(GURL(element.blobURL)); + break; + default: + NOTREACHED(); + } + } + request_body->set_identifier(request.httpBody().identifier()); + bridge_->SetRequestBody(request_body.get()); + } + + if (sync_load_response) { + bridge_->SyncLoad(sync_load_response); + return; + } + + if (bridge_->Start(this)) { + AddRef(); // Balanced in OnCompletedRequest + } else { + bridge_.reset(); + } +} + +void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { + if (client_) + client_->didSendData(loader_, position, size); +} + +bool WebURLLoaderImpl::Context::OnReceivedRedirect( + const GURL& new_url, + const ResourceResponseInfo& info, + bool* has_new_first_party_for_cookies, + GURL* new_first_party_for_cookies) { + if (!client_) + return false; + + WebURLResponse response; + response.initialize(); + PopulateURLResponse(request_.url(), info, &response); + + // TODO(darin): We lack sufficient information to construct the actual + // request that resulted from the redirect. + WebURLRequest new_request(new_url); + new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); + new_request.setDownloadToFile(request_.downloadToFile()); + + WebString referrer_string = WebString::fromUTF8("Referer"); + WebString referrer = WebSecurityPolicy::generateReferrerHeader( + referrer_policy_, + new_url, + request_.httpHeaderField(referrer_string)); + if (!referrer.isEmpty()) + new_request.setHTTPHeaderField(referrer_string, referrer); + + if (response.httpStatusCode() == 307) + new_request.setHTTPMethod(request_.httpMethod()); + + client_->willSendRequest(loader_, new_request, response); + request_ = new_request; + *has_new_first_party_for_cookies = true; + *new_first_party_for_cookies = request_.firstPartyForCookies(); + + // Only follow the redirect if WebKit left the URL unmodified. + if (new_url == GURL(new_request.url())) + return true; + + // We assume that WebKit only changes the URL to suppress a redirect, and we + // assume that it does so by setting it to be invalid. + DCHECK(!new_request.url().isValid()); + return false; +} + +void WebURLLoaderImpl::Context::OnReceivedResponse( + const ResourceResponseInfo& info) { + if (!client_) + return; + + WebURLResponse response; + response.initialize(); + PopulateURLResponse(request_.url(), info, &response); + + bool show_raw_listing = (GURL(request_.url()).query() == "raw"); + + if (info.mime_type == "text/vnd.chromium.ftp-dir") { + if (show_raw_listing) { + // Set the MIME type to plain text to prevent any active content. + response.setMIMEType("text/plain"); + } else { + // We're going to produce a parsed listing in HTML. + response.setMIMEType("text/html"); + } + } + + scoped_refptr protect(this); + client_->didReceiveResponse(loader_, response); + + // We may have been cancelled after didReceiveResponse, which would leave us + // without a client and therefore without much need to do further handling. + if (!client_) + return; + + DCHECK(!ftp_listing_delegate_.get()); + DCHECK(!multipart_delegate_.get()); + if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") { + std::string content_type; + info.headers->EnumerateHeader(NULL, "content-type", &content_type); + + std::string mime_type; + std::string charset; + bool had_charset = false; + std::string boundary; + net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, + &had_charset, &boundary); + TrimString(boundary, " \"", &boundary); + + // If there's no boundary, just handle the request normally. In the gecko + // code, nsMultiMixedConv::OnStartRequest throws an exception. + if (!boundary.empty()) { + multipart_delegate_.reset( + new MultipartResponseDelegate(client_, loader_, response, boundary)); + } + } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && + !show_raw_listing) { + ftp_listing_delegate_.reset( + new FtpDirectoryListingResponseDelegate(client_, loader_, response)); + } +} + +void WebURLLoaderImpl::Context::OnDownloadedData(int len) { + if (client_) + client_->didDownloadData(loader_, len); +} + +void WebURLLoaderImpl::Context::OnReceivedData(const char* data, + int data_length, + int encoded_data_length) { + if (!client_) + return; + + if (ftp_listing_delegate_) { + // The FTP listing delegate will make the appropriate calls to + // client_->didReceiveData and client_->didReceiveResponse. + ftp_listing_delegate_->OnReceivedData(data, data_length); + } else if (multipart_delegate_) { + // The multipart delegate will make the appropriate calls to + // client_->didReceiveData and client_->didReceiveResponse. + multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length); + } else { + client_->didReceiveData(loader_, data, data_length, encoded_data_length); + } +} + +void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( + const char* data, int len) { + if (client_) + client_->didReceiveCachedMetadata(loader_, data, len); +} + +void WebURLLoaderImpl::Context::OnCompletedRequest( + int error_code, + bool was_ignored_by_handler, + const std::string& security_info, + const base::TimeTicks& completion_time) { + if (ftp_listing_delegate_) { + ftp_listing_delegate_->OnCompletedRequest(); + ftp_listing_delegate_.reset(NULL); + } else if (multipart_delegate_) { + multipart_delegate_->OnCompletedRequest(); + multipart_delegate_.reset(NULL); + } + + // Prevent any further IPC to the browser now that we're complete, but + // don't delete it to keep any downloaded temp files alive. + DCHECK(!completed_bridge_.get()); + completed_bridge_.swap(bridge_); + + if (client_) { + if (error_code != net::OK) { + client_->didFail(loader_, CreateError(request_.url(), error_code)); + } else { + client_->didFinishLoading( + loader_, (completion_time - TimeTicks()).InSecondsF()); + } + } + + // We are done with the bridge now, and so we need to release the reference + // to ourselves that we took on behalf of the bridge. This may cause our + // destruction. + Release(); +} + +bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const { + DCHECK(url.SchemeIs("data")); + + // Optimize for the case where we can handle a data URL locally. We must + // skip this for data URLs targetted at frames since those could trigger a + // download. + // + // NOTE: We special case MIME types we can render both for performance + // reasons as well as to support unit tests, which do not have an underlying + // ResourceLoaderBridge implementation. + +#if defined(OS_ANDROID) + // For compatibility reasons on Android we need to expose top-level data:// + // to the browser. + if (request_.targetType() == WebURLRequest::TargetIsMainFrame) + return false; +#endif + + if (request_.targetType() != WebURLRequest::TargetIsMainFrame && + request_.targetType() != WebURLRequest::TargetIsSubframe) + return true; + + std::string mime_type, unused_charset; + if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && + net::IsSupportedMimeType(mime_type)) + return true; + + return false; +} + +void WebURLLoaderImpl::Context::HandleDataURL() { + ResourceResponseInfo info; + int error_code; + std::string data; + + if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { + OnReceivedResponse(info); + if (!data.empty()) + OnReceivedData(data.data(), data.size(), 0); + } + + OnCompletedRequest(error_code, false, info.security_info, + base::TimeTicks::Now()); +} + +// WebURLLoaderImpl ----------------------------------------------------------- + +WebURLLoaderImpl::WebURLLoaderImpl(WebKitPlatformSupportImpl* platform) + : context_(new Context(this)), + platform_(platform) { +} + +WebURLLoaderImpl::~WebURLLoaderImpl() { + cancel(); +} + +WebURLError WebURLLoaderImpl::CreateError(const WebURL& unreachable_url, + int reason) { + WebURLError error; + error.domain = WebString::fromUTF8(net::kErrorDomain); + error.reason = reason; + error.unreachableURL = unreachable_url; + if (reason == net::ERR_ABORTED) { + error.isCancellation = true; + } else if (reason == net::ERR_TEMPORARILY_THROTTLED) { + error.localizedDescription = WebString::fromUTF8( + kThrottledErrorDescription); + } + return error; +} + +void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, + WebURLResponse& response, + WebURLError& error, + WebData& data) { + ResourceLoaderBridge::SyncLoadResponse sync_load_response; + context_->Start(request, &sync_load_response, platform_); + + const GURL& final_url = sync_load_response.url; + + // TODO(tc): For file loads, we may want to include a more descriptive + // status code or status text. + int error_code = sync_load_response.error_code; + if (error_code != net::OK) { + response.setURL(final_url); + error.domain = WebString::fromUTF8(net::kErrorDomain); + error.reason = error_code; + error.unreachableURL = final_url; + return; + } + + PopulateURLResponse(final_url, sync_load_response, &response); + + data.assign(sync_load_response.data.data(), + sync_load_response.data.size()); +} + +void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, + WebURLLoaderClient* client) { + DCHECK(!context_->client()); + + context_->set_client(client); + context_->Start(request, NULL, platform_); +} + +void WebURLLoaderImpl::cancel() { + context_->Cancel(); +} + +void WebURLLoaderImpl::setDefersLoading(bool value) { + context_->SetDefersLoading(value); +} + +void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority) { + context_->DidChangePriority(new_priority); +} + +} // namespace webkit_glue diff --git a/webkit/child/weburlloader_impl.h b/webkit/child/weburlloader_impl.h new file mode 100644 index 0000000..1412b32 --- /dev/null +++ b/webkit/child/weburlloader_impl.h @@ -0,0 +1,44 @@ +// 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. + +#ifndef WEBKIT_CHILD_WEBURLLOADER_IMPL_H_ +#define WEBKIT_CHILD_WEBURLLOADER_IMPL_H_ + +#include "base/memory/ref_counted.h" +#include "third_party/WebKit/public/platform/WebURLLoader.h" + +namespace webkit_glue { + +class WebKitPlatformSupportImpl; + +class WebURLLoaderImpl : public WebKit::WebURLLoader { + public: + explicit WebURLLoaderImpl(WebKitPlatformSupportImpl* platform); + virtual ~WebURLLoaderImpl(); + + static WebKit::WebURLError CreateError(const WebKit::WebURL& unreachable_url, + int reason); + + // WebURLLoader methods: + virtual void loadSynchronously( + const WebKit::WebURLRequest& request, + WebKit::WebURLResponse& response, + WebKit::WebURLError& error, + WebKit::WebData& data); + virtual void loadAsynchronously( + const WebKit::WebURLRequest& request, + WebKit::WebURLLoaderClient* client); + virtual void cancel(); + virtual void setDefersLoading(bool value); + virtual void didChangePriority(WebKit::WebURLRequest::Priority new_priority); + + private: + class Context; + scoped_refptr context_; + WebKitPlatformSupportImpl* platform_; +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_WEBURLLOADER_IMPL_H_ diff --git a/webkit/child/weburlrequest_extradata_impl.cc b/webkit/child/weburlrequest_extradata_impl.cc new file mode 100644 index 0000000..231672c --- /dev/null +++ b/webkit/child/weburlrequest_extradata_impl.cc @@ -0,0 +1,22 @@ +// 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/child/weburlrequest_extradata_impl.h" + +using WebKit::WebReferrerPolicy; +using WebKit::WebString; + +namespace webkit_glue { + +WebURLRequestExtraDataImpl::WebURLRequestExtraDataImpl( + WebReferrerPolicy referrer_policy, + const WebString& custom_user_agent) + : referrer_policy_(referrer_policy), + custom_user_agent_(custom_user_agent) { +} + +WebURLRequestExtraDataImpl::~WebURLRequestExtraDataImpl() { +} + +} // namespace webkit_glue diff --git a/webkit/child/weburlrequest_extradata_impl.h b/webkit/child/weburlrequest_extradata_impl.h new file mode 100644 index 0000000..6e5dccd --- /dev/null +++ b/webkit/child/weburlrequest_extradata_impl.h @@ -0,0 +1,45 @@ +// 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. + +#ifndef WEBKIT_CHILD_WEBURLREQUEST_EXTRADATA_IMPL_H_ +#define WEBKIT_CHILD_WEBURLREQUEST_EXTRADATA_IMPL_H_ + +#include "base/compiler_specific.h" +#include "third_party/WebKit/public/platform/WebReferrerPolicy.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/WebURLRequest.h" +#include "webkit/child/webkit_child_export.h" + +namespace webkit_glue { + +// Base class for Chrome's implementation of the "extra data" stored in each +// ResourceRequest. +class WEBKIT_CHILD_EXPORT WebURLRequestExtraDataImpl : + public NON_EXPORTED_BASE(WebKit::WebURLRequest::ExtraData) { + public: + // |custom_user_agent| is used to communicate an overriding custom user agent + // to |RenderViewImpl::willSendRequest()|; set to a null string to indicate no + // override and an empty string to indicate that there should be no user + // agent. This needs to be here, instead of content's |RequestExtraData| since + // ppb_url_request_info_impl.cc needs to be able to set it. + explicit WebURLRequestExtraDataImpl( + WebKit::WebReferrerPolicy referrer_policy, + const WebKit::WebString& custom_user_agent); + virtual ~WebURLRequestExtraDataImpl(); + + WebKit::WebReferrerPolicy referrer_policy() const { return referrer_policy_; } + const WebKit::WebString& custom_user_agent() const { + return custom_user_agent_; + } + + private: + WebKit::WebReferrerPolicy referrer_policy_; + WebKit::WebString custom_user_agent_; + + DISALLOW_COPY_AND_ASSIGN(WebURLRequestExtraDataImpl); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_WEBURLREQUEST_EXTRADATA_IMPL_H_ diff --git a/webkit/child/weburlresponse_extradata_impl.cc b/webkit/child/weburlresponse_extradata_impl.cc new file mode 100644 index 0000000..89ace8a --- /dev/null +++ b/webkit/child/weburlresponse_extradata_impl.cc @@ -0,0 +1,19 @@ +// 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/child/weburlresponse_extradata_impl.h" + +namespace webkit_glue { + +WebURLResponseExtraDataImpl::WebURLResponseExtraDataImpl( + const std::string& npn_negotiated_protocol) + : npn_negotiated_protocol_(npn_negotiated_protocol), + is_ftp_directory_listing_(false), + connection_info_(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN) { +} + +WebURLResponseExtraDataImpl::~WebURLResponseExtraDataImpl() { +} + +} // namespace webkit_glue diff --git a/webkit/child/weburlresponse_extradata_impl.h b/webkit/child/weburlresponse_extradata_impl.h new file mode 100644 index 0000000..ac87d7e --- /dev/null +++ b/webkit/child/weburlresponse_extradata_impl.h @@ -0,0 +1,96 @@ +// 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. + +#ifndef WEBKIT_CHILD_WEBURLRESPONSE_EXTRADATA_IMPL_H_ +#define WEBKIT_CHILD_WEBURLRESPONSE_EXTRADATA_IMPL_H_ + +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "net/http/http_response_info.h" +#include "third_party/WebKit/public/platform/WebURLResponse.h" +#include "webkit/child/webkit_child_export.h" + +namespace webkit_glue { + +// Base class for Chrome's implementation of the "extra data". +class WEBKIT_CHILD_EXPORT WebURLResponseExtraDataImpl : + public NON_EXPORTED_BASE(WebKit::WebURLResponse::ExtraData) { + public: + explicit WebURLResponseExtraDataImpl( + const std::string& npn_negotiated_protocol); + virtual ~WebURLResponseExtraDataImpl(); + + const std::string& npn_negotiated_protocol() const { + return npn_negotiated_protocol_; + } + + // Flag whether this request was loaded via an explicit proxy + // (HTTP, SOCKS, etc). + bool was_fetched_via_proxy() const { + return was_fetched_via_proxy_; + } + void set_was_fetched_via_proxy(bool was_fetched_via_proxy) { + was_fetched_via_proxy_ = was_fetched_via_proxy; + } + + /// Flag whether this request was loaded via the SPDY protocol or not. + // SPDY is an experimental web protocol, see http://dev.chromium.org/spdy + bool was_fetched_via_spdy() const { + return was_fetched_via_spdy_; + } + void set_was_fetched_via_spdy(bool was_fetched_via_spdy) { + was_fetched_via_spdy_ = was_fetched_via_spdy; + } + + // Information about the type of connection used to fetch this response. + net::HttpResponseInfo::ConnectionInfo connection_info() const { + return connection_info_; + } + void set_connection_info( + net::HttpResponseInfo::ConnectionInfo connection_info) { + connection_info_ = connection_info; + } + + // Flag whether this request was loaded after the + // TLS/Next-Protocol-Negotiation was used. + // This is related to SPDY. + bool was_npn_negotiated() const { + return was_npn_negotiated_; + } + void set_was_npn_negotiated(bool was_npn_negotiated) { + was_npn_negotiated_ = was_npn_negotiated; + } + + // Flag whether this request was made when "Alternate-Protocol: xxx" + // is present in server's response. + bool was_alternate_protocol_available() const { + return was_alternate_protocol_available_; + } + void set_was_alternate_protocol_available( + bool was_alternate_protocol_available) { + was_alternate_protocol_available_ = was_alternate_protocol_available; + } + + bool is_ftp_directory_listing() const { return is_ftp_directory_listing_; } + void set_is_ftp_directory_listing(bool is_ftp_directory_listing) { + is_ftp_directory_listing_ = is_ftp_directory_listing; + } + + private: + std::string npn_negotiated_protocol_; + bool is_ftp_directory_listing_; + bool was_fetched_via_proxy_; + bool was_fetched_via_spdy_; + bool was_npn_negotiated_; + net::HttpResponseInfo::ConnectionInfo connection_info_; + bool was_alternate_protocol_available_; + + DISALLOW_COPY_AND_ASSIGN(WebURLResponseExtraDataImpl); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_CHILD_WEBURLRESPONSE_EXTRADATA_IMPL_H_ diff --git a/webkit/common/resource_request_body.h b/webkit/common/resource_request_body.h index 5c1edd1..c0bdc08 100644 --- a/webkit/common/resource_request_body.h +++ b/webkit/common/resource_request_body.h @@ -62,4 +62,4 @@ class WEBKIT_COMMON_EXPORT ResourceRequestBody } // namespace webkit_glue -#endif // WEBKIT_GLUE_RESOURCE_REQUEST_BODY_H_ +#endif // WEBKIT_COMMON_RESOURCE_REQUEST_BODY_H_ diff --git a/webkit/common/resource_type.cc b/webkit/common/resource_type.cc new file mode 100644 index 0000000..2c416d3 --- /dev/null +++ b/webkit/common/resource_type.cc @@ -0,0 +1,47 @@ +// 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/common/resource_type.h" + +#include "base/logging.h" + +using WebKit::WebURLRequest; + +// static +ResourceType::Type ResourceType::FromTargetType( + WebURLRequest::TargetType type) { + switch (type) { + case WebURLRequest::TargetIsMainFrame: + return ResourceType::MAIN_FRAME; + case WebURLRequest::TargetIsSubframe: + return ResourceType::SUB_FRAME; + case WebURLRequest::TargetIsSubresource: + return ResourceType::SUB_RESOURCE; + case WebURLRequest::TargetIsStyleSheet: + return ResourceType::STYLESHEET; + case WebURLRequest::TargetIsScript: + return ResourceType::SCRIPT; + case WebURLRequest::TargetIsFontResource: + return ResourceType::FONT_RESOURCE; + case WebURLRequest::TargetIsImage: + return ResourceType::IMAGE; + case WebURLRequest::TargetIsObject: + return ResourceType::OBJECT; + case WebURLRequest::TargetIsMedia: + return ResourceType::MEDIA; + case WebURLRequest::TargetIsWorker: + return ResourceType::WORKER; + case WebURLRequest::TargetIsSharedWorker: + return ResourceType::SHARED_WORKER; + case WebURLRequest::TargetIsPrefetch: + return ResourceType::PREFETCH; + case WebURLRequest::TargetIsFavicon: + return ResourceType::FAVICON; + case WebURLRequest::TargetIsXHR: + return ResourceType::XHR; + default: + NOTREACHED(); + return ResourceType::SUB_RESOURCE; + } +} diff --git a/webkit/common/resource_type.h b/webkit/common/resource_type.h new file mode 100644 index 0000000..9ec7909 --- /dev/null +++ b/webkit/common/resource_type.h @@ -0,0 +1,70 @@ +// 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. + +#ifndef WEBKIT_COMMON_RESOURCE_TYPE_H__ +#define WEBKIT_COMMON_RESOURCE_TYPE_H__ + +#include "base/basictypes.h" +#include "third_party/WebKit/public/platform/WebURLRequest.h" +#include "webkit/common/webkit_common_export.h" + +class ResourceType { + public: + // Used in histograms, so please add new types at the end, and rename unused + // entries to RESOURCETYPE_UNUSED_0, etc... + enum Type { + MAIN_FRAME = 0, // top level page + SUB_FRAME, // frame or iframe + STYLESHEET, // a CSS stylesheet + SCRIPT, // an external script + IMAGE, // an image (jpg/gif/png/etc) + FONT_RESOURCE, // a font + SUB_RESOURCE, // an "other" subresource. + OBJECT, // an object (or embed) tag for a plugin, + // or a resource that a plugin requested. + MEDIA, // a media resource. + WORKER, // the main resource of a dedicated worker. + SHARED_WORKER, // the main resource of a shared worker. + PREFETCH, // an explicitly requested prefetch + FAVICON, // a favicon + XHR, // a XMLHttpRequest + LAST_TYPE // Place holder so we don't need to change ValidType + // everytime. + }; + + static bool ValidType(int32 type) { + return type >= MAIN_FRAME && type < LAST_TYPE; + } + + static Type FromInt(int32 type) { + return static_cast(type); + } + + WEBKIT_COMMON_EXPORT static Type FromTargetType( + WebKit::WebURLRequest::TargetType type); + + static bool IsFrame(ResourceType::Type type) { + return type == MAIN_FRAME || type == SUB_FRAME; + } + + static bool IsSharedWorker(ResourceType::Type type) { + return type == SHARED_WORKER; + } + + static bool IsSubresource(ResourceType::Type type) { + return type == STYLESHEET || + type == SCRIPT || + type == IMAGE || + type == FONT_RESOURCE || + type == SUB_RESOURCE || + type == WORKER || + type == XHR; + } + + private: + // Don't instantiate this class. + ResourceType(); + ~ResourceType(); +}; +#endif // WEBKIT_COMMON_RESOURCE_TYPE_H__ diff --git a/webkit/common/webkit_common.gyp b/webkit/common/webkit_common.gyp index e3b6579..af1c688 100644 --- a/webkit/common/webkit_common.gyp +++ b/webkit/common/webkit_common.gyp @@ -15,8 +15,8 @@ 'WEBKIT_COMMON_IMPLEMENTATION', ], 'dependencies': [ - '<(DEPTH)/base/base.gyp:base_i18n', '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/base/base.gyp:base_i18n', '<(DEPTH)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '<(DEPTH)/net/net.gyp:net', '<(DEPTH)/skia/skia.gyp:skia', @@ -39,10 +39,10 @@ 'cursors/webcursor_aura.cc', 'cursors/webcursor_aurawin.cc', 'cursors/webcursor_aurax11.cc', - 'cursors/webcursor_null.cc', 'cursors/webcursor_gtk.cc', 'cursors/webcursor_gtk_data.h', 'cursors/webcursor_mac.mm', + 'cursors/webcursor_null.cc', 'cursors/webcursor_win.cc', 'data_element.cc', 'data_element.h', @@ -52,6 +52,8 @@ 'resource_request_body.h', 'resource_response_info.cc', 'resource_response_info.h', + 'resource_type.cc', + 'resource_type.h', ], 'conditions': [ diff --git a/webkit/glue/ftp_directory_listing_response_delegate.cc b/webkit/glue/ftp_directory_listing_response_delegate.cc deleted file mode 100644 index 0629000..0000000 --- a/webkit/glue/ftp_directory_listing_response_delegate.cc +++ /dev/null @@ -1,123 +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/ftp_directory_listing_response_delegate.h" - -#include - -#include "base/i18n/icu_encoding_detection.h" -#include "base/i18n/icu_string_conversions.h" -#include "base/logging.h" -#include "base/strings/string_util.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "net/base/escape.h" -#include "net/base/net_errors.h" -#include "net/base/net_util.h" -#include "net/ftp/ftp_directory_listing_parser.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" -#include "webkit/glue/weburlresponse_extradata_impl.h" - -using net::FtpDirectoryListingEntry; - -using WebKit::WebURLLoader; -using WebKit::WebURLLoaderClient; -using WebKit::WebURLResponse; - -namespace { - -base::string16 ConvertPathToUTF16(const std::string& path) { - // Per RFC 2640, FTP servers should use UTF-8 or its proper subset ASCII, - // but many old FTP servers use legacy encodings. Try UTF-8 first. - if (IsStringUTF8(path)) - return UTF8ToUTF16(path); - - // Try detecting the encoding. The sample is rather small though, so it may - // fail. - std::string encoding; - if (base::DetectEncoding(path, &encoding) && !encoding.empty()) { - base::string16 path_utf16; - if (base::CodepageToUTF16(path, encoding.c_str(), - base::OnStringConversionError::SUBSTITUTE, - &path_utf16)) { - return path_utf16; - } - } - - // Use system native encoding as the last resort. - return WideToUTF16Hack(base::SysNativeMBToWide(path)); -} - -} // namespace - -namespace webkit_glue { - -FtpDirectoryListingResponseDelegate::FtpDirectoryListingResponseDelegate( - WebURLLoaderClient* client, - WebURLLoader* loader, - const WebURLResponse& response) - : client_(client), - loader_(loader) { - if (response.extraData()) { - // extraData can be NULL during tests. - WebURLResponseExtraDataImpl* extra_data = - static_cast(response.extraData()); - extra_data->set_is_ftp_directory_listing(true); - } - Init(response.url()); -} - -void FtpDirectoryListingResponseDelegate::OnReceivedData(const char* data, - int data_len) { - buffer_.append(data, data_len); -} - -void FtpDirectoryListingResponseDelegate::OnCompletedRequest() { - std::vector entries; - int rv = net::ParseFtpDirectoryListing(buffer_, base::Time::Now(), &entries); - if (rv != net::OK) { - SendDataToClient("\n"); - return; - } - for (size_t i = 0; i < entries.size(); i++) { - FtpDirectoryListingEntry entry = entries[i]; - - // Skip the current and parent directory entries in the listing. Our header - // always includes them. - if (EqualsASCII(entry.name, ".") || EqualsASCII(entry.name, "..")) - continue; - - bool is_directory = (entry.type == FtpDirectoryListingEntry::DIRECTORY); - int64 size = entry.size; - if (entry.type != FtpDirectoryListingEntry::FILE) - size = 0; - SendDataToClient(net::GetDirectoryListingEntry( - entry.name, entry.raw_name, is_directory, size, entry.last_modified)); - } -} - -void FtpDirectoryListingResponseDelegate::Init(const GURL& response_url) { - net::UnescapeRule::Type unescape_rules = net::UnescapeRule::SPACES | - net::UnescapeRule::URL_SPECIAL_CHARS; - std::string unescaped_path = net::UnescapeURLComponent(response_url.path(), - unescape_rules); - SendDataToClient(net::GetDirectoryListingHeader( - ConvertPathToUTF16(unescaped_path))); - - // If this isn't top level directory (i.e. the path isn't "/",) - // add a link to the parent directory. - if (response_url.path().length() > 1) { - SendDataToClient(net::GetDirectoryListingEntry( - ASCIIToUTF16(".."), std::string(), false, 0, base::Time())); - } -} - -void FtpDirectoryListingResponseDelegate::SendDataToClient( - const std::string& data) { - client_->didReceiveData(loader_, data.data(), data.length(), -1); -} - -} // namespace webkit_glue diff --git a/webkit/glue/ftp_directory_listing_response_delegate.h b/webkit/glue/ftp_directory_listing_response_delegate.h deleted file mode 100644 index 0562049..0000000 --- a/webkit/glue/ftp_directory_listing_response_delegate.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011 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. -// -// A delegate class of WebURLLoaderImpl that handles text/vnd.chromium.ftp-dir -// data. - -#ifndef WEBKIT_GLUE_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_ -#define WEBKIT_GLUE_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_ - -#include - -#include "base/basictypes.h" -#include "third_party/WebKit/public/platform/WebURLResponse.h" - -namespace WebKit { -class WebURLLoader; -class WebURLLoaderClient; -} - -class GURL; - -namespace webkit_glue { - -class FtpDirectoryListingResponseDelegate { - public: - FtpDirectoryListingResponseDelegate(WebKit::WebURLLoaderClient* client, - WebKit::WebURLLoader* loader, - const WebKit::WebURLResponse& response); - - // Passed through from ResourceHandleInternal - void OnReceivedData(const char* data, int data_len); - void OnCompletedRequest(); - - private: - void Init(const GURL& response_url); - - void SendDataToClient(const std::string& data); - - // Pointers to the client and associated loader so we can make callbacks as - // we parse pieces of data. - WebKit::WebURLLoaderClient* client_; - WebKit::WebURLLoader* loader_; - - // Buffer for data received from the network. - std::string buffer_; - - DISALLOW_COPY_AND_ASSIGN(FtpDirectoryListingResponseDelegate); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_FTP_DIRECTORY_LISTING_RESPONSE_DELEGATE_H_ diff --git a/webkit/glue/multipart_response_delegate.cc b/webkit/glue/multipart_response_delegate.cc deleted file mode 100644 index 325caf9..0000000 --- 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(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(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 diff --git a/webkit/glue/multipart_response_delegate.h b/webkit/glue/multipart_response_delegate.h deleted file mode 100644 index 6de1591..0000000 --- a/webkit/glue/multipart_response_delegate.h +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2011 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. -// -// A delegate class of WebURLLoaderImpl that handles multipart/x-mixed-replace -// data. We special case multipart/x-mixed-replace because WebCore expects a -// separate didReceiveResponse for each new message part. -// -// Most of the logic and edge case handling are based on the Mozilla's -// implementation in netwerk/streamconv/converters/nsMultiMixedConv.cpp. -// This seems like a derivative work, so here's the original license: - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef WEBKIT_GLUE_MULTIPART_RESPONSE_DELEGATE_H_ -#define WEBKIT_GLUE_MULTIPART_RESPONSE_DELEGATE_H_ - -#include - -#include "base/basictypes.h" -#include "third_party/WebKit/public/platform/WebURLResponse.h" -#include "webkit/common/webkit_common_export.h" - -namespace WebKit { -class WebURLLoader; -class WebURLLoaderClient; -} - -namespace webkit_glue { - -// Used by unit tests to access private members. -class MultipartResponseDelegateTester; - -class WEBKIT_COMMON_EXPORT MultipartResponseDelegate { - public: - MultipartResponseDelegate(WebKit::WebURLLoaderClient* client, - WebKit::WebURLLoader* loader, - const WebKit::WebURLResponse& response, - const std::string& boundary); - - // Passed through from ResourceHandleInternal - void OnReceivedData(const char* data, int data_len, int encoded_data_length); - void OnCompletedRequest(); - - // The request has been canceled, so stop making calls to the client. - void Cancel() { - client_ = NULL; - loader_ = NULL; - } - - // Returns the multi part boundary string from the Content-type header - // in the response. - // Returns true on success. - static bool ReadMultipartBoundary(const WebKit::WebURLResponse& response, - std::string* multipart_boundary); - - // Returns the lower and higher content ranges from an individual multipart - // in a multipart response. - // Returns true on success. - static bool ReadContentRanges( - const WebKit::WebURLResponse& response, - int64* content_range_lower_bound, - int64* content_range_upper_bound, - int64* content_range_instance_size); - - private: - friend class MultipartResponseDelegateTester; // For unittests. - - // Pointers to the client and associated loader so we can make callbacks as - // we parse pieces of data. - WebKit::WebURLLoaderClient* client_; - WebKit::WebURLLoader* loader_; - - // The original resource response for this request. We use this as a - // starting point for each parts response. - WebKit::WebURLResponse original_response_; - - // Checks to see if data[pos] character is a line break; handles crlf, lflf, - // lf, or cr. Returns the number of characters to skip over (0, 1 or 2). - int PushOverLine(const std::string& data, size_t pos); - - // Tries to parse http headers from the start of data_. Returns true if it - // succeeds and sends a didReceiveResponse to m_client. Returns false if - // the header is incomplete (in which case we just wait for more data). - bool ParseHeaders(); - - // Find the next boundary in data_. Returns std::string::npos if there's no - // full token. - size_t FindBoundary(); - - // Transferred data size accumulated between client callbacks. - int encoded_data_length_; - - // A temporary buffer to hold data between reads for multipart data that - // gets split in the middle of a header. - std::string data_; - - // Multipart boundary token - std::string boundary_; - - // true until we get our first on received data call - bool first_received_data_; - - // true if we're truncated in the middle of a header - bool processing_headers_; - - // true when we're done sending information. At that point, we stop - // processing AddData requests. - bool stop_sending_; - - // true after we've sent our first response to the WebURLLoaderClient. - bool has_sent_first_response_; - - DISALLOW_COPY_AND_ASSIGN(MultipartResponseDelegate); -}; - -} // namespace webkit_glue - -#endif diff --git a/webkit/glue/multipart_response_delegate_unittest.cc b/webkit/glue/multipart_response_delegate_unittest.cc deleted file mode 100644 index 8e43d85..0000000 --- a/webkit/glue/multipart_response_delegate_unittest.cc +++ /dev/null @@ -1,675 +0,0 @@ -// Copyright (c) 2011 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 - -#include "base/basictypes.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" -#include "third_party/WebKit/public/platform/WebURLResponse.h" -#include "webkit/glue/multipart_response_delegate.h" -#include "testing/gtest/include/gtest/gtest.h" - -using std::string; -using WebKit::WebString; -using WebKit::WebURL; -using WebKit::WebURLError; -using WebKit::WebURLLoader; -using WebKit::WebURLLoaderClient; -using WebKit::WebURLRequest; -using WebKit::WebURLResponse; -using webkit_glue::MultipartResponseDelegate; -using webkit_glue::MultipartResponseDelegateTester; - -namespace webkit_glue { - -class MultipartResponseDelegateTester { - public: - MultipartResponseDelegateTester(MultipartResponseDelegate* delegate) - : delegate_(delegate) { - } - - int PushOverLine(const std::string& data, size_t pos) { - return delegate_->PushOverLine(data, pos); - } - - bool ParseHeaders() { return delegate_->ParseHeaders(); } - size_t FindBoundary() { return delegate_->FindBoundary(); } - std::string& boundary() { return delegate_->boundary_; } - std::string& data() { return delegate_->data_; } - - private: - MultipartResponseDelegate* delegate_; -}; - -} // namespace webkit_glue - -namespace { - -class MultipartResponseTest : public testing::Test { -}; - -class MockWebURLLoaderClient : public WebURLLoaderClient { - public: - MockWebURLLoaderClient() { Reset(); } - - virtual void willSendRequest( - WebURLLoader*, WebURLRequest&, const WebURLResponse&) {} - virtual void didSendData( - WebURLLoader*, unsigned long long, unsigned long long) {} - - virtual void didReceiveResponse(WebURLLoader* loader, - const WebURLResponse& response) { - ++received_response_; - response_ = response; - data_.clear(); - } - virtual void didReceiveData( - WebKit::WebURLLoader* loader, - const char* data, - int data_length, - int encoded_data_length) { - ++received_data_; - data_.append(data, data_length); - total_encoded_data_length_ += encoded_data_length; - } - virtual void didFinishLoading(WebURLLoader*, double finishTime) {} - virtual void didFail(WebURLLoader*, const WebURLError&) {} - - void Reset() { - received_response_ = received_data_ = total_encoded_data_length_ = 0; - data_.clear(); - response_.reset(); - } - - string GetResponseHeader(const char* name) const { - return string(response_.httpHeaderField(WebString::fromUTF8(name)).utf8()); - } - - int received_response_, received_data_, total_encoded_data_length_; - string data_; - WebURLResponse response_; -}; - -// We can't put this in an anonymous function because it's a friend class for -// access to private members. -TEST(MultipartResponseTest, Functions) { - // PushOverLine tests - - WebURLResponse response; - response.initialize(); - response.setMIMEType("multipart/x-mixed-replace"); - response.setHTTPHeaderField("Foo", "Bar"); - response.setHTTPHeaderField("Content-type", "text/plain"); - MockWebURLLoaderClient client; - MultipartResponseDelegate delegate(&client, NULL, response, "bound"); - MultipartResponseDelegateTester delegate_tester(&delegate); - - struct { - const char* input; - const int position; - const int expected; - } line_tests[] = { - { "Line", 0, 0 }, - { "Line", 2, 0 }, - { "Line", 10, 0 }, - { "\r\nLine", 0, 2 }, - { "\nLine", 0, 1 }, - { "\n\nLine", 0, 2 }, - { "\rLine", 0, 1 }, - { "Line\r\nLine", 4, 2 }, - { "Line\nLine", 4, 1 }, - { "Line\n\nLine", 4, 2 }, - { "Line\rLine", 4, 1 }, - { "Line\r\rLine", 4, 1 }, - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(line_tests); ++i) { - EXPECT_EQ(line_tests[i].expected, - delegate_tester.PushOverLine(line_tests[i].input, - line_tests[i].position)); - } - - // ParseHeaders tests - struct { - const char* data; - const bool rv; - const int received_response_calls; - const char* newdata; - } header_tests[] = { - { "This is junk", false, 0, "This is junk" }, - { "Foo: bar\nBaz:\n\nAfter:\n", true, 1, "After:\n" }, - { "Foo: bar\nBaz:\n", false, 0, "Foo: bar\nBaz:\n" }, - { "Foo: bar\r\nBaz:\r\n\r\nAfter:\r\n", true, 1, "After:\r\n" }, - { "Foo: bar\r\nBaz:\r\n", false, 0, "Foo: bar\r\nBaz:\r\n" }, - { "Foo: bar\nBaz:\r\n\r\nAfter:\n\n", true, 1, "After:\n\n" }, - { "Foo: bar\r\nBaz:\n", false, 0, "Foo: bar\r\nBaz:\n" }, - { "\r\n", true, 1, "" }, - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(header_tests); ++i) { - client.Reset(); - delegate_tester.data().assign(header_tests[i].data); - EXPECT_EQ(header_tests[i].rv, - delegate_tester.ParseHeaders()); - EXPECT_EQ(header_tests[i].received_response_calls, - client.received_response_); - EXPECT_EQ(string(header_tests[i].newdata), - delegate_tester.data()); - } - // Test that the resource response is filled in correctly when parsing - // headers. - client.Reset(); - string test_header("content-type: image/png\ncontent-length: 10\n\n"); - delegate_tester.data().assign(test_header); - EXPECT_TRUE(delegate_tester.ParseHeaders()); - EXPECT_TRUE(delegate_tester.data().length() == 0); - EXPECT_EQ(string("image/png"), client.GetResponseHeader("Content-Type")); - EXPECT_EQ(string("10"), client.GetResponseHeader("content-length")); - // This header is passed from the original request. - EXPECT_EQ(string("Bar"), client.GetResponseHeader("foo")); - - // Make sure we parse the right mime-type if a charset is provided. - client.Reset(); - string test_header2("content-type: text/html; charset=utf-8\n\n"); - delegate_tester.data().assign(test_header2); - EXPECT_TRUE(delegate_tester.ParseHeaders()); - EXPECT_TRUE(delegate_tester.data().length() == 0); - EXPECT_EQ(string("text/html; charset=utf-8"), - client.GetResponseHeader("Content-Type")); - EXPECT_EQ(string("utf-8"), - string(client.response_.textEncodingName().utf8())); - - // FindBoundary tests - struct { - const char* boundary; - const char* data; - const size_t position; - } boundary_tests[] = { - { "bound", "bound", 0 }, - { "bound", "--bound", 0 }, - { "bound", "junkbound", 4 }, - { "bound", "junk--bound", 4 }, - { "foo", "bound", string::npos }, - { "bound", "--boundbound", 0 }, - }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(boundary_tests); ++i) { - delegate_tester.boundary().assign(boundary_tests[i].boundary); - delegate_tester.data().assign(boundary_tests[i].data); - EXPECT_EQ(boundary_tests[i].position, - delegate_tester.FindBoundary()); - } -} - -TEST(MultipartResponseTest, MissingBoundaries) { - WebURLResponse response; - response.initialize(); - response.setMIMEType("multipart/x-mixed-replace"); - response.setHTTPHeaderField("Foo", "Bar"); - response.setHTTPHeaderField("Content-type", "text/plain"); - MockWebURLLoaderClient client; - MultipartResponseDelegate delegate(&client, NULL, response, "bound"); - - // No start boundary - string no_start_boundary( - "Content-type: text/plain\n\n" - "This is a sample response\n" - "--bound--" - "ignore junk after end token --bound\n\nTest2\n"); - delegate.OnReceivedData(no_start_boundary.c_str(), - static_cast(no_start_boundary.length()), - static_cast(no_start_boundary.length())); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); - EXPECT_EQ(string("This is a sample response"), client.data_); - EXPECT_EQ(static_cast(no_start_boundary.length()), - client.total_encoded_data_length_); - - delegate.OnCompletedRequest(); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); - - // No end boundary - client.Reset(); - MultipartResponseDelegate delegate2(&client, NULL, response, "bound"); - string no_end_boundary( - "bound\nContent-type: text/plain\n\n" - "This is a sample response\n"); - delegate2.OnReceivedData(no_end_boundary.c_str(), - static_cast(no_end_boundary.length()), - static_cast(no_end_boundary.length())); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); - EXPECT_EQ("This is a sample response\n", client.data_); - EXPECT_EQ(static_cast(no_end_boundary.length()), - client.total_encoded_data_length_); - - delegate2.OnCompletedRequest(); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); - EXPECT_EQ(string("This is a sample response\n"), client.data_); - EXPECT_EQ(static_cast(no_end_boundary.length()), - client.total_encoded_data_length_); - - // Neither boundary - client.Reset(); - MultipartResponseDelegate delegate3(&client, NULL, response, "bound"); - string no_boundaries( - "Content-type: text/plain\n\n" - "This is a sample response\n"); - delegate3.OnReceivedData(no_boundaries.c_str(), - static_cast(no_boundaries.length()), - static_cast(no_boundaries.length())); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); - EXPECT_EQ("This is a sample response\n", client.data_); - EXPECT_EQ(static_cast(no_boundaries.length()), - client.total_encoded_data_length_); - - delegate3.OnCompletedRequest(); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); - EXPECT_EQ(string("This is a sample response\n"), client.data_); - EXPECT_EQ(static_cast(no_boundaries.length()), - client.total_encoded_data_length_); -} - -TEST(MultipartResponseTest, MalformedBoundary) { - // Some servers send a boundary that is prefixed by "--". See bug 5786. - - WebURLResponse response; - response.initialize(); - response.setMIMEType("multipart/x-mixed-replace"); - response.setHTTPHeaderField("Foo", "Bar"); - response.setHTTPHeaderField("Content-type", "text/plain"); - MockWebURLLoaderClient client; - MultipartResponseDelegate delegate(&client, NULL, response, "--bound"); - - string data( - "--bound\n" - "Content-type: text/plain\n\n" - "This is a sample response\n" - "--bound--" - "ignore junk after end token --bound\n\nTest2\n"); - delegate.OnReceivedData(data.c_str(), - static_cast(data.length()), - static_cast(data.length())); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); - EXPECT_EQ(string("This is a sample response"), client.data_); - EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); - - delegate.OnCompletedRequest(); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(1, client.received_data_); -} - - -// Used in for tests that break the data in various places. -struct TestChunk { - const int start_pos; // offset in data - const int end_pos; // end offset in data - const int expected_responses; - const int expected_received_data; - const char* expected_data; - const int expected_encoded_data_length; -}; - -void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size, - int responses, int received_data, - const char* completed_data, - int completed_encoded_data_length) { - const string data( - "--bound\n" // 0-7 - "Content-type: image/png\n\n" // 8-32 - "datadatadatadatadata" // 33-52 - "--bound\n" // 53-60 - "Content-type: image/jpg\n\n" // 61-85 - "foofoofoofoofoo" // 86-100 - "--bound--"); // 101-109 - - WebURLResponse response; - response.initialize(); - response.setMIMEType("multipart/x-mixed-replace"); - MockWebURLLoaderClient client; - MultipartResponseDelegate delegate(&client, NULL, response, "bound"); - - for (int i = 0; i < chunks_size; ++i) { - ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos); - string chunk = data.substr(chunks[i].start_pos, - chunks[i].end_pos - chunks[i].start_pos); - delegate.OnReceivedData( - chunk.c_str(), - static_cast(chunk.length()), - static_cast(chunk.length())); - EXPECT_EQ(chunks[i].expected_responses, client.received_response_); - EXPECT_EQ(chunks[i].expected_received_data, client.received_data_); - EXPECT_EQ(string(chunks[i].expected_data), client.data_); - EXPECT_EQ(chunks[i].expected_encoded_data_length, - client.total_encoded_data_length_); - } - // Check final state - delegate.OnCompletedRequest(); - EXPECT_EQ(responses, client.received_response_); - EXPECT_EQ(received_data, client.received_data_); - string completed_data_string(completed_data); - EXPECT_EQ(completed_data_string, client.data_); - EXPECT_EQ(completed_encoded_data_length, client.total_encoded_data_length_); -} - -TEST(MultipartResponseTest, BreakInBoundary) { - // Break in the first boundary - const TestChunk bound1[] = { - { 0, 4, 0, 0, "", 0 }, - { 4, 110, 2, 2, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(bound1, arraysize(bound1), - 2, 2, "foofoofoofoofoo", 110); - - // Break in first and second - const TestChunk bound2[] = { - { 0, 4, 0, 0, "", 0 }, - { 4, 55, 1, 1, "datadatadatadat", 55 }, - { 55, 65, 1, 2, "datadatadatadatadata", 65 }, - { 65, 110, 2, 3, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(bound2, arraysize(bound2), - 2, 3, "foofoofoofoofoo", 110); - - // Break in second only - const TestChunk bound3[] = { - { 0, 55, 1, 1, "datadatadatadat", 55 }, - { 55, 110, 2, 3, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(bound3, arraysize(bound3), - 2, 3, "foofoofoofoofoo", 110); -} - -TEST(MultipartResponseTest, BreakInHeaders) { - // Break in first header - const TestChunk header1[] = { - { 0, 10, 0, 0, "", 0 }, - { 10, 35, 1, 0, "", 0 }, - { 35, 110, 2, 2, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(header1, arraysize(header1), - 2, 2, "foofoofoofoofoo", 110); - - // Break in both headers - const TestChunk header2[] = { - { 0, 10, 0, 0, "", 0 }, - { 10, 65, 1, 1, "datadatadatadatadata", 65 }, - { 65, 110, 2, 2, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(header2, arraysize(header2), - 2, 2, "foofoofoofoofoo", 110); - - // Break at end of a header - const TestChunk header3[] = { - { 0, 33, 1, 0, "", 0 }, - { 33, 65, 1, 1, "datadatadatadatadata", 65 }, - { 65, 110, 2, 2, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(header3, arraysize(header3), - 2, 2, "foofoofoofoofoo", 110); -} - -TEST(MultipartResponseTest, BreakInData) { - // All data as one chunk - const TestChunk data1[] = { - { 0, 110, 2, 2, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(data1, arraysize(data1), - 2, 2, "foofoofoofoofoo", 110); - - // breaks in data segment - const TestChunk data2[] = { - { 0, 35, 1, 0, "", 0 }, - { 35, 65, 1, 1, "datadatadatadatadata", 65 }, - { 65, 90, 2, 1, "", 65 }, - { 90, 110, 2, 2, "foofoofoofoofoo", 110 }, - }; - VariousChunkSizesTest(data2, arraysize(data2), - 2, 2, "foofoofoofoofoo", 110); - - // Incomplete send - const TestChunk data3[] = { - { 0, 35, 1, 0, "", 0 }, - { 35, 90, 2, 1, "", 90 }, - }; - VariousChunkSizesTest(data3, arraysize(data3), - 2, 2, "foof", 90); -} - -TEST(MultipartResponseTest, SmallChunk) { - WebURLResponse response; - response.initialize(); - response.setMIMEType("multipart/x-mixed-replace"); - response.setHTTPHeaderField("Content-type", "text/plain"); - MockWebURLLoaderClient client; - MultipartResponseDelegate delegate(&client, NULL, response, "bound"); - - // Test chunks of size 1, 2, and 0. - string data( - "--boundContent-type: text/plain\n\n" - "\n--boundContent-type: text/plain\n\n" - "\n\n--boundContent-type: text/plain\n\n" - "--boundContent-type: text/plain\n\n" - "end--bound--"); - delegate.OnReceivedData(data.c_str(), - static_cast(data.length()), - static_cast(data.length())); - EXPECT_EQ(4, client.received_response_); - EXPECT_EQ(2, client.received_data_); - EXPECT_EQ(string("end"), client.data_); - EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); - - delegate.OnCompletedRequest(); - EXPECT_EQ(4, client.received_response_); - EXPECT_EQ(2, client.received_data_); -} - -TEST(MultipartResponseTest, MultipleBoundaries) { - // Test multiple boundaries back to back - WebURLResponse response; - response.initialize(); - response.setMIMEType("multipart/x-mixed-replace"); - MockWebURLLoaderClient client; - MultipartResponseDelegate delegate(&client, NULL, response, "bound"); - - string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--"); - delegate.OnReceivedData(data.c_str(), - static_cast(data.length()), - static_cast(data.length())); - EXPECT_EQ(2, client.received_response_); - EXPECT_EQ(1, client.received_data_); - EXPECT_EQ(string("foofoo"), client.data_); - EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); -} - -TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { - // Test multipart/byteranges based boundary parsing. - WebURLResponse response1; - response1.initialize(); - response1.setMIMEType("multipart/x-mixed-replace"); - response1.setHTTPHeaderField("Content-Length", "200"); - response1.setHTTPHeaderField("Content-type", - "multipart/byteranges; boundary=--bound--"); - - std::string multipart_boundary; - bool result = MultipartResponseDelegate::ReadMultipartBoundary( - response1, &multipart_boundary); - EXPECT_EQ(result, true); - EXPECT_EQ(string("--bound--"), - multipart_boundary); - - WebURLResponse response2; - response2.initialize(); - response2.setMIMEType("image/png"); - - response2.setHTTPHeaderField("Content-Length", "300"); - response2.setHTTPHeaderField("Last-Modified", - "Mon, 04 Apr 2005 20:36:01 GMT"); - response2.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT"); - - multipart_boundary.clear(); - result = MultipartResponseDelegate::ReadMultipartBoundary( - response2, &multipart_boundary); - EXPECT_EQ(result, false); - - WebURLResponse response3; - response3.initialize(); - response3.setMIMEType("multipart/byteranges"); - - response3.setHTTPHeaderField("Content-Length", "300"); - response3.setHTTPHeaderField("Last-Modified", - "Mon, 04 Apr 2005 20:36:01 GMT"); - response3.setHTTPHeaderField("Date", "Thu, 11 Sep 2008 18:21:42 GMT"); - response3.setHTTPHeaderField("Content-type", "multipart/byteranges"); - - multipart_boundary.clear(); - result = MultipartResponseDelegate::ReadMultipartBoundary( - response3, &multipart_boundary); - EXPECT_EQ(result, false); - EXPECT_EQ(multipart_boundary.length(), 0U); - - WebURLResponse response4; - response4.initialize(); - response4.setMIMEType("multipart/byteranges"); - response4.setHTTPHeaderField("Content-Length", "200"); - response4.setHTTPHeaderField("Content-type", - "multipart/byteranges; boundary=--bound--; charSet=utf8"); - - multipart_boundary.clear(); - - result = MultipartResponseDelegate::ReadMultipartBoundary( - response4, &multipart_boundary); - EXPECT_EQ(result, true); - EXPECT_EQ(string("--bound--"), multipart_boundary); - - WebURLResponse response5; - response5.initialize(); - response5.setMIMEType("multipart/byteranges"); - response5.setHTTPHeaderField("Content-Length", "200"); - response5.setHTTPHeaderField("Content-type", - "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8"); - - multipart_boundary.clear(); - - result = MultipartResponseDelegate::ReadMultipartBoundary( - response5, &multipart_boundary); - EXPECT_EQ(result, true); - EXPECT_EQ(string("--bound--"), multipart_boundary); -} - -TEST(MultipartResponseTest, MultipartContentRangesTest) { - WebURLResponse response1; - response1.initialize(); - response1.setMIMEType("application/pdf"); - response1.setHTTPHeaderField("Content-Length", "200"); // Ignored! - // Use intentionally >32bit values to check they are handled correctly. - response1.setHTTPHeaderField("Content-Range", - "bytes 5000000000-5000000050/6000000000"); - - int64 content_range_lower_bound = 0; - int64 content_range_upper_bound = 0; - int64 content_range_instance_size = 0; - - bool result = MultipartResponseDelegate::ReadContentRanges( - response1, &content_range_lower_bound, - &content_range_upper_bound, - &content_range_instance_size); - - EXPECT_EQ(result, true); - EXPECT_EQ(content_range_lower_bound, 5e9); - EXPECT_EQ(content_range_upper_bound, 5e9+50); - EXPECT_EQ(content_range_instance_size, 6e9); - - WebURLResponse response2; - response2.initialize(); - response2.setMIMEType("application/pdf"); - response2.setHTTPHeaderField("Content-Length", "200"); - response2.setHTTPHeaderField("Content-Range", "bytes 1000/1050"); - - content_range_lower_bound = 0; - content_range_upper_bound = 0; - content_range_instance_size = 0; - - result = MultipartResponseDelegate::ReadContentRanges( - response2, &content_range_lower_bound, - &content_range_upper_bound, - &content_range_instance_size); - - EXPECT_EQ(result, false); - - WebURLResponse response3; - response3.initialize(); - response3.setMIMEType("application/pdf"); - response3.setHTTPHeaderField("Content-Length", "200"); - response3.setHTTPHeaderField("Range", "bytes 1000-1050/5000"); - - content_range_lower_bound = 0; - content_range_upper_bound = 0; - content_range_instance_size = 0; - - result = MultipartResponseDelegate::ReadContentRanges( - response3, &content_range_lower_bound, - &content_range_upper_bound, - &content_range_instance_size); - - EXPECT_EQ(result, true); - EXPECT_EQ(content_range_lower_bound, 1000); - EXPECT_EQ(content_range_upper_bound, 1050); - - WebURLResponse response4; - response4.initialize(); - response4.setMIMEType("application/pdf"); - response4.setHTTPHeaderField("Content-Length", "200"); - - content_range_lower_bound = 0; - content_range_upper_bound = 0; - content_range_instance_size = 0; - - result = MultipartResponseDelegate::ReadContentRanges( - response4, &content_range_lower_bound, - &content_range_upper_bound, - &content_range_instance_size); - - EXPECT_EQ(result, false); -} - -TEST(MultipartResponseTest, MultipartPayloadSet) { - WebURLResponse response; - response.initialize(); - response.setMIMEType("multipart/x-mixed-replace"); - MockWebURLLoaderClient client; - MultipartResponseDelegate delegate(&client, NULL, response, "bound"); - - string data( - "--bound\n" - "Content-type: text/plain\n\n" - "response data\n" - "--bound\n"); - delegate.OnReceivedData(data.c_str(), - static_cast(data.length()), - static_cast(data.length())); - EXPECT_EQ(1, client.received_response_); - EXPECT_EQ(string("response data"), client.data_); - EXPECT_EQ(static_cast(data.length()), client.total_encoded_data_length_); - EXPECT_FALSE(client.response_.isMultipartPayload()); - - string data2( - "Content-type: text/plain\n\n" - "response data2\n" - "--bound\n"); - delegate.OnReceivedData(data2.c_str(), - static_cast(data2.length()), - static_cast(data2.length())); - EXPECT_EQ(2, client.received_response_); - EXPECT_EQ(string("response data2"), client.data_); - EXPECT_EQ(static_cast(data.length()) + static_cast(data2.length()), - client.total_encoded_data_length_); - EXPECT_TRUE(client.response_.isMultipartPayload()); -} - -} // namespace diff --git a/webkit/glue/resource_loader_bridge.cc b/webkit/glue/resource_loader_bridge.cc deleted file mode 100644 index 4d8eabe..0000000 --- a/webkit/glue/resource_loader_bridge.cc +++ /dev/null @@ -1,36 +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/resource_loader_bridge.h" - -#include "net/http/http_response_headers.h" -#include "webkit/common/appcache/appcache_interfaces.h" - -namespace webkit_glue { - -ResourceLoaderBridge::RequestInfo::RequestInfo() - : referrer_policy(WebKit::WebReferrerPolicyDefault), - load_flags(0), - requestor_pid(0), - request_type(ResourceType::MAIN_FRAME), - priority(net::LOW), - request_context(0), - appcache_host_id(0), - routing_id(0), - download_to_file(false), - has_user_gesture(false), - extra_data(NULL) { -} - -ResourceLoaderBridge::RequestInfo::~RequestInfo() {} - -ResourceLoaderBridge::SyncLoadResponse::SyncLoadResponse() {} - -ResourceLoaderBridge::SyncLoadResponse::~SyncLoadResponse() {} - -ResourceLoaderBridge::ResourceLoaderBridge() {} - -ResourceLoaderBridge::~ResourceLoaderBridge() {} - -} // namespace webkit_glue diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h deleted file mode 100644 index 3df3cc3..0000000 --- a/webkit/glue/resource_loader_bridge.h +++ /dev/null @@ -1,232 +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. -// -// The intent of this file is to provide a type-neutral abstraction between -// Chrome and WebKit for resource loading. This pure-virtual interface is -// implemented by the embedder. -// -// One of these objects will be created by WebKit for each request. WebKit -// will own the pointer to the bridge, and will delete it when the request is -// no longer needed. -// -// In turn, the bridge's owner on the WebKit end will implement the Peer -// interface, which we will use to communicate notifications back. - -#ifndef WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_ -#define WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_ - -#include - -#include "build/build_config.h" -#if defined(OS_POSIX) -#include "base/file_descriptor_posix.h" -#endif -#include "base/memory/ref_counted.h" -#include "base/platform_file.h" -#include "base/values.h" -#include "net/base/request_priority.h" -#include "third_party/WebKit/public/platform/WebReferrerPolicy.h" -#include "third_party/WebKit/public/platform/WebURLRequest.h" -#include "url/gurl.h" -#include "webkit/common/resource_response_info.h" -#include "webkit/glue/resource_type.h" -#include "webkit/glue/webkit_glue_export.h" - -namespace webkit_glue { -class ResourceRequestBody; - -class ResourceLoaderBridge { - public: - // Structure used when calling - // WebKitPlatformSupportImpl::CreateResourceLoader(). - struct WEBKIT_GLUE_EXPORT RequestInfo { - RequestInfo(); - ~RequestInfo(); - - // HTTP-style method name (e.g., "GET" or "POST"). - std::string method; - - // Absolute URL encoded in ASCII per the rules of RFC-2396. - GURL url; - - // URL of the document in the top-level window, which may be checked by the - // third-party cookie blocking policy. - GURL first_party_for_cookies; - - // Optional parameter, a URL with similar constraints in how it must be - // encoded as the url member. - GURL referrer; - - // The referrer policy that applies to the referrer. - WebKit::WebReferrerPolicy referrer_policy; - - // For HTTP(S) requests, the headers parameter can be a \r\n-delimited and - // \r\n-terminated list of MIME headers. They should be ASCII-encoded using - // the standard MIME header encoding rules. The headers parameter can also - // be null if no extra request headers need to be set. - std::string headers; - - // Composed of the values defined in url_request_load_flags.h. - int load_flags; - - // Process id of the process making the request. - int requestor_pid; - - // Indicates if the current request is the main frame load, a sub-frame - // load, or a sub objects load. - ResourceType::Type request_type; - - // Indicates the priority of this request, as determined by WebKit. - net::RequestPriority priority; - - // Used for plugin to browser requests. - uint32 request_context; - - // Identifies what appcache host this request is associated with. - int appcache_host_id; - - // Used to associated the bridge with a frame's network context. - int routing_id; - - // If true, then the response body will be downloaded to a file and the - // path to that file will be provided in ResponseInfo::download_file_path. - bool download_to_file; - - // True if the request was user initiated. - bool has_user_gesture; - - // Extra data associated with this request. We do not own this pointer. - WebKit::WebURLRequest::ExtraData* extra_data; - - private: - DISALLOW_COPY_AND_ASSIGN(RequestInfo); - }; - - // See the SyncLoad method declared below. (The name of this struct is not - // suffixed with "Info" because it also contains the response data.) - struct SyncLoadResponse : ResourceResponseInfo { - SyncLoadResponse(); - ~SyncLoadResponse(); - - // The response error code. - int error_code; - - // The final URL of the response. This may differ from the request URL in - // the case of a server redirect. - GURL url; - - // The response data. - std::string data; - }; - - // Generated by the bridge. This is implemented by our custom resource loader - // within webkit. The Peer and it's bridge should have identical lifetimes - // as they represent each end of a communication channel. - // - // These callbacks mirror net::URLRequest::Delegate and the order and - // conditions in which they will be called are identical. See url_request.h - // for more information. - class Peer { - public: - // Called as upload progress is made. - // note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set - virtual void OnUploadProgress(uint64 position, uint64 size) = 0; - - // Called when a redirect occurs. The implementation may return false to - // suppress the redirect. The given ResponseInfo provides complete - // information about the redirect, and new_url is the URL that will be - // loaded if this method returns true. If this method returns true, the - // output parameter *has_new_first_party_for_cookies indicates whether the - // output parameter *new_first_party_for_cookies contains the new URL that - // should be consulted for the third-party cookie blocking policy. - virtual bool OnReceivedRedirect(const GURL& new_url, - const ResourceResponseInfo& info, - bool* has_new_first_party_for_cookies, - GURL* new_first_party_for_cookies) = 0; - - // Called when response headers are available (after all redirects have - // been followed). - virtual void OnReceivedResponse(const ResourceResponseInfo& info) = 0; - - // Called when a chunk of response data is downloaded. This method may be - // called multiple times or not at all if an error occurs. This method is - // only called if RequestInfo::download_to_file was set to true, and in - // that case, OnReceivedData will not be called. - virtual void OnDownloadedData(int len) = 0; - - // Called when a chunk of response data is available. This method may - // be called multiple times or not at all if an error occurs. - // The encoded_data_length is the length of the encoded data transferred - // over the network, which could be different from data length (e.g. for - // gzipped content), or -1 if if unknown. - virtual void OnReceivedData(const char* data, - int data_length, - int encoded_data_length) = 0; - - // Called when metadata generated by the renderer is retrieved from the - // cache. This method may be called zero or one times. - virtual void OnReceivedCachedMetadata(const char* data, int len) { } - - // Called when the response is complete. This method signals completion of - // the resource load. - virtual void OnCompletedRequest( - int error_code, - bool was_ignored_by_handler, - const std::string& security_info, - const base::TimeTicks& completion_time) = 0; - - protected: - virtual ~Peer() {} - }; - - // use WebKitPlatformSupportImpl::CreateResourceLoader() for construction, but - // anybody can delete at any time, INCLUDING during processing of callbacks. - WEBKIT_GLUE_EXPORT virtual ~ResourceLoaderBridge(); - - // Call this method before calling Start() to set the request body. - // May only be used with HTTP(S) POST requests. - virtual void SetRequestBody(ResourceRequestBody* request_body) = 0; - - // Call this method to initiate the request. If this method succeeds, then - // the peer's methods will be called asynchronously to report various events. - virtual bool Start(Peer* peer) = 0; - - // Call this method to cancel a request that is in progress. This method - // causes the request to immediately transition into the 'done' state. The - // OnCompletedRequest method will be called asynchronously; this assumes - // the peer is still valid. - virtual void Cancel() = 0; - - // Call this method to suspend or resume a load that is in progress. This - // method may only be called after a successful call to the Start method. - virtual void SetDefersLoading(bool value) = 0; - - // Call this method when the priority of the requested resource changes after - // Start() has been called. This method may only be called after a successful - // call to the Start method. - virtual void DidChangePriority(net::RequestPriority new_priority) = 0; - - // Call this method to load the resource synchronously (i.e., in one shot). - // This is an alternative to the Start method. Be warned that this method - // will block the calling thread until the resource is fully downloaded or an - // error occurs. It could block the calling thread for a long time, so only - // use this if you really need it! There is also no way for the caller to - // interrupt this method. Errors are reported via the status field of the - // response parameter. - virtual void SyncLoad(SyncLoadResponse* response) = 0; - - protected: - // Construction must go through - // WebKitPlatformSupportImpl::CreateResourceLoader() - // For HTTP(S) POST requests, the AppendDataToUpload and AppendFileToUpload - // methods may be called to construct the body of the request. - WEBKIT_GLUE_EXPORT ResourceLoaderBridge(); - - private: - DISALLOW_COPY_AND_ASSIGN(ResourceLoaderBridge); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_ diff --git a/webkit/glue/resource_type.cc b/webkit/glue/resource_type.cc deleted file mode 100644 index e6df456..0000000 --- a/webkit/glue/resource_type.cc +++ /dev/null @@ -1,47 +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/resource_type.h" - -#include "base/logging.h" - -using WebKit::WebURLRequest; - -// static -ResourceType::Type ResourceType::FromTargetType( - WebURLRequest::TargetType type) { - switch (type) { - case WebURLRequest::TargetIsMainFrame: - return ResourceType::MAIN_FRAME; - case WebURLRequest::TargetIsSubframe: - return ResourceType::SUB_FRAME; - case WebURLRequest::TargetIsSubresource: - return ResourceType::SUB_RESOURCE; - case WebURLRequest::TargetIsStyleSheet: - return ResourceType::STYLESHEET; - case WebURLRequest::TargetIsScript: - return ResourceType::SCRIPT; - case WebURLRequest::TargetIsFontResource: - return ResourceType::FONT_RESOURCE; - case WebURLRequest::TargetIsImage: - return ResourceType::IMAGE; - case WebURLRequest::TargetIsObject: - return ResourceType::OBJECT; - case WebURLRequest::TargetIsMedia: - return ResourceType::MEDIA; - case WebURLRequest::TargetIsWorker: - return ResourceType::WORKER; - case WebURLRequest::TargetIsSharedWorker: - return ResourceType::SHARED_WORKER; - case WebURLRequest::TargetIsPrefetch: - return ResourceType::PREFETCH; - case WebURLRequest::TargetIsFavicon: - return ResourceType::FAVICON; - case WebURLRequest::TargetIsXHR: - return ResourceType::XHR; - default: - NOTREACHED(); - return ResourceType::SUB_RESOURCE; - } -} diff --git a/webkit/glue/resource_type.h b/webkit/glue/resource_type.h deleted file mode 100644 index f083806..0000000 --- a/webkit/glue/resource_type.h +++ /dev/null @@ -1,70 +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. - -#ifndef WEBKIT_GLUE_RESOURCE_TYPE_H__ -#define WEBKIT_GLUE_RESOURCE_TYPE_H__ - -#include "base/basictypes.h" -#include "third_party/WebKit/public/platform/WebURLRequest.h" -#include "webkit/glue/webkit_glue_export.h" - -class ResourceType { - public: - // Used in histograms, so please add new types at the end, and rename unused - // entries to RESOURCETYPE_UNUSED_0, etc... - enum Type { - MAIN_FRAME = 0, // top level page - SUB_FRAME, // frame or iframe - STYLESHEET, // a CSS stylesheet - SCRIPT, // an external script - IMAGE, // an image (jpg/gif/png/etc) - FONT_RESOURCE, // a font - SUB_RESOURCE, // an "other" subresource. - OBJECT, // an object (or embed) tag for a plugin, - // or a resource that a plugin requested. - MEDIA, // a media resource. - WORKER, // the main resource of a dedicated worker. - SHARED_WORKER, // the main resource of a shared worker. - PREFETCH, // an explicitly requested prefetch - FAVICON, // a favicon - XHR, // a XMLHttpRequest - LAST_TYPE // Place holder so we don't need to change ValidType - // everytime. - }; - - static bool ValidType(int32 type) { - return type >= MAIN_FRAME && type < LAST_TYPE; - } - - static Type FromInt(int32 type) { - return static_cast(type); - } - - WEBKIT_GLUE_EXPORT static Type FromTargetType( - WebKit::WebURLRequest::TargetType type); - - static bool IsFrame(ResourceType::Type type) { - return type == MAIN_FRAME || type == SUB_FRAME; - } - - static bool IsSharedWorker(ResourceType::Type type) { - return type == SHARED_WORKER; - } - - static bool IsSubresource(ResourceType::Type type) { - return type == STYLESHEET || - type == SCRIPT || - type == IMAGE || - type == FONT_RESOURCE || - type == SUB_RESOURCE || - type == WORKER || - type == XHR; - } - - private: - // Don't instantiate this class. - ResourceType(); - ~ResourceType(); -}; -#endif // WEBKIT_GLUE_RESOURCE_TYPE_H__ diff --git a/webkit/glue/webkit_glue.cc b/webkit/glue/webkit_glue.cc index 2ef0e57..4c832f3 100644 --- a/webkit/glue/webkit_glue.cc +++ b/webkit/glue/webkit_glue.cc @@ -89,39 +89,4 @@ int GetGlyphPageCount() { COMPILE_ASSERT(std::numeric_limits::has_quiet_NaN, has_quiet_NaN); -#if defined(OS_LINUX) || defined(OS_ANDROID) -size_t MemoryUsageKB() { - struct mallinfo minfo = mallinfo(); - uint64_t mem_usage = -#if defined(USE_TCMALLOC) - minfo.uordblks -#else - (minfo.hblkhd + minfo.arena) -#endif - >> 10; - - v8::HeapStatistics stat; - // TODO(svenpanne) The call below doesn't take web workers into account, this - // has to be done manually by iterating over all Isolates involved. - v8::Isolate::GetCurrent()->GetHeapStatistics(&stat); - return mem_usage + (static_cast(stat.total_heap_size()) >> 10); -} -#elif defined(OS_MACOSX) -size_t MemoryUsageKB() { - scoped_ptr process_metrics( - // The default port provider is sufficient to get data for the current - // process. - base::ProcessMetrics::CreateProcessMetrics( - base::GetCurrentProcessHandle(), NULL)); - return process_metrics->GetWorkingSetSize() >> 10; -} -#else -size_t MemoryUsageKB() { - scoped_ptr process_metrics( - base::ProcessMetrics::CreateProcessMetrics( - base::GetCurrentProcessHandle())); - return process_metrics->GetPagefileUsage() >> 10; -} -#endif - } // namespace webkit_glue diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index a12d4c6..347fe30 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -19,26 +19,38 @@ ], 'dependencies': [ '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/base/base.gyp:base_i18n', + '<(DEPTH)/base/base.gyp:base_static', '<(DEPTH)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '<(DEPTH)/net/net.gyp:net', '<(DEPTH)/skia/skia.gyp:skia', '<(DEPTH)/third_party/WebKit/public/blink.gyp:blink', '<(DEPTH)/ui/native_theme/native_theme.gyp:native_theme', '<(DEPTH)/ui/ui.gyp:ui', - - # TODO(scottmg): crbug.com/237249 - 'glue', + '<(DEPTH)/url/url.gyp:url_lib', + '<(DEPTH)/v8/tools/gyp/v8.gyp:v8', + '<(DEPTH)/webkit/common/user_agent/webkit_user_agent.gyp:user_agent', + '<(DEPTH)/webkit/common/webkit_common.gyp:webkit_common', + '<(DEPTH)/webkit/plugins/webkit_plugins.gyp:plugins_common', ], 'include_dirs': [ # For JNI generated header. '<(SHARED_INTERMEDIATE_DIR)/webkit', ], + 'hard_dependency': 1, 'sources': [ '../child/fling_animator_impl_android.cc', '../child/fling_animator_impl_android.h', '../child/fling_curve_configuration.cc', '../child/fling_curve_configuration.h', + '../child/ftp_directory_listing_response_delegate.cc', + '../child/ftp_directory_listing_response_delegate.h', + '../child/multipart_response_delegate.cc', + '../child/multipart_response_delegate.h', + '../child/resource_loader_bridge.cc', + '../child/resource_loader_bridge.h', '../child/touch_fling_gesture_curve.cc', '../child/touch_fling_gesture_curve.h', '../child/web_discardable_memory_impl.cc', @@ -46,8 +58,15 @@ '../child/webfallbackthemeengine_impl.cc', '../child/webfallbackthemeengine_impl.h', '../child/webkit_child_export.h', + '../child/webkit_child_helpers.cc', + '../child/webkit_child_helpers.h', '../child/webkitplatformsupport_child_impl.cc', '../child/webkitplatformsupport_child_impl.h', + '../child/webkitplatformsupport_impl.cc', + '../child/webkitplatformsupport_impl.h', + '../child/websocketstreamhandle_delegate.h', + '../child/websocketstreamhandle_impl.cc', + '../child/websocketstreamhandle_impl.h', '../child/webthemeengine_impl_android.cc', '../child/webthemeengine_impl_android.h', '../child/webthemeengine_impl_default.cc', @@ -58,6 +77,12 @@ '../child/webthemeengine_impl_win.h', '../child/webthread_impl.cc', '../child/webthread_impl.h', + '../child/weburlloader_impl.cc', + '../child/weburlloader_impl.h', + '../child/weburlrequest_extradata_impl.cc', + '../child/weburlrequest_extradata_impl.h', + '../child/weburlresponse_extradata_impl.cc', + '../child/weburlresponse_extradata_impl.h', '../child/worker_task_runner.cc', '../child/worker_task_runner.h', ], @@ -129,13 +154,7 @@ '<(SHARED_INTERMEDIATE_DIR)/ui', ], 'sources': [ - 'ftp_directory_listing_response_delegate.cc', - 'ftp_directory_listing_response_delegate.h', 'network_list_observer.h', - 'resource_loader_bridge.cc', - 'resource_loader_bridge.h', - 'resource_type.cc', - 'resource_type.h', 'simple_webmimeregistry_impl.cc', 'simple_webmimeregistry_impl.h', 'webfileutilities_impl.cc', @@ -143,14 +162,7 @@ 'webkit_glue.cc', 'webkit_glue.h', 'webkit_glue_export.h', - 'webkitplatformsupport_impl.cc', - 'webkitplatformsupport_impl.h', 'websocketstreamhandle_bridge.h', - 'websocketstreamhandle_delegate.h', - 'websocketstreamhandle_impl.cc', - 'websocketstreamhandle_impl.h', - 'weburlloader_impl.cc', - 'weburlloader_impl.h', ], # When glue is a dependency, it needs to be a hard dependency. # Dependents may rely on files generated by this target or one of its diff --git a/webkit/glue/webkit_glue.h b/webkit/glue/webkit_glue.h index 2a9d74d..33fed9f 100644 --- a/webkit/glue/webkit_glue.h +++ b/webkit/glue/webkit_glue.h @@ -46,12 +46,6 @@ WEBKIT_GLUE_EXPORT WebKit::WebCanvas* ToWebCanvas(SkCanvas*); // used to get memory usage statistics. WEBKIT_GLUE_EXPORT int GetGlyphPageCount(); -// Returns an estimate of the memory usage of the renderer process. Different -// platforms implement this function differently, and count in different -// allocations. Results are not comparable across platforms. The estimate is -// computed inside the sandbox and thus its not always accurate. -WEBKIT_GLUE_EXPORT size_t MemoryUsageKB(); - } // namespace webkit_glue #endif // WEBKIT_GLUE_WEBKIT_GLUE_H_ diff --git a/webkit/glue/webkit_glue_common.gyp b/webkit/glue/webkit_glue_common.gyp index ff845ef..51f152e 100644 --- a/webkit/glue/webkit_glue_common.gyp +++ b/webkit/glue/webkit_glue_common.gyp @@ -26,12 +26,6 @@ '../common/webkit_common_export.h', '../common/webpreferences.cc', '../common/webpreferences.h', - 'multipart_response_delegate.cc', - 'multipart_response_delegate.h', - 'weburlrequest_extradata_impl.cc', - 'weburlrequest_extradata_impl.h', - 'weburlresponse_extradata_impl.cc', - 'weburlresponse_extradata_impl.h', ], 'conditions': [ ['toolkit_uses_gtk == 1', { diff --git a/webkit/glue/webkit_glue_unittest.cc b/webkit/glue/webkit_glue_unittest.cc index 27879e8..50b57ab 100644 --- a/webkit/glue/webkit_glue_unittest.cc +++ b/webkit/glue/webkit_glue_unittest.cc @@ -9,7 +9,7 @@ #include "base/message_loop/message_loop.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webkit/glue/webkitplatformsupport_impl.h" +#include "webkit/child/webkitplatformsupport_impl.h" namespace { diff --git a/webkit/glue/webkitplatformsupport_impl.cc b/webkit/glue/webkitplatformsupport_impl.cc deleted file mode 100644 index e592058..0000000 --- a/webkit/glue/webkitplatformsupport_impl.cc +++ /dev/null @@ -1,901 +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/webkitplatformsupport_impl.h" - -#include - -#include - -#include "base/allocator/allocator_extension.h" -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/singleton.h" -#include "base/message_loop/message_loop.h" -#include "base/metrics/histogram.h" -#include "base/metrics/sparse_histogram.h" -#include "base/metrics/stats_counters.h" -#include "base/platform_file.h" -#include "base/process_util.h" -#include "base/rand_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/synchronization/lock.h" -#include "base/sys_info.h" -#include "base/time/time.h" -#include "grit/webkit_chromium_resources.h" -#include "grit/webkit_resources.h" -#include "grit/webkit_strings.h" -#include "net/base/data_url.h" -#include "net/base/mime_util.h" -#include "net/base/net_errors.h" -#include "third_party/WebKit/public/platform/WebCookie.h" -#include "third_party/WebKit/public/platform/WebData.h" -#include "third_party/WebKit/public/platform/WebDiscardableMemory.h" -#include "third_party/WebKit/public/platform/WebGestureCurve.h" -#include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/web/WebFrameClient.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" -#include "third_party/WebKit/public/web/WebScreenInfo.h" -#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" -#include "ui/base/layout.h" -#include "webkit/common/user_agent/user_agent.h" -#include "webkit/glue/webkit_glue.h" -#include "webkit/glue/websocketstreamhandle_impl.h" -#include "webkit/glue/weburlloader_impl.h" - -using WebKit::WebAudioBus; -using WebKit::WebCookie; -using WebKit::WebData; -using WebKit::WebLocalizedString; -using WebKit::WebPluginListBuilder; -using WebKit::WebString; -using WebKit::WebSocketStreamHandle; -using WebKit::WebURL; -using WebKit::WebURLError; -using WebKit::WebURLLoader; -using WebKit::WebVector; - -namespace { - -// A simple class to cache the memory usage for a given amount of time. -class MemoryUsageCache { - public: - // Retrieves the Singleton. - static MemoryUsageCache* GetInstance() { - return Singleton::get(); - } - - MemoryUsageCache() : memory_value_(0) { Init(); } - ~MemoryUsageCache() {} - - void Init() { - const unsigned int kCacheSeconds = 1; - cache_valid_time_ = base::TimeDelta::FromSeconds(kCacheSeconds); - } - - // Returns true if the cached value is fresh. - // Returns false if the cached value is stale, or if |cached_value| is NULL. - bool IsCachedValueValid(size_t* cached_value) { - base::AutoLock scoped_lock(lock_); - if (!cached_value) - return false; - if (base::Time::Now() - last_updated_time_ > cache_valid_time_) - return false; - *cached_value = memory_value_; - return true; - }; - - // Setter for |memory_value_|, refreshes |last_updated_time_|. - void SetMemoryValue(const size_t value) { - base::AutoLock scoped_lock(lock_); - memory_value_ = value; - last_updated_time_ = base::Time::Now(); - } - - private: - // The cached memory value. - size_t memory_value_; - - // How long the cached value should remain valid. - base::TimeDelta cache_valid_time_; - - // The last time the cached value was updated. - base::Time last_updated_time_; - - base::Lock lock_; -}; - -} // anonymous namespace - -namespace webkit_glue { - -static int ToMessageID(WebLocalizedString::Name name) { - switch (name) { - case WebLocalizedString::AXAMPMFieldText: - return IDS_AX_AM_PM_FIELD_TEXT; - case WebLocalizedString::AXButtonActionVerb: - return IDS_AX_BUTTON_ACTION_VERB; - case WebLocalizedString::AXCheckedCheckBoxActionVerb: - return IDS_AX_CHECKED_CHECK_BOX_ACTION_VERB; - case WebLocalizedString::AXDateTimeFieldEmptyValueText: - return IDS_AX_DATE_TIME_FIELD_EMPTY_VALUE_TEXT; - case WebLocalizedString::AXDayOfMonthFieldText: - return IDS_AX_DAY_OF_MONTH_FIELD_TEXT; - case WebLocalizedString::AXHeadingText: - return IDS_AX_ROLE_HEADING; - case WebLocalizedString::AXHourFieldText: - return IDS_AX_HOUR_FIELD_TEXT; - case WebLocalizedString::AXImageMapText: - return IDS_AX_ROLE_IMAGE_MAP; - case WebLocalizedString::AXLinkActionVerb: - return IDS_AX_LINK_ACTION_VERB; - case WebLocalizedString::AXLinkText: - return IDS_AX_ROLE_LINK; - case WebLocalizedString::AXListMarkerText: - return IDS_AX_ROLE_LIST_MARKER; - case WebLocalizedString::AXMediaDefault: - return IDS_AX_MEDIA_DEFAULT; - case WebLocalizedString::AXMediaAudioElement: - return IDS_AX_MEDIA_AUDIO_ELEMENT; - case WebLocalizedString::AXMediaVideoElement: - return IDS_AX_MEDIA_VIDEO_ELEMENT; - case WebLocalizedString::AXMediaMuteButton: - return IDS_AX_MEDIA_MUTE_BUTTON; - case WebLocalizedString::AXMediaUnMuteButton: - return IDS_AX_MEDIA_UNMUTE_BUTTON; - case WebLocalizedString::AXMediaPlayButton: - return IDS_AX_MEDIA_PLAY_BUTTON; - case WebLocalizedString::AXMediaPauseButton: - return IDS_AX_MEDIA_PAUSE_BUTTON; - case WebLocalizedString::AXMediaSlider: - return IDS_AX_MEDIA_SLIDER; - case WebLocalizedString::AXMediaSliderThumb: - return IDS_AX_MEDIA_SLIDER_THUMB; - case WebLocalizedString::AXMediaRewindButton: - return IDS_AX_MEDIA_REWIND_BUTTON; - case WebLocalizedString::AXMediaReturnToRealTime: - return IDS_AX_MEDIA_RETURN_TO_REALTIME_BUTTON; - case WebLocalizedString::AXMediaCurrentTimeDisplay: - return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY; - case WebLocalizedString::AXMediaTimeRemainingDisplay: - return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY; - case WebLocalizedString::AXMediaStatusDisplay: - return IDS_AX_MEDIA_STATUS_DISPLAY; - case WebLocalizedString::AXMediaEnterFullscreenButton: - return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON; - case WebLocalizedString::AXMediaExitFullscreenButton: - return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON; - case WebLocalizedString::AXMediaSeekForwardButton: - return IDS_AX_MEDIA_SEEK_FORWARD_BUTTON; - case WebLocalizedString::AXMediaSeekBackButton: - return IDS_AX_MEDIA_SEEK_BACK_BUTTON; - case WebLocalizedString::AXMediaShowClosedCaptionsButton: - return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON; - case WebLocalizedString::AXMediaHideClosedCaptionsButton: - return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON; - case WebLocalizedString::AXMediaAudioElementHelp: - return IDS_AX_MEDIA_AUDIO_ELEMENT_HELP; - case WebLocalizedString::AXMediaVideoElementHelp: - return IDS_AX_MEDIA_VIDEO_ELEMENT_HELP; - case WebLocalizedString::AXMediaMuteButtonHelp: - return IDS_AX_MEDIA_MUTE_BUTTON_HELP; - case WebLocalizedString::AXMediaUnMuteButtonHelp: - return IDS_AX_MEDIA_UNMUTE_BUTTON_HELP; - case WebLocalizedString::AXMediaPlayButtonHelp: - return IDS_AX_MEDIA_PLAY_BUTTON_HELP; - case WebLocalizedString::AXMediaPauseButtonHelp: - return IDS_AX_MEDIA_PAUSE_BUTTON_HELP; - case WebLocalizedString::AXMediaSliderHelp: - return IDS_AX_MEDIA_SLIDER_HELP; - case WebLocalizedString::AXMediaSliderThumbHelp: - return IDS_AX_MEDIA_SLIDER_THUMB_HELP; - case WebLocalizedString::AXMediaRewindButtonHelp: - return IDS_AX_MEDIA_REWIND_BUTTON_HELP; - case WebLocalizedString::AXMediaReturnToRealTimeHelp: - return IDS_AX_MEDIA_RETURN_TO_REALTIME_BUTTON_HELP; - case WebLocalizedString::AXMediaCurrentTimeDisplayHelp: - return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP; - case WebLocalizedString::AXMediaTimeRemainingDisplayHelp: - return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY_HELP; - case WebLocalizedString::AXMediaStatusDisplayHelp: - return IDS_AX_MEDIA_STATUS_DISPLAY_HELP; - case WebLocalizedString::AXMediaEnterFullscreenButtonHelp: - return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP; - case WebLocalizedString::AXMediaExitFullscreenButtonHelp: - return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP; - case WebLocalizedString::AXMediaSeekForwardButtonHelp: - return IDS_AX_MEDIA_SEEK_FORWARD_BUTTON_HELP; - case WebLocalizedString::AXMediaSeekBackButtonHelp: - return IDS_AX_MEDIA_SEEK_BACK_BUTTON_HELP; - case WebLocalizedString::AXMediaShowClosedCaptionsButtonHelp: - return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP; - case WebLocalizedString::AXMediaHideClosedCaptionsButtonHelp: - return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON_HELP; - case WebLocalizedString::AXMillisecondFieldText: - return IDS_AX_MILLISECOND_FIELD_TEXT; - case WebLocalizedString::AXMinuteFieldText: - return IDS_AX_MINUTE_FIELD_TEXT; - case WebLocalizedString::AXMonthFieldText: - return IDS_AX_MONTH_FIELD_TEXT; - case WebLocalizedString::AXRadioButtonActionVerb: - return IDS_AX_RADIO_BUTTON_ACTION_VERB; - case WebLocalizedString::AXSecondFieldText: - return IDS_AX_SECOND_FIELD_TEXT; - case WebLocalizedString::AXTextFieldActionVerb: - return IDS_AX_TEXT_FIELD_ACTION_VERB; - case WebLocalizedString::AXUncheckedCheckBoxActionVerb: - return IDS_AX_UNCHECKED_CHECK_BOX_ACTION_VERB; - case WebLocalizedString::AXWebAreaText: - return IDS_AX_ROLE_WEB_AREA; - case WebLocalizedString::AXWeekOfYearFieldText: - return IDS_AX_WEEK_OF_YEAR_FIELD_TEXT; - case WebLocalizedString::AXYearFieldText: - return IDS_AX_YEAR_FIELD_TEXT; - case WebLocalizedString::CalendarClear: - return IDS_FORM_CALENDAR_CLEAR; - case WebLocalizedString::CalendarToday: - return IDS_FORM_CALENDAR_TODAY; - case WebLocalizedString::DateFormatDayInMonthLabel: - return IDS_FORM_DATE_FORMAT_DAY_IN_MONTH; - case WebLocalizedString::DateFormatMonthLabel: - return IDS_FORM_DATE_FORMAT_MONTH; - case WebLocalizedString::DateFormatYearLabel: - return IDS_FORM_DATE_FORMAT_YEAR; - case WebLocalizedString::DetailsLabel: - return IDS_DETAILS_WITHOUT_SUMMARY_LABEL; - case WebLocalizedString::FileButtonChooseFileLabel: - return IDS_FORM_FILE_BUTTON_LABEL; - case WebLocalizedString::FileButtonChooseMultipleFilesLabel: - return IDS_FORM_MULTIPLE_FILES_BUTTON_LABEL; - case WebLocalizedString::FileButtonNoFileSelectedLabel: - return IDS_FORM_FILE_NO_FILE_LABEL; - case WebLocalizedString::InputElementAltText: - return IDS_FORM_INPUT_ALT; - case WebLocalizedString::KeygenMenuHighGradeKeySize: - return IDS_KEYGEN_HIGH_GRADE_KEY; - case WebLocalizedString::KeygenMenuMediumGradeKeySize: - return IDS_KEYGEN_MED_GRADE_KEY; - case WebLocalizedString::MissingPluginText: - return IDS_PLUGIN_INITIALIZATION_ERROR; - case WebLocalizedString::MultipleFileUploadText: - return IDS_FORM_FILE_MULTIPLE_UPLOAD; - case WebLocalizedString::OtherColorLabel: - return IDS_FORM_OTHER_COLOR_LABEL; - case WebLocalizedString::OtherDateLabel: - return IDS_FORM_OTHER_DATE_LABEL; - case WebLocalizedString::OtherMonthLabel: - return IDS_FORM_OTHER_MONTH_LABEL; - case WebLocalizedString::OtherTimeLabel: - return IDS_FORM_OTHER_TIME_LABEL; - case WebLocalizedString::OtherWeekLabel: - return IDS_FORM_OTHER_WEEK_LABEL; - case WebLocalizedString::PlaceholderForDayOfMonthField: - return IDS_FORM_PLACEHOLDER_FOR_DAY_OF_MONTH_FIELD; - case WebLocalizedString::PlaceholderForMonthField: - return IDS_FORM_PLACEHOLDER_FOR_MONTH_FIELD; - case WebLocalizedString::PlaceholderForYearField: - return IDS_FORM_PLACEHOLDER_FOR_YEAR_FIELD; - case WebLocalizedString::ResetButtonDefaultLabel: - return IDS_FORM_RESET_LABEL; - case WebLocalizedString::SearchableIndexIntroduction: - return IDS_SEARCHABLE_INDEX_INTRO; - case WebLocalizedString::SearchMenuClearRecentSearchesText: - return IDS_RECENT_SEARCHES_CLEAR; - case WebLocalizedString::SearchMenuNoRecentSearchesText: - return IDS_RECENT_SEARCHES_NONE; - case WebLocalizedString::SearchMenuRecentSearchesText: - return IDS_RECENT_SEARCHES; - case WebLocalizedString::SubmitButtonDefaultLabel: - return IDS_FORM_SUBMIT_LABEL; - case WebLocalizedString::ThisMonthButtonLabel: - return IDS_FORM_THIS_MONTH_LABEL; - case WebLocalizedString::ThisWeekButtonLabel: - return IDS_FORM_THIS_WEEK_LABEL; - case WebLocalizedString::ValidationBadInputForDateTime: - return IDS_FORM_VALIDATION_BAD_INPUT_DATETIME; - case WebLocalizedString::ValidationBadInputForNumber: - return IDS_FORM_VALIDATION_BAD_INPUT_NUMBER; - case WebLocalizedString::ValidationPatternMismatch: - return IDS_FORM_VALIDATION_PATTERN_MISMATCH; - case WebLocalizedString::ValidationRangeOverflow: - return IDS_FORM_VALIDATION_RANGE_OVERFLOW; - case WebLocalizedString::ValidationRangeUnderflow: - return IDS_FORM_VALIDATION_RANGE_UNDERFLOW; - case WebLocalizedString::ValidationStepMismatch: - return IDS_FORM_VALIDATION_STEP_MISMATCH; - case WebLocalizedString::ValidationTooLong: - return IDS_FORM_VALIDATION_TOO_LONG; - case WebLocalizedString::ValidationTypeMismatch: - return IDS_FORM_VALIDATION_TYPE_MISMATCH; - case WebLocalizedString::ValidationTypeMismatchForEmail: - return IDS_FORM_VALIDATION_TYPE_MISMATCH_EMAIL; - case WebLocalizedString::ValidationTypeMismatchForMultipleEmail: - return IDS_FORM_VALIDATION_TYPE_MISMATCH_MULTIPLE_EMAIL; - case WebLocalizedString::ValidationTypeMismatchForURL: - return IDS_FORM_VALIDATION_TYPE_MISMATCH_URL; - case WebLocalizedString::ValidationValueMissing: - return IDS_FORM_VALIDATION_VALUE_MISSING; - case WebLocalizedString::ValidationValueMissingForCheckbox: - return IDS_FORM_VALIDATION_VALUE_MISSING_CHECKBOX; - case WebLocalizedString::ValidationValueMissingForFile: - return IDS_FORM_VALIDATION_VALUE_MISSING_FILE; - case WebLocalizedString::ValidationValueMissingForMultipleFile: - return IDS_FORM_VALIDATION_VALUE_MISSING_MULTIPLE_FILE; - case WebLocalizedString::ValidationValueMissingForRadio: - return IDS_FORM_VALIDATION_VALUE_MISSING_RADIO; - case WebLocalizedString::ValidationValueMissingForSelect: - return IDS_FORM_VALIDATION_VALUE_MISSING_SELECT; - case WebLocalizedString::WeekFormatTemplate: - return IDS_FORM_INPUT_WEEK_TEMPLATE; - case WebLocalizedString::WeekNumberLabel: - return IDS_FORM_WEEK_NUMBER_LABEL; - // This "default:" line exists to avoid compile warnings about enum - // coverage when we add a new symbol to WebLocalizedString.h in WebKit. - // After a planned WebKit patch is landed, we need to add a case statement - // for the added symbol here. - default: - break; - } - return -1; -} - -WebKitPlatformSupportImpl::WebKitPlatformSupportImpl() - : main_loop_(base::MessageLoop::current()), - shared_timer_func_(NULL), - shared_timer_fire_time_(0.0), - shared_timer_fire_time_was_set_while_suspended_(false), - shared_timer_suspended_(0) {} - -WebKitPlatformSupportImpl::~WebKitPlatformSupportImpl() { -} - -WebURLLoader* WebKitPlatformSupportImpl::createURLLoader() { - return new WebURLLoaderImpl(this); -} - -WebSocketStreamHandle* WebKitPlatformSupportImpl::createSocketStreamHandle() { - return new WebSocketStreamHandleImpl(this); -} - -WebString WebKitPlatformSupportImpl::userAgent(const WebURL& url) { - return WebString::fromUTF8(webkit_glue::GetUserAgent(url)); -} - -WebData WebKitPlatformSupportImpl::parseDataURL( - const WebURL& url, - WebString& mimetype_out, - WebString& charset_out) { - std::string mime_type, char_set, data; - if (net::DataURL::Parse(url, &mime_type, &char_set, &data) - && net::IsSupportedMimeType(mime_type)) { - mimetype_out = WebString::fromUTF8(mime_type); - charset_out = WebString::fromUTF8(char_set); - return data; - } - return WebData(); -} - -WebURLError WebKitPlatformSupportImpl::cancelledError( - const WebURL& unreachableURL) const { - return WebURLLoaderImpl::CreateError(unreachableURL, net::ERR_ABORTED); -} - -void WebKitPlatformSupportImpl::decrementStatsCounter(const char* name) { - base::StatsCounter(name).Decrement(); -} - -void WebKitPlatformSupportImpl::incrementStatsCounter(const char* name) { - base::StatsCounter(name).Increment(); -} - -void WebKitPlatformSupportImpl::histogramCustomCounts( - const char* name, int sample, int min, int max, int bucket_count) { - // Copied from histogram macro, but without the static variable caching - // the histogram because name is dynamic. - base::HistogramBase* counter = - base::Histogram::FactoryGet(name, min, max, bucket_count, - base::HistogramBase::kUmaTargetedHistogramFlag); - DCHECK_EQ(name, counter->histogram_name()); - counter->Add(sample); -} - -void WebKitPlatformSupportImpl::histogramEnumeration( - const char* name, int sample, int boundary_value) { - // Copied from histogram macro, but without the static variable caching - // the histogram because name is dynamic. - base::HistogramBase* counter = - base::LinearHistogram::FactoryGet(name, 1, boundary_value, - boundary_value + 1, base::HistogramBase::kUmaTargetedHistogramFlag); - DCHECK_EQ(name, counter->histogram_name()); - counter->Add(sample); -} - -void WebKitPlatformSupportImpl::histogramSparse(const char* name, int sample) { - // For sparse histograms, we can use the macro, as it does not incorporate a - // static. - UMA_HISTOGRAM_SPARSE_SLOWLY(name, sample); -} - -const unsigned char* WebKitPlatformSupportImpl::getTraceCategoryEnabledFlag( - const char* category_group) { - return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); -} - -long* WebKitPlatformSupportImpl::getTraceSamplingState( - const unsigned thread_bucket) { - switch (thread_bucket) { - case 0: - return reinterpret_cast(&TRACE_EVENT_API_THREAD_BUCKET(0)); - case 1: - return reinterpret_cast(&TRACE_EVENT_API_THREAD_BUCKET(1)); - case 2: - return reinterpret_cast(&TRACE_EVENT_API_THREAD_BUCKET(2)); - default: - NOTREACHED() << "Unknown thread bucket type."; - } - return NULL; -} - -void WebKitPlatformSupportImpl::addTraceEvent( - char phase, - const unsigned char* category_group_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - unsigned char flags) { - TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name, id, - num_args, arg_names, arg_types, - arg_values, NULL, flags); -} - - -namespace { - -WebData loadAudioSpatializationResource(WebKitPlatformSupportImpl* platform, - const char* name) { -#ifdef IDR_AUDIO_SPATIALIZATION_COMPOSITE - if (!strcmp(name, "Composite")) { - base::StringPiece resource = - platform->GetDataResource(IDR_AUDIO_SPATIALIZATION_COMPOSITE, - ui::SCALE_FACTOR_NONE); - return WebData(resource.data(), resource.size()); - } -#endif - -#ifdef IDR_AUDIO_SPATIALIZATION_T000_P000 - const size_t kExpectedSpatializationNameLength = 31; - if (strlen(name) != kExpectedSpatializationNameLength) { - return WebData(); - } - - // Extract the azimuth and elevation from the resource name. - int azimuth = 0; - int elevation = 0; - int values_parsed = - sscanf(name, "IRC_Composite_C_R0195_T%3d_P%3d", &azimuth, &elevation); - if (values_parsed != 2) { - return WebData(); - } - - // The resource index values go through the elevations first, then azimuths. - const int kAngleSpacing = 15; - - // 0 <= elevation <= 90 (or 315 <= elevation <= 345) - // in increments of 15 degrees. - int elevation_index = - elevation <= 90 ? elevation / kAngleSpacing : - 7 + (elevation - 315) / kAngleSpacing; - bool is_elevation_index_good = 0 <= elevation_index && elevation_index < 10; - - // 0 <= azimuth < 360 in increments of 15 degrees. - int azimuth_index = azimuth / kAngleSpacing; - bool is_azimuth_index_good = 0 <= azimuth_index && azimuth_index < 24; - - const int kNumberOfElevations = 10; - const int kNumberOfAudioResources = 240; - int resource_index = kNumberOfElevations * azimuth_index + elevation_index; - bool is_resource_index_good = 0 <= resource_index && - resource_index < kNumberOfAudioResources; - - if (is_azimuth_index_good && is_elevation_index_good && - is_resource_index_good) { - const int kFirstAudioResourceIndex = IDR_AUDIO_SPATIALIZATION_T000_P000; - base::StringPiece resource = - platform->GetDataResource(kFirstAudioResourceIndex + resource_index, - ui::SCALE_FACTOR_NONE); - return WebData(resource.data(), resource.size()); - } -#endif // IDR_AUDIO_SPATIALIZATION_T000_P000 - - NOTREACHED(); - return WebData(); -} - -struct DataResource { - const char* name; - int id; - ui::ScaleFactor scale_factor; -}; - -const DataResource kDataResources[] = { - { "missingImage", IDR_BROKENIMAGE, ui::SCALE_FACTOR_100P }, - { "missingImage@2x", IDR_BROKENIMAGE, ui::SCALE_FACTOR_200P }, - { "mediaplayerPause", IDR_MEDIAPLAYER_PAUSE_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerPauseHover", - IDR_MEDIAPLAYER_PAUSE_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerPauseDown", - IDR_MEDIAPLAYER_PAUSE_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerPlay", IDR_MEDIAPLAYER_PLAY_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerPlayHover", - IDR_MEDIAPLAYER_PLAY_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerPlayDown", - IDR_MEDIAPLAYER_PLAY_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerPlayDisabled", - IDR_MEDIAPLAYER_PLAY_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel3", - IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel3Hover", - IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel3Down", - IDR_MEDIAPLAYER_SOUND_LEVEL3_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel2", - IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel2Hover", - IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel2Down", - IDR_MEDIAPLAYER_SOUND_LEVEL2_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel1", - IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel1Hover", - IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel1Down", - IDR_MEDIAPLAYER_SOUND_LEVEL1_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel0", - IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel0Hover", - IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundLevel0Down", - IDR_MEDIAPLAYER_SOUND_LEVEL0_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerSoundDisabled", - IDR_MEDIAPLAYER_SOUND_DISABLED, ui::SCALE_FACTOR_100P }, - { "mediaplayerSliderThumb", - IDR_MEDIAPLAYER_SLIDER_THUMB, ui::SCALE_FACTOR_100P }, - { "mediaplayerSliderThumbHover", - IDR_MEDIAPLAYER_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerSliderThumbDown", - IDR_MEDIAPLAYER_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerVolumeSliderThumb", - IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB, ui::SCALE_FACTOR_100P }, - { "mediaplayerVolumeSliderThumbHover", - IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerVolumeSliderThumbDown", - IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerVolumeSliderThumbDisabled", - IDR_MEDIAPLAYER_VOLUME_SLIDER_THUMB_DISABLED, ui::SCALE_FACTOR_100P }, - { "mediaplayerClosedCaption", - IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerClosedCaptionHover", - IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerClosedCaptionDown", - IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerClosedCaptionDisabled", - IDR_MEDIAPLAYER_CLOSEDCAPTION_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, - { "mediaplayerFullscreen", - IDR_MEDIAPLAYER_FULLSCREEN_BUTTON, ui::SCALE_FACTOR_100P }, - { "mediaplayerFullscreenHover", - IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_HOVER, ui::SCALE_FACTOR_100P }, - { "mediaplayerFullscreenDown", - IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DOWN, ui::SCALE_FACTOR_100P }, - { "mediaplayerFullscreenDisabled", - IDR_MEDIAPLAYER_FULLSCREEN_BUTTON_DISABLED, ui::SCALE_FACTOR_100P }, -#if defined(OS_ANDROID) - { "mediaplayerOverlayPlay", - IDR_MEDIAPLAYER_OVERLAY_PLAY_BUTTON, ui::SCALE_FACTOR_100P }, -#endif -#if defined(OS_MACOSX) - { "overhangPattern", IDR_OVERHANG_PATTERN, ui::SCALE_FACTOR_100P }, -#endif - { "panIcon", IDR_PAN_SCROLL_ICON, ui::SCALE_FACTOR_100P }, - { "searchCancel", IDR_SEARCH_CANCEL, ui::SCALE_FACTOR_100P }, - { "searchCancelPressed", IDR_SEARCH_CANCEL_PRESSED, ui::SCALE_FACTOR_100P }, - { "searchMagnifier", IDR_SEARCH_MAGNIFIER, ui::SCALE_FACTOR_100P }, - { "searchMagnifierResults", - IDR_SEARCH_MAGNIFIER_RESULTS, ui::SCALE_FACTOR_100P }, - { "textAreaResizeCorner", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_100P }, - { "textAreaResizeCorner@2x", IDR_TEXTAREA_RESIZER, ui::SCALE_FACTOR_200P }, - { "inputSpeech", IDR_INPUT_SPEECH, ui::SCALE_FACTOR_100P }, - { "inputSpeechRecording", IDR_INPUT_SPEECH_RECORDING, ui::SCALE_FACTOR_100P }, - { "inputSpeechWaiting", IDR_INPUT_SPEECH_WAITING, ui::SCALE_FACTOR_100P }, - { "americanExpressCC", IDR_AUTOFILL_CC_AMEX, ui::SCALE_FACTOR_100P }, - { "dinersCC", IDR_AUTOFILL_CC_DINERS, ui::SCALE_FACTOR_100P }, - { "discoverCC", IDR_AUTOFILL_CC_DISCOVER, ui::SCALE_FACTOR_100P }, - { "genericCC", IDR_AUTOFILL_CC_GENERIC, ui::SCALE_FACTOR_100P }, - { "jcbCC", IDR_AUTOFILL_CC_JCB, ui::SCALE_FACTOR_100P }, - { "masterCardCC", IDR_AUTOFILL_CC_MASTERCARD, ui::SCALE_FACTOR_100P }, - { "visaCC", IDR_AUTOFILL_CC_VISA, ui::SCALE_FACTOR_100P }, - { "generatePassword", IDR_PASSWORD_GENERATION_ICON, ui::SCALE_FACTOR_100P }, - { "generatePasswordHover", - IDR_PASSWORD_GENERATION_ICON_HOVER, ui::SCALE_FACTOR_100P }, - { "syntheticTouchCursor", - IDR_SYNTHETIC_TOUCH_CURSOR, ui::SCALE_FACTOR_100P }, -}; - -} // namespace - -WebData WebKitPlatformSupportImpl::loadResource(const char* name) { - // Some clients will call into this method with an empty |name| when they have - // optional resources. For example, the PopupMenuChromium code can have icons - // for some Autofill items but not for others. - if (!strlen(name)) - return WebData(); - - // Check the name prefix to see if it's an audio resource. - if (StartsWithASCII(name, "IRC_Composite", true) || - StartsWithASCII(name, "Composite", true)) - return loadAudioSpatializationResource(this, name); - - // TODO(flackr): We should use a better than linear search here, a trie would - // be ideal. - for (size_t i = 0; i < arraysize(kDataResources); ++i) { - if (!strcmp(name, kDataResources[i].name)) { - base::StringPiece resource = - GetDataResource(kDataResources[i].id, - kDataResources[i].scale_factor); - return WebData(resource.data(), resource.size()); - } - } - - NOTREACHED() << "Unknown image resource " << name; - return WebData(); -} - -WebString WebKitPlatformSupportImpl::queryLocalizedString( - WebLocalizedString::Name name) { - int message_id = ToMessageID(name); - if (message_id < 0) - return WebString(); - return GetLocalizedString(message_id); -} - -WebString WebKitPlatformSupportImpl::queryLocalizedString( - WebLocalizedString::Name name, int numeric_value) { - return queryLocalizedString(name, base::IntToString16(numeric_value)); -} - -WebString WebKitPlatformSupportImpl::queryLocalizedString( - WebLocalizedString::Name name, const WebString& value) { - int message_id = ToMessageID(name); - if (message_id < 0) - return WebString(); - return ReplaceStringPlaceholders(GetLocalizedString(message_id), value, NULL); -} - -WebString WebKitPlatformSupportImpl::queryLocalizedString( - WebLocalizedString::Name name, - const WebString& value1, - const WebString& value2) { - int message_id = ToMessageID(name); - if (message_id < 0) - return WebString(); - std::vector values; - values.reserve(2); - values.push_back(value1); - values.push_back(value2); - return ReplaceStringPlaceholders( - GetLocalizedString(message_id), values, NULL); -} - -double WebKitPlatformSupportImpl::currentTime() { - return base::Time::Now().ToDoubleT(); -} - -double WebKitPlatformSupportImpl::monotonicallyIncreasingTime() { - return base::TimeTicks::Now().ToInternalValue() / - static_cast(base::Time::kMicrosecondsPerSecond); -} - -void WebKitPlatformSupportImpl::cryptographicallyRandomValues( - unsigned char* buffer, size_t length) { - base::RandBytes(buffer, length); -} - -void WebKitPlatformSupportImpl::setSharedTimerFiredFunction(void (*func)()) { - shared_timer_func_ = func; -} - -void WebKitPlatformSupportImpl::setSharedTimerFireInterval( - double interval_seconds) { - shared_timer_fire_time_ = interval_seconds + monotonicallyIncreasingTime(); - if (shared_timer_suspended_) { - shared_timer_fire_time_was_set_while_suspended_ = true; - return; - } - - // By converting between double and int64 representation, we run the risk - // of losing precision due to rounding errors. Performing computations in - // microseconds reduces this risk somewhat. But there still is the potential - // of us computing a fire time for the timer that is shorter than what we - // need. - // As the event loop will check event deadlines prior to actually firing - // them, there is a risk of needlessly rescheduling events and of - // needlessly looping if sleep times are too short even by small amounts. - // This results in measurable performance degradation unless we use ceil() to - // always round up the sleep times. - int64 interval = static_cast( - ceil(interval_seconds * base::Time::kMillisecondsPerSecond) - * base::Time::kMicrosecondsPerMillisecond); - - if (interval < 0) - interval = 0; - - shared_timer_.Stop(); - shared_timer_.Start(FROM_HERE, base::TimeDelta::FromMicroseconds(interval), - this, &WebKitPlatformSupportImpl::DoTimeout); - OnStartSharedTimer(base::TimeDelta::FromMicroseconds(interval)); -} - -void WebKitPlatformSupportImpl::stopSharedTimer() { - shared_timer_.Stop(); -} - -void WebKitPlatformSupportImpl::callOnMainThread( - void (*func)(void*), void* context) { - main_loop_->PostTask(FROM_HERE, base::Bind(func, context)); -} - -base::PlatformFile WebKitPlatformSupportImpl::databaseOpenFile( - const WebKit::WebString& vfs_file_name, int desired_flags) { - return base::kInvalidPlatformFileValue; -} - -int WebKitPlatformSupportImpl::databaseDeleteFile( - const WebKit::WebString& vfs_file_name, bool sync_dir) { - return -1; -} - -long WebKitPlatformSupportImpl::databaseGetFileAttributes( - const WebKit::WebString& vfs_file_name) { - return 0; -} - -long long WebKitPlatformSupportImpl::databaseGetFileSize( - const WebKit::WebString& vfs_file_name) { - return 0; -} - -long long WebKitPlatformSupportImpl::databaseGetSpaceAvailableForOrigin( - const WebKit::WebString& origin_identifier) { - return 0; -} - -WebKit::WebString WebKitPlatformSupportImpl::signedPublicKeyAndChallengeString( - unsigned key_size_index, - const WebKit::WebString& challenge, - const WebKit::WebURL& url) { - return WebKit::WebString(""); -} - -static scoped_ptr CurrentProcessMetrics() { - using base::ProcessMetrics; -#if defined(OS_MACOSX) - return scoped_ptr( - // The default port provider is sufficient to get data for the current - // process. - ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle(), - NULL)); -#else - return scoped_ptr( - ProcessMetrics::CreateProcessMetrics(base::GetCurrentProcessHandle())); -#endif -} - -static size_t getMemoryUsageMB(bool bypass_cache) { - size_t current_mem_usage = 0; - MemoryUsageCache* mem_usage_cache_singleton = MemoryUsageCache::GetInstance(); - if (!bypass_cache && - mem_usage_cache_singleton->IsCachedValueValid(¤t_mem_usage)) - return current_mem_usage; - - current_mem_usage = MemoryUsageKB() >> 10; - mem_usage_cache_singleton->SetMemoryValue(current_mem_usage); - return current_mem_usage; -} - -size_t WebKitPlatformSupportImpl::memoryUsageMB() { - return getMemoryUsageMB(false); -} - -size_t WebKitPlatformSupportImpl::actualMemoryUsageMB() { - return getMemoryUsageMB(true); -} - -#if defined(OS_ANDROID) -size_t WebKitPlatformSupportImpl::lowMemoryUsageMB() { - // If memory usage is below this threshold, do not bother forcing GC. - // Allow us to use up to our memory class value before V8's GC kicks in. - // These values have been determined by experimentation. - return base::SysInfo::DalvikHeapSizeMB() / 2; -} - -size_t WebKitPlatformSupportImpl::highMemoryUsageMB() { - // If memory usage is above this threshold, force GC more aggressively. - return base::SysInfo::DalvikHeapSizeMB() * 3 / 4; -} - -size_t WebKitPlatformSupportImpl::highUsageDeltaMB() { - // If memory usage is above highMemoryUsageMB() and memory usage increased by - // more than highUsageDeltaMB() since the last GC, then force GC. - // Note that this limit should be greater than the amount of memory for V8 - // internal data structures that are released on GC and reallocated during JS - // execution (about 8MB). Otherwise, it will cause too aggressive GCs. - return base::SysInfo::DalvikHeapSizeMB() / 8; -} -#endif - -void WebKitPlatformSupportImpl::startHeapProfiling( - const WebKit::WebString& prefix) { - // FIXME(morrita): Make this built on windows. -#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) - HeapProfilerStart(prefix.utf8().data()); -#endif -} - -void WebKitPlatformSupportImpl::stopHeapProfiling() { -#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) - HeapProfilerStop(); -#endif -} - -void WebKitPlatformSupportImpl::dumpHeapProfiling( - const WebKit::WebString& reason) { -#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) - HeapProfilerDump(reason.utf8().data()); -#endif -} - -WebString WebKitPlatformSupportImpl::getHeapProfile() { -#if !defined(NO_TCMALLOC) && defined(USE_TCMALLOC) && !defined(OS_WIN) - char* data = GetHeapProfile(); - WebString result = WebString::fromUTF8(std::string(data)); - free(data); - return result; -#else - return WebString(); -#endif -} - -bool WebKitPlatformSupportImpl::processMemorySizesInBytes( - size_t* private_bytes, - size_t* shared_bytes) { - return CurrentProcessMetrics()->GetMemoryBytes(private_bytes, shared_bytes); -} - -bool WebKitPlatformSupportImpl::memoryAllocatorWasteInBytes(size_t* size) { - return base::allocator::GetAllocatorWasteSize(size); -} - -void WebKitPlatformSupportImpl::SuspendSharedTimer() { - ++shared_timer_suspended_; -} - -void WebKitPlatformSupportImpl::ResumeSharedTimer() { - // The shared timer may have fired or been adjusted while we were suspended. - if (--shared_timer_suspended_ == 0 && - (!shared_timer_.IsRunning() || - shared_timer_fire_time_was_set_while_suspended_)) { - shared_timer_fire_time_was_set_while_suspended_ = false; - setSharedTimerFireInterval( - shared_timer_fire_time_ - monotonicallyIncreasingTime()); - } -} - -} // namespace webkit_glue diff --git a/webkit/glue/webkitplatformsupport_impl.h b/webkit/glue/webkitplatformsupport_impl.h deleted file mode 100644 index 68fcb2a..0000000 --- a/webkit/glue/webkitplatformsupport_impl.h +++ /dev/null @@ -1,155 +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. - -#ifndef WEBKIT_PLATFORM_SUPPORT_IMPL_H_ -#define WEBKIT_PLATFORM_SUPPORT_IMPL_H_ - -#include "base/compiler_specific.h" -#include "base/debug/trace_event.h" -#include "base/platform_file.h" -#include "base/timer/timer.h" -#include "third_party/WebKit/public/platform/Platform.h" -#include "third_party/WebKit/public/platform/WebURLError.h" -#include "ui/base/layout.h" -#include "webkit/glue/resource_loader_bridge.h" -#include "webkit/glue/webkit_glue_export.h" - -namespace base { -class MessageLoop; -} - -namespace WebKit { -class WebSocketStreamHandle; -} - -namespace webkit_glue { - -class WebSocketStreamHandleDelegate; -class WebSocketStreamHandleBridge; - -class WEBKIT_GLUE_EXPORT WebKitPlatformSupportImpl : - NON_EXPORTED_BASE(public WebKit::Platform) { - public: - WebKitPlatformSupportImpl(); - virtual ~WebKitPlatformSupportImpl(); - - // Platform methods (partial implementation): - virtual base::PlatformFile databaseOpenFile( - const WebKit::WebString& vfs_file_name, int desired_flags); - virtual int databaseDeleteFile(const WebKit::WebString& vfs_file_name, - bool sync_dir); - virtual long databaseGetFileAttributes( - const WebKit::WebString& vfs_file_name); - virtual long long databaseGetFileSize(const WebKit::WebString& vfs_file_name); - virtual long long databaseGetSpaceAvailableForOrigin( - const WebKit::WebString& origin_identifier); - virtual WebKit::WebString signedPublicKeyAndChallengeString( - unsigned key_size_index, const WebKit::WebString& challenge, - const WebKit::WebURL& url); - virtual size_t memoryUsageMB(); - virtual size_t actualMemoryUsageMB(); -#if defined(OS_ANDROID) // Other OSes just use the default values. - // TODO(jochen): Remove these. - virtual size_t lowMemoryUsageMB(); - virtual size_t highMemoryUsageMB(); - virtual size_t highUsageDeltaMB(); -#endif - - virtual void startHeapProfiling(const WebKit::WebString& prefix); - virtual void stopHeapProfiling() OVERRIDE; - virtual void dumpHeapProfiling(const WebKit::WebString& reason); - virtual WebKit::WebString getHeapProfile() OVERRIDE; - - virtual bool processMemorySizesInBytes(size_t* private_bytes, - size_t* shared_bytes); - virtual bool memoryAllocatorWasteInBytes(size_t* size); - virtual WebKit::WebURLLoader* createURLLoader(); - virtual WebKit::WebSocketStreamHandle* createSocketStreamHandle(); - virtual WebKit::WebString userAgent(const WebKit::WebURL& url); - virtual WebKit::WebData parseDataURL( - const WebKit::WebURL& url, WebKit::WebString& mimetype, - WebKit::WebString& charset); - virtual WebKit::WebURLError cancelledError(const WebKit::WebURL& url) const; - virtual void decrementStatsCounter(const char* name); - virtual void incrementStatsCounter(const char* name); - virtual void histogramCustomCounts( - const char* name, int sample, int min, int max, int bucket_count); - virtual void histogramEnumeration( - const char* name, int sample, int boundary_value); - virtual void histogramSparse(const char* name, int sample); - virtual const unsigned char* getTraceCategoryEnabledFlag( - const char* category_name); - virtual long* getTraceSamplingState(const unsigned thread_bucket); - virtual void addTraceEvent( - char phase, - const unsigned char* category_group_enabled, - const char* name, - unsigned long long id, - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, - unsigned char flags); - virtual WebKit::WebData loadResource(const char* name); - virtual WebKit::WebString queryLocalizedString( - WebKit::WebLocalizedString::Name name); - virtual WebKit::WebString queryLocalizedString( - WebKit::WebLocalizedString::Name name, int numeric_value); - virtual WebKit::WebString queryLocalizedString( - WebKit::WebLocalizedString::Name name, const WebKit::WebString& value); - virtual WebKit::WebString queryLocalizedString( - WebKit::WebLocalizedString::Name name, - const WebKit::WebString& value1, const WebKit::WebString& value2); - virtual void suddenTerminationChanged(bool enabled) { } - virtual double currentTime(); - virtual double monotonicallyIncreasingTime(); - virtual void cryptographicallyRandomValues( - unsigned char* buffer, size_t length); - virtual void setSharedTimerFiredFunction(void (*func)()); - virtual void setSharedTimerFireInterval(double interval_seconds); - virtual void stopSharedTimer(); - virtual void callOnMainThread(void (*func)(void*), void* context); - - - // Embedder functions. The following are not implemented by the glue layer and - // need to be specialized by the embedder. - - // Gets a localized string given a message id. Returns an empty string if the - // message id is not found. - virtual base::string16 GetLocalizedString(int message_id) = 0; - - // Returns the raw data for a resource. This resource must have been - // specified as BINDATA in the relevant .rc file. - virtual base::StringPiece GetDataResource(int resource_id, - ui::ScaleFactor scale_factor) = 0; - - // Creates a ResourceLoaderBridge. - virtual ResourceLoaderBridge* CreateResourceLoader( - const ResourceLoaderBridge::RequestInfo& request_info) = 0; - // Creates a WebSocketStreamHandleBridge. - virtual WebSocketStreamHandleBridge* CreateWebSocketBridge( - WebKit::WebSocketStreamHandle* handle, - WebSocketStreamHandleDelegate* delegate) = 0; - - void SuspendSharedTimer(); - void ResumeSharedTimer(); - virtual void OnStartSharedTimer(base::TimeDelta delay) {} - - private: - void DoTimeout() { - if (shared_timer_func_ && !shared_timer_suspended_) - shared_timer_func_(); - } - - base::MessageLoop* main_loop_; - base::OneShotTimer shared_timer_; - void (*shared_timer_func_)(); - double shared_timer_fire_time_; - bool shared_timer_fire_time_was_set_while_suspended_; - int shared_timer_suspended_; // counter -}; - -} // namespace webkit_glue - -#endif // WEBKIT_PLATFORM_SUPPORT_IMPL_H_ diff --git a/webkit/glue/websocketstreamhandle_delegate.h b/webkit/glue/websocketstreamhandle_delegate.h deleted file mode 100644 index 2d02329..0000000 --- a/webkit/glue/websocketstreamhandle_delegate.h +++ /dev/null @@ -1,44 +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. - -#ifndef WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ -#define WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ - -#include "base/strings/string16.h" - -class GURL; - -namespace WebKit { -class WebSocketStreamHandle; -} - -namespace webkit_glue { - -class WebSocketStreamHandleDelegate { - public: - WebSocketStreamHandleDelegate() {} - - virtual void WillOpenStream(WebKit::WebSocketStreamHandle* handle, - const GURL& url) {} - virtual void WillSendData(WebKit::WebSocketStreamHandle* handle, - const char* data, int len) {} - - virtual void DidOpenStream(WebKit::WebSocketStreamHandle* handle, - int max_amount_send_allowed) {} - virtual void DidSendData(WebKit::WebSocketStreamHandle* handle, - int amount_sent) {} - virtual void DidReceiveData(WebKit::WebSocketStreamHandle* handle, - const char* data, int len) {} - virtual void DidClose(WebKit::WebSocketStreamHandle*) {} - virtual void DidFail(WebKit::WebSocketStreamHandle* handle, - int error_code, - const string16& error_msg) {} - - protected: - virtual ~WebSocketStreamHandleDelegate() {} -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ diff --git a/webkit/glue/websocketstreamhandle_impl.cc b/webkit/glue/websocketstreamhandle_impl.cc deleted file mode 100644 index 7736dd5..0000000 --- a/webkit/glue/websocketstreamhandle_impl.cc +++ /dev/null @@ -1,196 +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. - -// An implementation of WebSocketStreamHandle. - -#include "webkit/glue/websocketstreamhandle_impl.h" - -#include - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/string16.h" -#include "third_party/WebKit/public/platform/WebData.h" -#include "third_party/WebKit/public/platform/WebSocketStreamError.h" -#include "third_party/WebKit/public/platform/WebSocketStreamHandleClient.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "webkit/glue/webkitplatformsupport_impl.h" -#include "webkit/glue/websocketstreamhandle_bridge.h" -#include "webkit/glue/websocketstreamhandle_delegate.h" - -using WebKit::WebData; -using WebKit::WebSocketStreamError; -using WebKit::WebSocketStreamHandle; -using WebKit::WebSocketStreamHandleClient; -using WebKit::WebURL; - -namespace webkit_glue { - -// WebSocketStreamHandleImpl::Context ----------------------------------------- - -class WebSocketStreamHandleImpl::Context - : public base::RefCounted, - public WebSocketStreamHandleDelegate { - public: - explicit Context(WebSocketStreamHandleImpl* handle); - - WebSocketStreamHandleClient* client() const { return client_; } - void set_client(WebSocketStreamHandleClient* client) { - client_ = client; - } - - void Connect(const WebURL& url, WebKitPlatformSupportImpl* platform); - bool Send(const WebData& data); - void Close(); - - // Must be called before |handle_| or |client_| is deleted. - // Once detached, it never calls |client_| back. - void Detach(); - - // WebSocketStreamHandleDelegate methods: - virtual void DidOpenStream(WebSocketStreamHandle*, int) OVERRIDE; - virtual void DidSendData(WebSocketStreamHandle*, int) OVERRIDE; - virtual void DidReceiveData(WebSocketStreamHandle*, - const char*, - int) OVERRIDE; - virtual void DidClose(WebSocketStreamHandle*) OVERRIDE; - virtual void DidFail(WebSocketStreamHandle*, int, const string16&) OVERRIDE; - - private: - friend class base::RefCounted; - virtual ~Context() { - DCHECK(!handle_); - DCHECK(!client_); - DCHECK(!bridge_.get()); - } - - WebSocketStreamHandleImpl* handle_; - WebSocketStreamHandleClient* client_; - // |bridge_| is alive from Connect to DidClose, so Context must be alive - // in the time period. - scoped_refptr bridge_; - - DISALLOW_COPY_AND_ASSIGN(Context); -}; - -WebSocketStreamHandleImpl::Context::Context(WebSocketStreamHandleImpl* handle) - : handle_(handle), - client_(NULL), - bridge_(NULL) { -} - -void WebSocketStreamHandleImpl::Context::Connect( - const WebURL& url, - WebKitPlatformSupportImpl* platform) { - VLOG(1) << "Connect url=" << url; - DCHECK(!bridge_.get()); - bridge_ = platform->CreateWebSocketBridge(handle_, this); - AddRef(); // Will be released by DidClose(). - bridge_->Connect(url); -} - -bool WebSocketStreamHandleImpl::Context::Send(const WebData& data) { - VLOG(1) << "Send data.size=" << data.size(); - DCHECK(bridge_.get()); - return bridge_->Send( - std::vector(data.data(), data.data() + data.size())); -} - -void WebSocketStreamHandleImpl::Context::Close() { - VLOG(1) << "Close"; - if (bridge_.get()) - bridge_->Close(); -} - -void WebSocketStreamHandleImpl::Context::Detach() { - handle_ = NULL; - client_ = NULL; - // If Connect was called, |bridge_| is not NULL, so that this Context closes - // the |bridge_| here. Then |bridge_| will call back DidClose, and will - // be released by itself. - // Otherwise, |bridge_| is NULL. - if (bridge_.get()) - bridge_->Close(); -} - -void WebSocketStreamHandleImpl::Context::DidOpenStream( - WebSocketStreamHandle* web_handle, int max_amount_send_allowed) { - VLOG(1) << "DidOpen"; - if (client_) - client_->didOpenStream(handle_, max_amount_send_allowed); -} - -void WebSocketStreamHandleImpl::Context::DidSendData( - WebSocketStreamHandle* web_handle, int amount_sent) { - if (client_) - client_->didSendData(handle_, amount_sent); -} - -void WebSocketStreamHandleImpl::Context::DidReceiveData( - WebSocketStreamHandle* web_handle, const char* data, int size) { - if (client_) - client_->didReceiveData(handle_, WebData(data, size)); -} - -void WebSocketStreamHandleImpl::Context::DidClose( - WebSocketStreamHandle* web_handle) { - VLOG(1) << "DidClose"; - bridge_ = NULL; - WebSocketStreamHandleImpl* handle = handle_; - handle_ = NULL; - if (client_) { - WebSocketStreamHandleClient* client = client_; - client_ = NULL; - client->didClose(handle); - } - Release(); -} - -void WebSocketStreamHandleImpl::Context::DidFail( - WebSocketStreamHandle* web_handle, - int error_code, - const string16& error_msg) { - VLOG(1) << "DidFail"; - if (client_) { - client_->didFail( - handle_, - WebSocketStreamError(error_code, error_msg)); - } -} - -// WebSocketStreamHandleImpl ------------------------------------------------ - -WebSocketStreamHandleImpl::WebSocketStreamHandleImpl( - WebKitPlatformSupportImpl* platform) - : context_(new Context(this)), - platform_(platform) { -} - -WebSocketStreamHandleImpl::~WebSocketStreamHandleImpl() { - // We won't receive any events from |context_|. - // |context_| is ref counted, and will be released when it received - // DidClose. - context_->Detach(); -} - -void WebSocketStreamHandleImpl::connect( - const WebURL& url, WebSocketStreamHandleClient* client) { - VLOG(1) << "connect url=" << url; - DCHECK(!context_->client()); - context_->set_client(client); - - context_->Connect(url, platform_); -} - -bool WebSocketStreamHandleImpl::send(const WebData& data) { - return context_->Send(data); -} - -void WebSocketStreamHandleImpl::close() { - context_->Close(); -} - -} // namespace webkit_glue diff --git a/webkit/glue/websocketstreamhandle_impl.h b/webkit/glue/websocketstreamhandle_impl.h deleted file mode 100644 index 827bb88..0000000 --- a/webkit/glue/websocketstreamhandle_impl.h +++ /dev/null @@ -1,40 +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. - -#ifndef WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_IMPL_H_ -#define WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_IMPL_H_ - -#include "base/memory/ref_counted.h" -#include "base/supports_user_data.h" -#include "third_party/WebKit/public/platform/WebSocketStreamHandle.h" - -namespace webkit_glue { - -class WebKitPlatformSupportImpl; - -class WebSocketStreamHandleImpl - : public base::SupportsUserData, - public WebKit::WebSocketStreamHandle { - public: - explicit WebSocketStreamHandleImpl(WebKitPlatformSupportImpl* platform); - virtual ~WebSocketStreamHandleImpl(); - - // WebSocketStreamHandle methods: - virtual void connect( - const WebKit::WebURL& url, - WebKit::WebSocketStreamHandleClient* client); - virtual bool send(const WebKit::WebData& data); - virtual void close(); - - private: - class Context; - scoped_refptr context_; - WebKitPlatformSupportImpl* platform_; - - DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleImpl); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_IMPL_H_ diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc deleted file mode 100644 index 2f12b18..0000000 --- a/webkit/glue/weburlloader_impl.cc +++ /dev/null @@ -1,854 +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. - -// An implementation of WebURLLoader in terms of ResourceLoaderBridge. - -#include "webkit/glue/weburlloader_impl.h" - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/process_util.h" -#include "base/strings/string_util.h" -#include "base/time/time.h" -#include "net/base/data_url.h" -#include "net/base/load_flags.h" -#include "net/base/mime_util.h" -#include "net/base/net_errors.h" -#include "net/base/net_util.h" -#include "net/http/http_response_headers.h" -#include "net/http/http_util.h" -#include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h" -#include "third_party/WebKit/public/platform/WebHTTPLoadInfo.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "third_party/WebKit/public/platform/WebURLError.h" -#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" -#include "third_party/WebKit/public/platform/WebURLLoadTiming.h" -#include "third_party/WebKit/public/platform/WebURLRequest.h" -#include "third_party/WebKit/public/platform/WebURLResponse.h" -#include "third_party/WebKit/public/web/WebSecurityPolicy.h" -#include "webkit/common/resource_request_body.h" -#include "webkit/glue/ftp_directory_listing_response_delegate.h" -#include "webkit/glue/multipart_response_delegate.h" -#include "webkit/glue/resource_loader_bridge.h" -#include "webkit/glue/webkitplatformsupport_impl.h" -#include "webkit/glue/weburlrequest_extradata_impl.h" -#include "webkit/glue/weburlresponse_extradata_impl.h" - -using base::Time; -using base::TimeTicks; -using WebKit::WebData; -using WebKit::WebHTTPBody; -using WebKit::WebHTTPHeaderVisitor; -using WebKit::WebHTTPLoadInfo; -using WebKit::WebReferrerPolicy; -using WebKit::WebSecurityPolicy; -using WebKit::WebString; -using WebKit::WebURL; -using WebKit::WebURLError; -using WebKit::WebURLLoadTiming; -using WebKit::WebURLLoader; -using WebKit::WebURLLoaderClient; -using WebKit::WebURLRequest; -using WebKit::WebURLResponse; - -namespace webkit_glue { - -// Utilities ------------------------------------------------------------------ - -namespace { - -const char kThrottledErrorDescription[] = - "Request throttled. Visit http://dev.chromium.org/throttling for more " - "information."; - -class HeaderFlattener : public WebHTTPHeaderVisitor { - public: - explicit HeaderFlattener(int load_flags) - : load_flags_(load_flags), - has_accept_header_(false) { - } - - virtual void visitHeader(const WebString& name, const WebString& value) { - // TODO(darin): is UTF-8 really correct here? It is if the strings are - // already ASCII (i.e., if they are already escaped properly). - const std::string& name_utf8 = name.utf8(); - const std::string& value_utf8 = value.utf8(); - - // Skip over referrer headers found in the header map because we already - // pulled it out as a separate parameter. - if (LowerCaseEqualsASCII(name_utf8, "referer")) - return; - - // Skip over "Cache-Control: max-age=0" header if the corresponding - // load flag is already specified. FrameLoader sets both the flag and - // the extra header -- the extra header is redundant since our network - // implementation will add the necessary headers based on load flags. - // See http://code.google.com/p/chromium/issues/detail?id=3434. - if ((load_flags_ & net::LOAD_VALIDATE_CACHE) && - LowerCaseEqualsASCII(name_utf8, "cache-control") && - LowerCaseEqualsASCII(value_utf8, "max-age=0")) - return; - - if (LowerCaseEqualsASCII(name_utf8, "accept")) - has_accept_header_ = true; - - if (!buffer_.empty()) - buffer_.append("\r\n"); - buffer_.append(name_utf8 + ": " + value_utf8); - } - - const std::string& GetBuffer() { - // In some cases, WebKit doesn't add an Accept header, but not having the - // header confuses some web servers. See bug 808613. - if (!has_accept_header_) { - if (!buffer_.empty()) - buffer_.append("\r\n"); - buffer_.append("Accept: */*"); - has_accept_header_ = true; - } - return buffer_; - } - - private: - int load_flags_; - std::string buffer_; - bool has_accept_header_; -}; - -// Extracts the information from a data: url. -bool GetInfoFromDataURL(const GURL& url, - ResourceResponseInfo* info, - std::string* data, - int* error_code) { - std::string mime_type; - std::string charset; - if (net::DataURL::Parse(url, &mime_type, &charset, data)) { - *error_code = net::OK; - // Assure same time for all time fields of data: URLs. - Time now = Time::Now(); - info->load_timing.request_start = TimeTicks::Now(); - info->load_timing.request_start_time = now; - info->request_time = now; - info->response_time = now; - info->headers = NULL; - info->mime_type.swap(mime_type); - info->charset.swap(charset); - info->security_info.clear(); - info->content_length = data->length(); - info->encoded_data_length = 0; - - return true; - } - - *error_code = net::ERR_INVALID_URL; - return false; -} - -typedef ResourceDevToolsInfo::HeadersVector HeadersVector; - -// Converts timing data from |load_timing| to the format used by WebKit. -void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing, - WebURLLoadTiming* url_timing) { - DCHECK(!load_timing.request_start.is_null()); - - const TimeTicks kNullTicks; - url_timing->initialize(); - url_timing->setRequestTime( - (load_timing.request_start - kNullTicks).InSecondsF()); - url_timing->setProxyStart( - (load_timing.proxy_resolve_start - kNullTicks).InSecondsF()); - url_timing->setProxyEnd( - (load_timing.proxy_resolve_end - kNullTicks).InSecondsF()); - url_timing->setDNSStart( - (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF()); - url_timing->setDNSEnd( - (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF()); - url_timing->setConnectStart( - (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF()); - url_timing->setConnectEnd( - (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF()); - url_timing->setSSLStart( - (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF()); - url_timing->setSSLEnd( - (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF()); - url_timing->setSendStart( - (load_timing.send_start - kNullTicks).InSecondsF()); - url_timing->setSendEnd( - (load_timing.send_end - kNullTicks).InSecondsF()); - url_timing->setReceiveHeadersEnd( - (load_timing.receive_headers_end - kNullTicks).InSecondsF()); -} - -void PopulateURLResponse( - const GURL& url, - const ResourceResponseInfo& info, - WebURLResponse* response) { - response->setURL(url); - response->setResponseTime(info.response_time.ToDoubleT()); - response->setMIMEType(WebString::fromUTF8(info.mime_type)); - response->setTextEncodingName(WebString::fromUTF8(info.charset)); - response->setExpectedContentLength(info.content_length); - response->setSecurityInfo(info.security_info); - response->setAppCacheID(info.appcache_id); - response->setAppCacheManifestURL(info.appcache_manifest_url); - response->setWasCached(!info.load_timing.request_start_time.is_null() && - info.response_time < info.load_timing.request_start_time); - response->setRemoteIPAddress( - WebString::fromUTF8(info.socket_address.host())); - response->setRemotePort(info.socket_address.port()); - response->setConnectionID(info.load_timing.socket_log_id); - response->setConnectionReused(info.load_timing.socket_reused); - response->setDownloadFilePath(info.download_file_path.AsUTF16Unsafe()); - WebURLResponseExtraDataImpl* extra_data = - new WebURLResponseExtraDataImpl(info.npn_negotiated_protocol); - response->setExtraData(extra_data); - extra_data->set_was_fetched_via_spdy(info.was_fetched_via_spdy); - extra_data->set_was_npn_negotiated(info.was_npn_negotiated); - extra_data->set_was_alternate_protocol_available( - info.was_alternate_protocol_available); - extra_data->set_connection_info(info.connection_info); - extra_data->set_was_fetched_via_proxy(info.was_fetched_via_proxy); - - // If there's no received headers end time, don't set load timing. This is - // the case for non-HTTP requests, requests that don't go over the wire, and - // certain error cases. - if (!info.load_timing.receive_headers_end.is_null()) { - WebURLLoadTiming timing; - PopulateURLLoadTiming(info.load_timing, &timing); - response->setLoadTiming(timing); - } - - if (info.devtools_info.get()) { - WebHTTPLoadInfo load_info; - - load_info.setHTTPStatusCode(info.devtools_info->http_status_code); - load_info.setHTTPStatusText(WebString::fromUTF8( - info.devtools_info->http_status_text)); - load_info.setEncodedDataLength(info.encoded_data_length); - - load_info.setRequestHeadersText(WebString::fromUTF8( - info.devtools_info->request_headers_text)); - load_info.setResponseHeadersText(WebString::fromUTF8( - info.devtools_info->response_headers_text)); - const HeadersVector& request_headers = info.devtools_info->request_headers; - for (HeadersVector::const_iterator it = request_headers.begin(); - it != request_headers.end(); ++it) { - load_info.addRequestHeader(WebString::fromUTF8(it->first), - WebString::fromUTF8(it->second)); - } - const HeadersVector& response_headers = - info.devtools_info->response_headers; - for (HeadersVector::const_iterator it = response_headers.begin(); - it != response_headers.end(); ++it) { - load_info.addResponseHeader(WebString::fromUTF8(it->first), - WebString::fromUTF8(it->second)); - } - response->setHTTPLoadInfo(load_info); - } - - const net::HttpResponseHeaders* headers = info.headers.get(); - if (!headers) - return; - - WebURLResponse::HTTPVersion version = WebURLResponse::Unknown; - if (headers->GetHttpVersion() == net::HttpVersion(0, 9)) - version = WebURLResponse::HTTP_0_9; - else if (headers->GetHttpVersion() == net::HttpVersion(1, 0)) - version = WebURLResponse::HTTP_1_0; - else if (headers->GetHttpVersion() == net::HttpVersion(1, 1)) - version = WebURLResponse::HTTP_1_1; - response->setHTTPVersion(version); - response->setHTTPStatusCode(headers->response_code()); - response->setHTTPStatusText(WebString::fromUTF8(headers->GetStatusText())); - - // TODO(darin): We should leverage HttpResponseHeaders for this, and this - // should be using the same code as ResourceDispatcherHost. - // TODO(jungshik): Figure out the actual value of the referrer charset and - // pass it to GetSuggestedFilename. - std::string value; - headers->EnumerateHeader(NULL, "content-disposition", &value); - response->setSuggestedFileName( - net::GetSuggestedFilename(url, - value, - std::string(), // referrer_charset - std::string(), // suggested_name - std::string(), // mime_type - std::string())); // default_name - - Time time_val; - if (headers->GetLastModifiedValue(&time_val)) - response->setLastModifiedDate(time_val.ToDoubleT()); - - // Build up the header map. - void* iter = NULL; - std::string name; - while (headers->EnumerateHeaderLines(&iter, &name, &value)) { - response->addHTTPHeaderField(WebString::fromUTF8(name), - WebString::fromUTF8(value)); - } -} - -net::RequestPriority ConvertWebKitPriorityToNetPriority( - const WebURLRequest::Priority& priority) { - switch (priority) { - case WebURLRequest::PriorityVeryHigh: - return net::HIGHEST; - - case WebURLRequest::PriorityHigh: - return net::MEDIUM; - - case WebURLRequest::PriorityMedium: - return net::LOW; - - case WebURLRequest::PriorityLow: - return net::LOWEST; - - case WebURLRequest::PriorityVeryLow: - return net::IDLE; - - case WebURLRequest::PriorityUnresolved: - default: - NOTREACHED(); - return net::LOW; - } -} - -} // namespace - -// WebURLLoaderImpl::Context -------------------------------------------------- - -// This inner class exists since the WebURLLoader may be deleted while inside a -// call to WebURLLoaderClient. The bridge requires its Peer to stay alive -// until it receives OnCompletedRequest. -class WebURLLoaderImpl::Context : public base::RefCounted, - public ResourceLoaderBridge::Peer { - public: - explicit Context(WebURLLoaderImpl* loader); - - WebURLLoaderClient* client() const { return client_; } - void set_client(WebURLLoaderClient* client) { client_ = client; } - - void Cancel(); - void SetDefersLoading(bool value); - void DidChangePriority(WebURLRequest::Priority new_priority); - void Start( - const WebURLRequest& request, - ResourceLoaderBridge::SyncLoadResponse* sync_load_response, - WebKitPlatformSupportImpl* platform); - - // ResourceLoaderBridge::Peer methods: - virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE; - virtual bool OnReceivedRedirect( - const GURL& new_url, - const ResourceResponseInfo& info, - bool* has_new_first_party_for_cookies, - GURL* new_first_party_for_cookies) OVERRIDE; - virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE; - virtual void OnDownloadedData(int len) OVERRIDE; - virtual void OnReceivedData(const char* data, - int data_length, - int encoded_data_length) OVERRIDE; - virtual void OnReceivedCachedMetadata(const char* data, int len) OVERRIDE; - virtual void OnCompletedRequest( - int error_code, - bool was_ignored_by_handler, - const std::string& security_info, - const base::TimeTicks& completion_time) OVERRIDE; - - private: - friend class base::RefCounted; - virtual ~Context() {} - - // We can optimize the handling of data URLs in most cases. - bool CanHandleDataURL(const GURL& url) const; - void HandleDataURL(); - - WebURLLoaderImpl* loader_; - WebURLRequest request_; - WebURLLoaderClient* client_; - WebReferrerPolicy referrer_policy_; - scoped_ptr bridge_; - scoped_ptr ftp_listing_delegate_; - scoped_ptr multipart_delegate_; - scoped_ptr completed_bridge_; -}; - -WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader) - : loader_(loader), - client_(NULL), - referrer_policy_(WebKit::WebReferrerPolicyDefault) { -} - -void WebURLLoaderImpl::Context::Cancel() { - // The bridge will still send OnCompletedRequest, which will Release() us, so - // we don't do that here. - if (bridge_) - bridge_->Cancel(); - - // Ensure that we do not notify the multipart delegate anymore as it has - // its own pointer to the client. - if (multipart_delegate_) - multipart_delegate_->Cancel(); - - // Do not make any further calls to the client. - client_ = NULL; - loader_ = NULL; -} - -void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { - if (bridge_) - bridge_->SetDefersLoading(value); -} - -void WebURLLoaderImpl::Context::DidChangePriority( - WebURLRequest::Priority new_priority) { - if (bridge_) - bridge_->DidChangePriority( - ConvertWebKitPriorityToNetPriority(new_priority)); -} - -void WebURLLoaderImpl::Context::Start( - const WebURLRequest& request, - ResourceLoaderBridge::SyncLoadResponse* sync_load_response, - WebKitPlatformSupportImpl* platform) { - DCHECK(!bridge_.get()); - - request_ = request; // Save the request. - - GURL url = request.url(); - if (url.SchemeIs("data") && CanHandleDataURL(url)) { - if (sync_load_response) { - // This is a sync load. Do the work now. - sync_load_response->url = url; - std::string data; - GetInfoFromDataURL(sync_load_response->url, sync_load_response, - &sync_load_response->data, - &sync_load_response->error_code); - } else { - AddRef(); // Balanced in OnCompletedRequest - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(&Context::HandleDataURL, this)); - } - return; - } - - GURL referrer_url( - request.httpHeaderField(WebString::fromUTF8("Referer")).utf8()); - const std::string& method = request.httpMethod().utf8(); - - int load_flags = net::LOAD_NORMAL; - switch (request.cachePolicy()) { - case WebURLRequest::ReloadIgnoringCacheData: - // Required by LayoutTests/http/tests/misc/refresh-headers.php - load_flags |= net::LOAD_VALIDATE_CACHE; - break; - case WebURLRequest::ReturnCacheDataElseLoad: - load_flags |= net::LOAD_PREFERRING_CACHE; - break; - case WebURLRequest::ReturnCacheDataDontLoad: - load_flags |= net::LOAD_ONLY_FROM_CACHE; - break; - case WebURLRequest::UseProtocolCachePolicy: - break; - } - - if (request.reportUploadProgress()) - load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; - if (request.reportLoadTiming()) - load_flags |= net::LOAD_ENABLE_LOAD_TIMING; - if (request.reportRawHeaders()) - load_flags |= net::LOAD_REPORT_RAW_HEADERS; - - if (!request.allowCookies() || !request.allowStoredCredentials()) { - load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; - load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; - } - - if (!request.allowStoredCredentials()) - load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; - - HeaderFlattener flattener(load_flags); - request.visitHTTPHeaderFields(&flattener); - - // TODO(brettw) this should take parameter encoding into account when - // creating the GURLs. - - ResourceLoaderBridge::RequestInfo request_info; - request_info.method = method; - request_info.url = url; - request_info.first_party_for_cookies = request.firstPartyForCookies(); - request_info.referrer = referrer_url; - request_info.headers = flattener.GetBuffer(); - request_info.load_flags = load_flags; - // requestor_pid only needs to be non-zero if the request originates outside - // the render process, so we can use requestorProcessID even for requests - // from in-process plugins. - request_info.requestor_pid = request.requestorProcessID(); - request_info.request_type = - ResourceType::FromTargetType(request.targetType()); - request_info.priority = - ConvertWebKitPriorityToNetPriority(request.priority()); - request_info.appcache_host_id = request.appCacheHostID(); - request_info.routing_id = request.requestorID(); - request_info.download_to_file = request.downloadToFile(); - request_info.has_user_gesture = request.hasUserGesture(); - request_info.extra_data = request.extraData(); - if (request.extraData()) { - referrer_policy_ = static_cast( - request.extraData())->referrer_policy(); - request_info.referrer_policy = referrer_policy_; - } - bridge_.reset(platform->CreateResourceLoader(request_info)); - - if (!request.httpBody().isNull()) { - // GET and HEAD requests shouldn't have http bodies. - DCHECK(method != "GET" && method != "HEAD"); - const WebHTTPBody& httpBody = request.httpBody(); - size_t i = 0; - WebHTTPBody::Element element; - scoped_refptr request_body = new ResourceRequestBody; - while (httpBody.elementAt(i++, element)) { - switch (element.type) { - case WebHTTPBody::Element::TypeData: - if (!element.data.isEmpty()) { - // WebKit sometimes gives up empty data to append. These aren't - // necessary so we just optimize those out here. - request_body->AppendBytes( - element.data.data(), static_cast(element.data.size())); - } - break; - case WebHTTPBody::Element::TypeFile: - if (element.fileLength == -1) { - request_body->AppendFileRange( - base::FilePath::FromUTF16Unsafe(element.filePath), - 0, kuint64max, base::Time()); - } else { - request_body->AppendFileRange( - base::FilePath::FromUTF16Unsafe(element.filePath), - static_cast(element.fileStart), - static_cast(element.fileLength), - base::Time::FromDoubleT(element.modificationTime)); - } - break; - case WebHTTPBody::Element::TypeURL: { - GURL url = GURL(element.url); - DCHECK(url.SchemeIsFileSystem()); - request_body->AppendFileSystemFileRange( - url, - static_cast(element.fileStart), - static_cast(element.fileLength), - base::Time::FromDoubleT(element.modificationTime)); - break; - } - case WebHTTPBody::Element::TypeBlob: - request_body->AppendBlob(GURL(element.blobURL)); - break; - default: - NOTREACHED(); - } - } - request_body->set_identifier(request.httpBody().identifier()); - bridge_->SetRequestBody(request_body.get()); - } - - if (sync_load_response) { - bridge_->SyncLoad(sync_load_response); - return; - } - - if (bridge_->Start(this)) { - AddRef(); // Balanced in OnCompletedRequest - } else { - bridge_.reset(); - } -} - -void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { - if (client_) - client_->didSendData(loader_, position, size); -} - -bool WebURLLoaderImpl::Context::OnReceivedRedirect( - const GURL& new_url, - const ResourceResponseInfo& info, - bool* has_new_first_party_for_cookies, - GURL* new_first_party_for_cookies) { - if (!client_) - return false; - - WebURLResponse response; - response.initialize(); - PopulateURLResponse(request_.url(), info, &response); - - // TODO(darin): We lack sufficient information to construct the actual - // request that resulted from the redirect. - WebURLRequest new_request(new_url); - new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); - new_request.setDownloadToFile(request_.downloadToFile()); - - WebString referrer_string = WebString::fromUTF8("Referer"); - WebString referrer = WebSecurityPolicy::generateReferrerHeader( - referrer_policy_, - new_url, - request_.httpHeaderField(referrer_string)); - if (!referrer.isEmpty()) - new_request.setHTTPHeaderField(referrer_string, referrer); - - if (response.httpStatusCode() == 307) - new_request.setHTTPMethod(request_.httpMethod()); - - client_->willSendRequest(loader_, new_request, response); - request_ = new_request; - *has_new_first_party_for_cookies = true; - *new_first_party_for_cookies = request_.firstPartyForCookies(); - - // Only follow the redirect if WebKit left the URL unmodified. - if (new_url == GURL(new_request.url())) - return true; - - // We assume that WebKit only changes the URL to suppress a redirect, and we - // assume that it does so by setting it to be invalid. - DCHECK(!new_request.url().isValid()); - return false; -} - -void WebURLLoaderImpl::Context::OnReceivedResponse( - const ResourceResponseInfo& info) { - if (!client_) - return; - - WebURLResponse response; - response.initialize(); - PopulateURLResponse(request_.url(), info, &response); - - bool show_raw_listing = (GURL(request_.url()).query() == "raw"); - - if (info.mime_type == "text/vnd.chromium.ftp-dir") { - if (show_raw_listing) { - // Set the MIME type to plain text to prevent any active content. - response.setMIMEType("text/plain"); - } else { - // We're going to produce a parsed listing in HTML. - response.setMIMEType("text/html"); - } - } - - scoped_refptr protect(this); - client_->didReceiveResponse(loader_, response); - - // We may have been cancelled after didReceiveResponse, which would leave us - // without a client and therefore without much need to do further handling. - if (!client_) - return; - - DCHECK(!ftp_listing_delegate_.get()); - DCHECK(!multipart_delegate_.get()); - if (info.headers.get() && info.mime_type == "multipart/x-mixed-replace") { - std::string content_type; - info.headers->EnumerateHeader(NULL, "content-type", &content_type); - - std::string mime_type; - std::string charset; - bool had_charset = false; - std::string boundary; - net::HttpUtil::ParseContentType(content_type, &mime_type, &charset, - &had_charset, &boundary); - TrimString(boundary, " \"", &boundary); - - // If there's no boundary, just handle the request normally. In the gecko - // code, nsMultiMixedConv::OnStartRequest throws an exception. - if (!boundary.empty()) { - multipart_delegate_.reset( - new MultipartResponseDelegate(client_, loader_, response, boundary)); - } - } else if (info.mime_type == "text/vnd.chromium.ftp-dir" && - !show_raw_listing) { - ftp_listing_delegate_.reset( - new FtpDirectoryListingResponseDelegate(client_, loader_, response)); - } -} - -void WebURLLoaderImpl::Context::OnDownloadedData(int len) { - if (client_) - client_->didDownloadData(loader_, len); -} - -void WebURLLoaderImpl::Context::OnReceivedData(const char* data, - int data_length, - int encoded_data_length) { - if (!client_) - return; - - if (ftp_listing_delegate_) { - // The FTP listing delegate will make the appropriate calls to - // client_->didReceiveData and client_->didReceiveResponse. - ftp_listing_delegate_->OnReceivedData(data, data_length); - } else if (multipart_delegate_) { - // The multipart delegate will make the appropriate calls to - // client_->didReceiveData and client_->didReceiveResponse. - multipart_delegate_->OnReceivedData(data, data_length, encoded_data_length); - } else { - client_->didReceiveData(loader_, data, data_length, encoded_data_length); - } -} - -void WebURLLoaderImpl::Context::OnReceivedCachedMetadata( - const char* data, int len) { - if (client_) - client_->didReceiveCachedMetadata(loader_, data, len); -} - -void WebURLLoaderImpl::Context::OnCompletedRequest( - int error_code, - bool was_ignored_by_handler, - const std::string& security_info, - const base::TimeTicks& completion_time) { - if (ftp_listing_delegate_) { - ftp_listing_delegate_->OnCompletedRequest(); - ftp_listing_delegate_.reset(NULL); - } else if (multipart_delegate_) { - multipart_delegate_->OnCompletedRequest(); - multipart_delegate_.reset(NULL); - } - - // Prevent any further IPC to the browser now that we're complete, but - // don't delete it to keep any downloaded temp files alive. - DCHECK(!completed_bridge_.get()); - completed_bridge_.swap(bridge_); - - if (client_) { - if (error_code != net::OK) { - client_->didFail(loader_, CreateError(request_.url(), error_code)); - } else { - client_->didFinishLoading( - loader_, (completion_time - TimeTicks()).InSecondsF()); - } - } - - // We are done with the bridge now, and so we need to release the reference - // to ourselves that we took on behalf of the bridge. This may cause our - // destruction. - Release(); -} - -bool WebURLLoaderImpl::Context::CanHandleDataURL(const GURL& url) const { - DCHECK(url.SchemeIs("data")); - - // Optimize for the case where we can handle a data URL locally. We must - // skip this for data URLs targetted at frames since those could trigger a - // download. - // - // NOTE: We special case MIME types we can render both for performance - // reasons as well as to support unit tests, which do not have an underlying - // ResourceLoaderBridge implementation. - -#if defined(OS_ANDROID) - // For compatibility reasons on Android we need to expose top-level data:// - // to the browser. - if (request_.targetType() == WebURLRequest::TargetIsMainFrame) - return false; -#endif - - if (request_.targetType() != WebURLRequest::TargetIsMainFrame && - request_.targetType() != WebURLRequest::TargetIsSubframe) - return true; - - std::string mime_type, unused_charset; - if (net::DataURL::Parse(url, &mime_type, &unused_charset, NULL) && - net::IsSupportedMimeType(mime_type)) - return true; - - return false; -} - -void WebURLLoaderImpl::Context::HandleDataURL() { - ResourceResponseInfo info; - int error_code; - std::string data; - - if (GetInfoFromDataURL(request_.url(), &info, &data, &error_code)) { - OnReceivedResponse(info); - if (!data.empty()) - OnReceivedData(data.data(), data.size(), 0); - } - - OnCompletedRequest(error_code, false, info.security_info, - base::TimeTicks::Now()); -} - -// WebURLLoaderImpl ----------------------------------------------------------- - -WebURLLoaderImpl::WebURLLoaderImpl(WebKitPlatformSupportImpl* platform) - : context_(new Context(this)), - platform_(platform) { -} - -WebURLLoaderImpl::~WebURLLoaderImpl() { - cancel(); -} - -WebURLError WebURLLoaderImpl::CreateError(const WebURL& unreachable_url, - int reason) { - WebURLError error; - error.domain = WebString::fromUTF8(net::kErrorDomain); - error.reason = reason; - error.unreachableURL = unreachable_url; - if (reason == net::ERR_ABORTED) { - error.isCancellation = true; - } else if (reason == net::ERR_TEMPORARILY_THROTTLED) { - error.localizedDescription = WebString::fromUTF8( - kThrottledErrorDescription); - } - return error; -} - -void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, - WebURLResponse& response, - WebURLError& error, - WebData& data) { - ResourceLoaderBridge::SyncLoadResponse sync_load_response; - context_->Start(request, &sync_load_response, platform_); - - const GURL& final_url = sync_load_response.url; - - // TODO(tc): For file loads, we may want to include a more descriptive - // status code or status text. - int error_code = sync_load_response.error_code; - if (error_code != net::OK) { - response.setURL(final_url); - error.domain = WebString::fromUTF8(net::kErrorDomain); - error.reason = error_code; - error.unreachableURL = final_url; - return; - } - - PopulateURLResponse(final_url, sync_load_response, &response); - - data.assign(sync_load_response.data.data(), - sync_load_response.data.size()); -} - -void WebURLLoaderImpl::loadAsynchronously(const WebURLRequest& request, - WebURLLoaderClient* client) { - DCHECK(!context_->client()); - - context_->set_client(client); - context_->Start(request, NULL, platform_); -} - -void WebURLLoaderImpl::cancel() { - context_->Cancel(); -} - -void WebURLLoaderImpl::setDefersLoading(bool value) { - context_->SetDefersLoading(value); -} - -void WebURLLoaderImpl::didChangePriority(WebURLRequest::Priority new_priority) { - context_->DidChangePriority(new_priority); -} - -} // namespace webkit_glue diff --git a/webkit/glue/weburlloader_impl.h b/webkit/glue/weburlloader_impl.h deleted file mode 100644 index ecca9f4..0000000 --- a/webkit/glue/weburlloader_impl.h +++ /dev/null @@ -1,45 +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. - -#ifndef WEBKIT_GLUE_WEBURLLOADER_IMPL_H_ -#define WEBKIT_GLUE_WEBURLLOADER_IMPL_H_ - -#include "base/memory/ref_counted.h" -#include "third_party/WebKit/public/platform/WebURLLoader.h" -#include "webkit/glue/webkit_glue_export.h" - -namespace webkit_glue { - -class WebKitPlatformSupportImpl; - -class WebURLLoaderImpl : public WebKit::WebURLLoader { - public: - explicit WebURLLoaderImpl(WebKitPlatformSupportImpl* platform); - virtual ~WebURLLoaderImpl(); - - static WebKit::WebURLError CreateError(const WebKit::WebURL& unreachable_url, - int reason); - - // WebURLLoader methods: - virtual void loadSynchronously( - const WebKit::WebURLRequest& request, - WebKit::WebURLResponse& response, - WebKit::WebURLError& error, - WebKit::WebData& data); - virtual void loadAsynchronously( - const WebKit::WebURLRequest& request, - WebKit::WebURLLoaderClient* client); - virtual void cancel(); - virtual void setDefersLoading(bool value); - virtual void didChangePriority(WebKit::WebURLRequest::Priority new_priority); - - private: - class Context; - scoped_refptr context_; - WebKitPlatformSupportImpl* platform_; -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_WEBURLLOADER_IMPL_H_ diff --git a/webkit/glue/weburlrequest_extradata_impl.cc b/webkit/glue/weburlrequest_extradata_impl.cc deleted file mode 100644 index d9e7462..0000000 --- a/webkit/glue/weburlrequest_extradata_impl.cc +++ /dev/null @@ -1,22 +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/weburlrequest_extradata_impl.h" - -using WebKit::WebReferrerPolicy; -using WebKit::WebString; - -namespace webkit_glue { - -WebURLRequestExtraDataImpl::WebURLRequestExtraDataImpl( - WebReferrerPolicy referrer_policy, - const WebString& custom_user_agent) - : referrer_policy_(referrer_policy), - custom_user_agent_(custom_user_agent) { -} - -WebURLRequestExtraDataImpl::~WebURLRequestExtraDataImpl() { -} - -} // namespace webkit_glue diff --git a/webkit/glue/weburlrequest_extradata_impl.h b/webkit/glue/weburlrequest_extradata_impl.h deleted file mode 100644 index 151c4845..0000000 --- a/webkit/glue/weburlrequest_extradata_impl.h +++ /dev/null @@ -1,45 +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. - -#ifndef WEBKIT_GLUE_WEBURLREQUEST_EXTRADATA_IMPL_H_ -#define WEBKIT_GLUE_WEBURLREQUEST_EXTRADATA_IMPL_H_ - -#include "base/compiler_specific.h" -#include "third_party/WebKit/public/platform/WebReferrerPolicy.h" -#include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/platform/WebURLRequest.h" -#include "webkit/common/webkit_common_export.h" - -namespace webkit_glue { - -// Base class for Chrome's implementation of the "extra data" stored in each -// ResourceRequest. -class WEBKIT_COMMON_EXPORT WebURLRequestExtraDataImpl : - public NON_EXPORTED_BASE(WebKit::WebURLRequest::ExtraData) { - public: - // |custom_user_agent| is used to communicate an overriding custom user agent - // to |RenderViewImpl::willSendRequest()|; set to a null string to indicate no - // override and an empty string to indicate that there should be no user - // agent. This needs to be here, instead of content's |RequestExtraData| since - // ppb_url_request_info_impl.cc needs to be able to set it. - explicit WebURLRequestExtraDataImpl( - WebKit::WebReferrerPolicy referrer_policy, - const WebKit::WebString& custom_user_agent); - virtual ~WebURLRequestExtraDataImpl(); - - WebKit::WebReferrerPolicy referrer_policy() const { return referrer_policy_; } - const WebKit::WebString& custom_user_agent() const { - return custom_user_agent_; - } - - private: - WebKit::WebReferrerPolicy referrer_policy_; - WebKit::WebString custom_user_agent_; - - DISALLOW_COPY_AND_ASSIGN(WebURLRequestExtraDataImpl); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_WEBURLREQUEST_EXTRADATA_IMPL_H_ diff --git a/webkit/glue/weburlresponse_extradata_impl.cc b/webkit/glue/weburlresponse_extradata_impl.cc deleted file mode 100644 index 4063662..0000000 --- a/webkit/glue/weburlresponse_extradata_impl.cc +++ /dev/null @@ -1,19 +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/weburlresponse_extradata_impl.h" - -namespace webkit_glue { - -WebURLResponseExtraDataImpl::WebURLResponseExtraDataImpl( - const std::string& npn_negotiated_protocol) - : npn_negotiated_protocol_(npn_negotiated_protocol), - is_ftp_directory_listing_(false), - connection_info_(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN) { -} - -WebURLResponseExtraDataImpl::~WebURLResponseExtraDataImpl() { -} - -} // namespace webkit_glue diff --git a/webkit/glue/weburlresponse_extradata_impl.h b/webkit/glue/weburlresponse_extradata_impl.h deleted file mode 100644 index c26325c..0000000 --- a/webkit/glue/weburlresponse_extradata_impl.h +++ /dev/null @@ -1,96 +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. - -#ifndef WEBKIT_GLUE_WEBURLRESPONSE_EXTRADATA_IMPL_H_ -#define WEBKIT_GLUE_WEBURLRESPONSE_EXTRADATA_IMPL_H_ - -#include - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "net/http/http_response_info.h" -#include "third_party/WebKit/public/platform/WebURLResponse.h" -#include "webkit/common/webkit_common_export.h" - -namespace webkit_glue { - -// Base class for Chrome's implementation of the "extra data". -class WEBKIT_COMMON_EXPORT WebURLResponseExtraDataImpl : - public NON_EXPORTED_BASE(WebKit::WebURLResponse::ExtraData) { - public: - explicit WebURLResponseExtraDataImpl( - const std::string& npn_negotiated_protocol); - virtual ~WebURLResponseExtraDataImpl(); - - const std::string& npn_negotiated_protocol() const { - return npn_negotiated_protocol_; - } - - // Flag whether this request was loaded via an explicit proxy - // (HTTP, SOCKS, etc). - bool was_fetched_via_proxy() const { - return was_fetched_via_proxy_; - } - void set_was_fetched_via_proxy(bool was_fetched_via_proxy) { - was_fetched_via_proxy_ = was_fetched_via_proxy; - } - - /// Flag whether this request was loaded via the SPDY protocol or not. - // SPDY is an experimental web protocol, see http://dev.chromium.org/spdy - bool was_fetched_via_spdy() const { - return was_fetched_via_spdy_; - } - void set_was_fetched_via_spdy(bool was_fetched_via_spdy) { - was_fetched_via_spdy_ = was_fetched_via_spdy; - } - - // Information about the type of connection used to fetch this response. - net::HttpResponseInfo::ConnectionInfo connection_info() const { - return connection_info_; - } - void set_connection_info( - net::HttpResponseInfo::ConnectionInfo connection_info) { - connection_info_ = connection_info; - } - - // Flag whether this request was loaded after the - // TLS/Next-Protocol-Negotiation was used. - // This is related to SPDY. - bool was_npn_negotiated() const { - return was_npn_negotiated_; - } - void set_was_npn_negotiated(bool was_npn_negotiated) { - was_npn_negotiated_ = was_npn_negotiated; - } - - // Flag whether this request was made when "Alternate-Protocol: xxx" - // is present in server's response. - bool was_alternate_protocol_available() const { - return was_alternate_protocol_available_; - } - void set_was_alternate_protocol_available( - bool was_alternate_protocol_available) { - was_alternate_protocol_available_ = was_alternate_protocol_available; - } - - bool is_ftp_directory_listing() const { return is_ftp_directory_listing_; } - void set_is_ftp_directory_listing(bool is_ftp_directory_listing) { - is_ftp_directory_listing_ = is_ftp_directory_listing; - } - - private: - std::string npn_negotiated_protocol_; - bool is_ftp_directory_listing_; - bool was_fetched_via_proxy_; - bool was_fetched_via_spdy_; - bool was_npn_negotiated_; - net::HttpResponseInfo::ConnectionInfo connection_info_; - bool was_alternate_protocol_available_; - - DISALLOW_COPY_AND_ASSIGN(WebURLResponseExtraDataImpl); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_WEBURLRESPONSE_EXTRADATA_IMPL_H_ diff --git a/webkit/mocks/mock_weburlloader.h b/webkit/mocks/mock_weburlloader.h index 68ff9a2..a9e2d6b 100644 --- a/webkit/mocks/mock_weburlloader.h +++ b/webkit/mocks/mock_weburlloader.h @@ -6,7 +6,7 @@ #define WEBKIT_MOCKS_MOCK_WEBURLLOADER_H_ #include "testing/gmock/include/gmock/gmock.h" -#include "webkit/glue/weburlloader_impl.h" +#include "webkit/child/weburlloader_impl.h" namespace webkit_glue { diff --git a/webkit/plugins/ppapi/url_request_info_util.cc b/webkit/plugins/ppapi/url_request_info_util.cc index 774a3c9..b9e765a 100644 --- a/webkit/plugins/ppapi/url_request_info_util.cc +++ b/webkit/plugins/ppapi/url_request_info_util.cc @@ -18,7 +18,7 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "url/gurl.h" #include "url/url_util.h" -#include "webkit/glue/weburlrequest_extradata_impl.h" +#include "webkit/child/weburlrequest_extradata_impl.h" #include "webkit/plugins/ppapi/common.h" #include "webkit/plugins/ppapi/plugin_module.h" #include "webkit/plugins/ppapi/ppb_file_ref_impl.h" diff --git a/webkit/plugins/webkit_plugins.gypi b/webkit/plugins/webkit_plugins.gypi index 0479a6c..c63f524 100644 --- a/webkit/plugins/webkit_plugins.gypi +++ b/webkit/plugins/webkit_plugins.gypi @@ -41,6 +41,7 @@ '<(DEPTH)/webkit/plugins/webkit_plugins.gyp:plugins_common', '<(DEPTH)/webkit/renderer/compositor_bindings/compositor_bindings.gyp:webkit_compositor_support', '<(DEPTH)/webkit/storage_common.gyp:webkit_storage_common', + 'glue_child', ], 'sources': [ # This list contains all .h, .cc, and .mm files in glue except for diff --git a/webkit/support/test_webkit_platform_support.cc b/webkit/support/test_webkit_platform_support.cc index bde978b..8b3c5d2 100644 --- a/webkit/support/test_webkit_platform_support.cc +++ b/webkit/support/test_webkit_platform_support.cc @@ -14,12 +14,6 @@ #include "media/base/media.h" #include "net/cookies/cookie_monster.h" #include "net/test/spawned_test_server/spawned_test_server.h" -#include "third_party/WebKit/public/web/WebDatabase.h" -#include "third_party/WebKit/public/web/WebKit.h" -#include "third_party/WebKit/public/web/WebRuntimeFeatures.h" -#include "third_party/WebKit/public/web/WebScriptController.h" -#include "third_party/WebKit/public/web/WebSecurityPolicy.h" -#include "third_party/WebKit/public/web/WebStorageEventDispatcher.h" #include "third_party/WebKit/public/platform/WebAudioDevice.h" #include "third_party/WebKit/public/platform/WebData.h" #include "third_party/WebKit/public/platform/WebFileSystem.h" @@ -28,14 +22,20 @@ #include "third_party/WebKit/public/platform/WebStorageNamespace.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/web/WebDatabase.h" +#include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebRuntimeFeatures.h" +#include "third_party/WebKit/public/web/WebScriptController.h" +#include "third_party/WebKit/public/web/WebSecurityPolicy.h" +#include "third_party/WebKit/public/web/WebStorageEventDispatcher.h" #include "v8/include/v8.h" #include "webkit/browser/database/vfs_backend.h" +#include "webkit/child/webkitplatformsupport_impl.h" #include "webkit/common/gpu/test_context_provider_factory.h" #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" #include "webkit/common/gpu/webgraphicscontext3d_provider_impl.h" #include "webkit/glue/simple_webmimeregistry_impl.h" #include "webkit/glue/webkit_glue.h" -#include "webkit/glue/webkitplatformsupport_impl.h" #include "webkit/renderer/appcache/web_application_cache_host_impl.h" #include "webkit/renderer/compositor_bindings/web_compositor_support_impl.h" #include "webkit/support/gc_extension.h" diff --git a/webkit/support/webkit_support.cc b/webkit/support/webkit_support.cc index b96b537..bdb99f9 100644 --- a/webkit/support/webkit_support.cc +++ b/webkit/support/webkit_support.cc @@ -17,10 +17,10 @@ #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" #include "url/url_util.h" +#include "webkit/child/webkitplatformsupport_impl.h" #include "webkit/common/user_agent/user_agent.h" #include "webkit/common/user_agent/user_agent_util.h" #include "webkit/glue/webkit_glue.h" -#include "webkit/glue/webkitplatformsupport_impl.h" #include "webkit/support/platform_support.h" #include "webkit/support/test_webkit_platform_support.h" -- cgit v1.1