diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-30 22:42:58 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-30 22:42:58 +0000 |
commit | eed529ce5d09706bc2b9da5b96822eda2919a9ae (patch) | |
tree | f5afad43a1e8412ed9473fa9d7e418621373decd /webkit/glue | |
parent | ee8f54a54cab5cc3eaf837622ec61b482fac8858 (diff) | |
download | chromium_src-eed529ce5d09706bc2b9da5b96822eda2919a9ae.zip chromium_src-eed529ce5d09706bc2b9da5b96822eda2919a9ae.tar.gz chromium_src-eed529ce5d09706bc2b9da5b96822eda2919a9ae.tar.bz2 |
Revert WebURLLoader landing. Too many layout test failures.
TBR=dglazkov
Review URL: http://codereview.chromium.org/115973
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17293 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/glue_util.cc | 42 | ||||
-rw-r--r-- | webkit/glue/glue_util.h | 20 | ||||
-rw-r--r-- | webkit/glue/multipart_response_delegate.cc | 162 | ||||
-rw-r--r-- | webkit/glue/multipart_response_delegate.h | 57 | ||||
-rw-r--r-- | webkit/glue/multipart_response_delegate_unittest.cc | 277 | ||||
-rw-r--r-- | webkit/glue/resource_handle_impl.cc | 765 | ||||
-rw-r--r-- | webkit/glue/webkitclient_impl.cc | 6 | ||||
-rw-r--r-- | webkit/glue/webkitclient_impl.h | 1 | ||||
-rw-r--r-- | webkit/glue/webplugin_impl.cc | 288 | ||||
-rw-r--r-- | webkit/glue/webplugin_impl.h | 99 | ||||
-rw-r--r-- | webkit/glue/webplugin_impl_unittest.cc | 171 | ||||
-rw-r--r-- | webkit/glue/weburlloader_impl.cc | 502 | ||||
-rw-r--r-- | webkit/glue/weburlloader_impl.h | 61 |
13 files changed, 1215 insertions, 1236 deletions
diff --git a/webkit/glue/glue_util.cc b/webkit/glue/glue_util.cc index b85ad71..5f7228f 100644 --- a/webkit/glue/glue_util.cc +++ b/webkit/glue/glue_util.cc @@ -35,8 +35,6 @@ #include "webkit/api/public/WebSize.h" #include "webkit/api/public/WebString.h" #include "webkit/api/public/WebURL.h" -#include "webkit/api/public/WebURLRequest.h" -#include "webkit/api/public/WebURLResponse.h" namespace webkit_glue { @@ -73,9 +71,10 @@ WebCore::String String16ToString(const string16& str) { } std::string StringToStdString(const WebCore::String& str) { + if (str.length() == 0) + return std::string(); std::string ret; - if (!str.isNull()) - UTF16ToUTF8(str.characters(), str.length(), &ret); + UTF16ToUTF8(str.characters(), str.length(), &ret); return ret; } @@ -109,17 +108,6 @@ WebCore::CString WebCStringToCString(const WebKit::WebCString& str) { return str; } -WebKit::WebString StdStringToWebString(const std::string& str) { - return WebKit::WebString::fromUTF8(str.data(), str.size()); -} - -std::string WebStringToStdString(const WebKit::WebString& str) { - std::string ret; - if (!str.isNull()) - UTF16ToUTF8(str.data(), str.length(), &ret); - return ret; -} - FilePath::StringType StringToFilePathString(const WebCore::String& str) { #if defined(OS_WIN) return StringToStdWString(str); @@ -226,28 +214,4 @@ PassRefPtr<WebCore::ChromiumDataObject> WebDragDataToChromiumDataObject( return data; } -// WebURLRequest conversions --------------------------------------------------- - -WebCore::ResourceRequest* WebURLRequestToMutableResourceRequest( - WebKit::WebURLRequest* request) { - return &request->toMutableResourceRequest(); -} - -const WebCore::ResourceRequest* WebURLRequestToResourceRequest( - const WebKit::WebURLRequest* request) { - return &request->toResourceRequest(); -} - -// WebURLResponse conversions -------------------------------------------------- - -WebCore::ResourceResponse* WebURLResponseToMutableResourceResponse( - WebKit::WebURLResponse* response) { - return &response->toMutableResourceResponse(); -} - -const WebCore::ResourceResponse* WebURLResponseToResourceResponse( - const WebKit::WebURLResponse* response) { - return &response->toResourceResponse(); -} - } // namespace webkit_glue diff --git a/webkit/glue/glue_util.h b/webkit/glue/glue_util.h index 553802c..4bcebad 100644 --- a/webkit/glue/glue_util.h +++ b/webkit/glue/glue_util.h @@ -17,9 +17,7 @@ class IntPoint; class IntRect; class IntSize; class KURL; -class ResourceResponse; class String; -struct ResourceRequest; } namespace WebKit { @@ -27,8 +25,6 @@ class WebCString; class WebDragData; class WebString; class WebURL; -class WebURLRequest; -class WebURLResponse; struct WebPoint; struct WebRect; struct WebSize; @@ -72,10 +68,6 @@ WebCore::String WebStringToString(const WebKit::WebString& str); WebKit::WebCString CStringToWebCString(const WebCore::CString& str); WebCore::CString WebCStringToCString(const WebKit::WebCString& str); -// std::string <-> WebString. Conversion to/from UTF-8. -WebKit::WebString StdStringToWebString(const std::string& str); -std::string WebStringToStdString(const WebKit::WebString& str); - FilePath::StringType StringToFilePathString(const WebCore::String& str); WebCore::String FilePathStringToString(const FilePath::StringType& str); @@ -107,18 +99,6 @@ WebKit::WebDragData ChromiumDataObjectToWebDragData( WTF::PassRefPtr<WebCore::ChromiumDataObject> WebDragDataToChromiumDataObject( const WebKit::WebDragData&); -// Exposes the ResourceRequest contained by a WebURLRequest -WebCore::ResourceRequest* WebURLRequestToMutableResourceRequest( - WebKit::WebURLRequest* req); -const WebCore::ResourceRequest* WebURLRequestToResourceRequest( - const WebKit::WebURLRequest* req); - -// Exposes the ResourceResponse contained by a WebURLResponse -WebCore::ResourceResponse* WebURLResponseToMutableResourceResponse( - WebKit::WebURLResponse* resp); -const WebCore::ResourceResponse* WebURLResponseToResourceResponse( - const WebKit::WebURLResponse* resp); - } // namespace webkit_glue #endif // #ifndef WEBKIT_GLUE_GLUE_UTIL_H_ diff --git a/webkit/glue/multipart_response_delegate.cc b/webkit/glue/multipart_response_delegate.cc index 2000b61..9e8e67d 100644 --- a/webkit/glue/multipart_response_delegate.cc +++ b/webkit/glue/multipart_response_delegate.cc @@ -2,64 +2,32 @@ // 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 "config.h" +#include <string> + +#include "base/compiler_specific.h" +MSVC_PUSH_WARNING_LEVEL(0); +#include "HTTPHeaderMap.h" +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +#include "PlatformString.h" +MSVC_POP_WARNING(); + +#undef LOG #include "base/logging.h" #include "base/string_util.h" -#include "net/base/net_util.h" -#include "webkit/api/public/WebHTTPHeaderVisitor.h" -#include "webkit/api/public/WebString.h" -#include "webkit/api/public/WebURL.h" -#include "webkit/api/public/WebURLLoaderClient.h" +#include "webkit/glue/multipart_response_delegate.h" #include "webkit/glue/glue_util.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 = WebStringToStdString(name); - for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) { - if (LowerCaseEqualsASCII(name_utf8, kReplaceHeaders[i])) - return; - } - response_->setHTTPHeaderField(name, value); - } - private: - WebURLResponse* response_; -}; - -} // namespace +#include "net/base/net_util.h" MultipartResponseDelegate::MultipartResponseDelegate( - WebURLLoaderClient* client, - WebURLLoader* loader, - const WebURLResponse& response, + WebCore::ResourceHandleClient* client, + WebCore::ResourceHandle* job, + const WebCore::ResourceResponse& response, const std::string& boundary) : client_(client), - loader_(loader), + job_(job), original_response_(response), boundary_("--"), first_received_data_(true), @@ -73,8 +41,7 @@ MultipartResponseDelegate::MultipartResponseDelegate( } } -void MultipartResponseDelegate::OnReceivedData(const char* data, - int data_len) { +void MultipartResponseDelegate::OnReceivedData(const char* data, int data_len) { // 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. @@ -82,7 +49,8 @@ void MultipartResponseDelegate::OnReceivedData(const char* data, return; // TODO(tc): Figure out what to use for length_received. Maybe we can just - // pass the value on from our caller. + // pass the value on from our caller. See note in + // resource_handle_win.cc:ResourceHandleInternal::OnReceivedData. int length_received = -1; data_.append(data, data_len); @@ -130,10 +98,8 @@ void MultipartResponseDelegate::OnReceivedData(const char* data, while ((boundary_pos = FindBoundary()) != std::string::npos) { if (boundary_pos > 0) { // Send the last data chunk. - client_->didReceiveData(loader_, - data_.substr(0, boundary_pos).data(), - static_cast<int>(boundary_pos), - length_received); + client_->didReceiveData(job_, data_.substr(0, boundary_pos).data(), + static_cast<int>(boundary_pos), length_received); } size_t boundary_end_pos = boundary_pos + boundary_.length(); if (boundary_end_pos < data_.length() && '-' == data_[boundary_end_pos]) { @@ -162,15 +128,12 @@ void MultipartResponseDelegate::OnCompletedRequest() { // TODO(tc): Figure out what to use for length_received. Maybe we can just // pass the value on from our caller. int length_received = -1; - client_->didReceiveData(loader_, - data_.data(), - static_cast<int>(data_.length()), - length_received); + client_->didReceiveData(job_, data_.data(), + static_cast<int>(data_.length()), length_received); } } -int MultipartResponseDelegate::PushOverLine(const std::string& data, - size_t pos) { +int MultipartResponseDelegate::PushOverLine(const std::string& data, size_t pos) { int offset = 0; if (pos < data.length() && (data[pos] == '\r' || data[pos] == '\n')) { ++offset; @@ -212,28 +175,47 @@ bool MultipartResponseDelegate::ParseHeaders() { headers.append(data_.substr(0, line_end_pos)); data_ = data_.substr(line_end_pos); - // Create a WebURLResponse based on the original set of headers + the + // Create a ResourceResponse 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 mime_type = net::GetSpecificHeader(headers, "content-type"); std::string charset = net::GetHeaderParamValue(mime_type, "charset"); - WebURLResponse response(original_response_.url()); - response.setMIMEType(StdStringToWebString(mime_type)); - response.setTextEncodingName(StdStringToWebString(charset)); - - HeaderCopier copier(&response); - original_response_.visitHTTPHeaderFields(&copier); - - for (size_t i = 0; i < arraysize(kReplaceHeaders); ++i) { - std::string name(kReplaceHeaders[i]); + WebCore::ResourceResponse response(original_response_.url(), + webkit_glue::StdStringToString(mime_type.c_str()), + -1, + charset.c_str(), + WebCore::String()); + const WebCore::HTTPHeaderMap& orig_headers = + original_response_.httpHeaderFields(); + for (WebCore::HTTPHeaderMap::const_iterator it = orig_headers.begin(); + it != orig_headers.end(); ++it) { + if (!(equalIgnoringCase("content-type", it->first) || + equalIgnoringCase("content-length", it->first) || + equalIgnoringCase("content-disposition", it->first) || + equalIgnoringCase("content-range", it->first) || + equalIgnoringCase("range", it->first) || + equalIgnoringCase("set-cookie", it->first))) { + response.setHTTPHeaderField(it->first, it->second); + } + } + static const char* replace_headers[] = { + "Content-Type", + "Content-Length", + "Content-Disposition", + "Content-Range", + "Range", + "Set-Cookie" + }; + for (size_t i = 0; i < arraysize(replace_headers); ++i) { + std::string name(replace_headers[i]); std::string value = net::GetSpecificHeader(headers, name); if (!value.empty()) { - response.setHTTPHeaderField(StdStringToWebString(name), - StdStringToWebString(value)); + response.setHTTPHeaderField(webkit_glue::StdStringToString(name.c_str()), + webkit_glue::StdStringToString(value.c_str())); } } // Send the response! - client_->didReceiveResponse(loader_, response); + client_->didReceiveResponse(job_, response); return true; } @@ -257,27 +239,29 @@ size_t MultipartResponseDelegate::FindBoundary() { } bool MultipartResponseDelegate::ReadMultipartBoundary( - const WebURLResponse& response, + const WebCore::ResourceResponse& response, std::string* multipart_boundary) { - std::string content_type = WebStringToStdString( - response.httpHeaderField(WebString::fromUTF8("Content-Type"))); + WebCore::String content_type = response.httpHeaderField("Content-Type"); + std::string content_type_as_string = + webkit_glue::StringToStdString(content_type); - size_t boundary_start_offset = content_type.find("boundary="); + size_t boundary_start_offset = content_type_as_string.find("boundary="); if (boundary_start_offset == std::wstring::npos) { return false; } boundary_start_offset += strlen("boundary="); - size_t boundary_end_offset = content_type.find(';', boundary_start_offset); + size_t boundary_end_offset = + content_type_as_string.find(';', boundary_start_offset); if (boundary_end_offset == std::string::npos) - boundary_end_offset = content_type.length(); + boundary_end_offset = content_type_as_string.length(); size_t boundary_length = boundary_end_offset - boundary_start_offset; *multipart_boundary = - content_type.substr(boundary_start_offset, boundary_length); + content_type_as_string.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. @@ -286,14 +270,16 @@ bool MultipartResponseDelegate::ReadMultipartBoundary( } bool MultipartResponseDelegate::ReadContentRanges( - const WebURLResponse& response, + const WebCore::ResourceResponse& response, int* content_range_lower_bound, int* content_range_upper_bound) { - std::string content_range = WebStringToStdString( - response.httpHeaderField(WebString::fromUTF8("Content-Range"))); + std::string content_range = + webkit_glue::StringToStdString( + response.httpHeaderField("Content-Range")); - size_t byte_range_lower_bound_start_offset = content_range.find(" "); + size_t byte_range_lower_bound_start_offset = + content_range.find(" "); if (byte_range_lower_bound_start_offset == std::string::npos) { return false; } @@ -335,5 +321,3 @@ bool MultipartResponseDelegate::ReadContentRanges( return false; return true; } - -} // namespace webkit_glue diff --git a/webkit/glue/multipart_response_delegate.h b/webkit/glue/multipart_response_delegate.h index 3676a78..41d09c2 100644 --- a/webkit/glue/multipart_response_delegate.h +++ b/webkit/glue/multipart_response_delegate.h @@ -1,10 +1,11 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 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. +// A delegate class of ResourceHandleInternal (resource_handle_win) 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. @@ -46,28 +47,28 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef WEBKIT_GLUE_MULTIPART_RESPONSE_DELEGATE_H_ -#define WEBKIT_GLUE_MULTIPART_RESPONSE_DELEGATE_H_ - #include <string> -#include "webkit/api/public/WebURLResponse.h" +#include "config.h" -namespace WebKit { -class WebURLLoader; -class WebURLLoaderClient; -} +#include "base/compiler_specific.h" -namespace webkit_glue { +MSVC_PUSH_WARNING_LEVEL(0); +#include "ResourceResponse.h" +MSVC_POP_WARNING(); -// Used by unit tests to access private members. -class MultipartResponseDelegateTester; +namespace WebCore { + class ResourceHandle; + class ResourceHandleClient; +} class MultipartResponseDelegate { + friend class MultipartResponseTest_Functions_Test; // For unittests. + public: - MultipartResponseDelegate(WebKit::WebURLLoaderClient* client, - WebKit::WebURLLoader* loader, - const WebKit::WebURLResponse& response, + MultipartResponseDelegate(WebCore::ResourceHandleClient* client, + WebCore::ResourceHandle* job, + const WebCore::ResourceResponse& response, const std::string& boundary); // Passed through from ResourceHandleInternal @@ -77,27 +78,25 @@ class MultipartResponseDelegate { // 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, + static bool ReadMultipartBoundary(const WebCore::ResourceResponse& 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, + static bool ReadContentRanges(const WebCore::ResourceResponse& response, int* content_range_lower_bound, int* content_range_upper_bound); 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_; + // Pointers back to our owning object so we can make callbacks as we parse + // pieces of data. + WebCore::ResourceHandleClient* client_; + WebCore::ResourceHandle* job_; // The original resource response for this request. We use this as a // starting point for each parts response. - WebKit::WebURLResponse original_response_; + WebCore::ResourceResponse 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). @@ -129,7 +128,3 @@ class MultipartResponseDelegate { // processing AddData requests. bool stop_sending_; }; - -} // namespace webkit_glue - -#endif diff --git a/webkit/glue/multipart_response_delegate_unittest.cc b/webkit/glue/multipart_response_delegate_unittest.cc index 3cafba2..e05879d 100644 --- a/webkit/glue/multipart_response_delegate_unittest.cc +++ b/webkit/glue/multipart_response_delegate_unittest.cc @@ -4,104 +4,71 @@ #include <vector> +#include "config.h" + +#include "base/compiler_specific.h" + +MSVC_PUSH_WARNING_LEVEL(0); +#include "KURL.h" +#include "ResourceResponse.h" +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +MSVC_POP_WARNING(); + #include "base/basictypes.h" -#include "webkit/api/public/WebString.h" -#include "webkit/api/public/WebURL.h" -#include "webkit/api/public/WebURLLoaderClient.h" -#include "webkit/api/public/WebURLResponse.h" #include "webkit/glue/glue_util.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 +using namespace WebCore; +using namespace std; namespace { class MultipartResponseTest : public testing::Test { }; -class MockWebURLLoaderClient : public WebURLLoaderClient { +class MockResourceHandleClient : public ResourceHandleClient { public: - MockWebURLLoaderClient() { Reset(); } + MockResourceHandleClient() { 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) { + virtual void didReceiveResponse(ResourceHandle* handle, + const ResourceResponse& response) { ++received_response_; - response_ = response; + resource_response_ = response; data_.clear(); } - virtual void didReceiveData(WebURLLoader* loader, + virtual void didReceiveData(ResourceHandle* handle, const char* data, int data_length, - long long length_received) { + int length_received) { ++received_data_; data_.append(data, data_length); } - virtual void didFinishLoading(WebURLLoader*) {} - virtual void didFail(WebURLLoader*, const WebURLError&) {} - void Reset() { received_response_ = received_data_ = 0; data_.clear(); - response_.reset(); + resource_response_ = ResourceResponse(); } int received_response_, received_data_; string data_; - WebURLResponse response_; + ResourceResponse resource_response_; }; +} // namespace + // 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(WebString::fromUTF8("multipart/x-mixed-replace")); - response.setHTTPHeaderField(WebString::fromUTF8("Foo"), - WebString::fromUTF8("Bar")); - response.setHTTPHeaderField(WebString::fromUTF8("Content-type"), - WebString::fromUTF8("text/plain")); - MockWebURLLoaderClient client; + ResourceResponse response(KURL(), "multipart/x-mixed-replace", 0, "en-US", + String()); + response.setHTTPHeaderField(String("Foo"), String("Bar")); + response.setHTTPHeaderField(String("Content-type"), String("text/plain")); + MockResourceHandleClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); - MultipartResponseDelegateTester delegate_tester(&delegate); struct { const char* input; @@ -123,8 +90,8 @@ TEST(MultipartResponseTest, Functions) { }; 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)); + delegate.PushOverLine(line_tests[i].input, + line_tests[i].position)); } // ParseHeaders tests @@ -145,33 +112,33 @@ TEST(MultipartResponseTest, Functions) { }; for (size_t i = 0; i < ARRAYSIZE_UNSAFE(header_tests); ++i) { client.Reset(); - delegate_tester.data().assign(header_tests[i].data); + delegate.data_.assign(header_tests[i].data); EXPECT_EQ(header_tests[i].rv, - delegate_tester.ParseHeaders()); + delegate.ParseHeaders()); EXPECT_EQ(header_tests[i].received_response_calls, client.received_response_); EXPECT_EQ(string(header_tests[i].newdata), - delegate_tester.data()); + delegate.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(webkit_glue::WebStringToStdString( - client.response_.httpHeaderField( - WebString::fromUTF8("Content-Type"))), - string("image/png")); - EXPECT_EQ(webkit_glue::WebStringToStdString( - client.response_.httpHeaderField( - WebString::fromUTF8("content-length"))), - string("10")); + delegate.data_.assign(test_header); + EXPECT_TRUE(delegate.ParseHeaders()); + EXPECT_TRUE(delegate.data_.length() == 0); + EXPECT_EQ(webkit_glue::StringToStdWString( + client.resource_response_.httpHeaderField( + String("Content-Type"))), + wstring(L"image/png")); + EXPECT_EQ(webkit_glue::StringToStdWString( + client.resource_response_.httpHeaderField( + String("content-length"))), + wstring(L"10")); // This header is passed from the original request. - EXPECT_EQ(webkit_glue::WebStringToStdString( - client.response_.httpHeaderField(WebString::fromUTF8("foo"))), - string("Bar")); + EXPECT_EQ(webkit_glue::StringToStdWString( + client.resource_response_.httpHeaderField(String("foo"))), + wstring(L"Bar")); // FindBoundary tests struct { @@ -187,22 +154,21 @@ TEST(MultipartResponseTest, Functions) { { "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); + delegate.boundary_.assign(boundary_tests[i].boundary); + delegate.data_.assign(boundary_tests[i].data); EXPECT_EQ(boundary_tests[i].position, - delegate_tester.FindBoundary()); + delegate.FindBoundary()); } } +namespace { + TEST(MultipartResponseTest, MissingBoundaries) { - WebURLResponse response; - response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - response.setHTTPHeaderField(WebString::fromUTF8("Foo"), - WebString::fromUTF8("Bar")); - response.setHTTPHeaderField(WebString::fromUTF8("Content-type"), - WebString::fromUTF8("text/plain")); - MockWebURLLoaderClient client; + ResourceResponse response(KURL(), "multipart/x-mixed-replace", 0, "en-US", + String()); + response.setHTTPHeaderField(String("Foo"), String("Bar")); + response.setHTTPHeaderField(String("Content-type"), String("text/plain")); + MockResourceHandleClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); // No start boundary @@ -262,14 +228,11 @@ TEST(MultipartResponseTest, MissingBoundaries) { TEST(MultipartResponseTest, MalformedBoundary) { // Some servers send a boundary that is prefixed by "--". See bug 5786. - WebURLResponse response; - response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - response.setHTTPHeaderField(WebString::fromUTF8("Foo"), - WebString::fromUTF8("Bar")); - response.setHTTPHeaderField(WebString::fromUTF8("Content-type"), - WebString::fromUTF8("text/plain")); - MockWebURLLoaderClient client; + ResourceResponse response(KURL(), "multipart/x-mixed-replace", 0, "en-US", + String()); + response.setHTTPHeaderField(String("Foo"), String("Bar")); + response.setHTTPHeaderField(String("Content-type"), String("text/plain")); + MockResourceHandleClient client; MultipartResponseDelegate delegate(&client, NULL, response, "--bound"); string data( @@ -309,14 +272,13 @@ void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size, int respon "foofoofoofoofoo" // 86-100 "--bound--"); // 101-109 - WebURLResponse response; - response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - MockWebURLLoaderClient client; + ResourceResponse response(KURL(), "multipart/x-mixed-replace", 0, "en-US", + String()); + MockResourceHandleClient 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); + ASSERT(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<int>(chunk.length())); @@ -423,10 +385,9 @@ TEST(MultipartResponseTest, BreakInData) { TEST(MultipartResponseTest, MultipleBoundaries) { // Test multiple boundaries back to back - WebURLResponse response; - response.initialize(); - response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - MockWebURLLoaderClient client; + ResourceResponse response(KURL(), "multipart/x-mixed-replace", 0, "en-US", + String()); + MockResourceHandleClient client; MultipartResponseDelegate delegate(&client, NULL, response, "bound"); string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--"); @@ -441,14 +402,12 @@ TEST(MultipartResponseTest, MultipleBoundaries) { TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { // Test multipart/byteranges based boundary parsing. - WebURLResponse response1; - response1.initialize(); - response1.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace")); - response1.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); + ResourceResponse response1(KURL(), "multipart/byteranges", 0, "en-US", + String()); + response1.setHTTPHeaderField(String("Content-Length"), String("200")); response1.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8("multipart/byteranges; boundary=--bound--")); + String("Content-type"), + String("multipart/byteranges; boundary=--bound--")); std::string multipart_boundary; bool result = MultipartResponseDelegate::ReadMultipartBoundary( @@ -457,39 +416,35 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { EXPECT_EQ(string("--bound--"), multipart_boundary); - WebURLResponse response2; - response2.initialize(); - response2.setMIMEType(WebString::fromUTF8("image/png")); + ResourceResponse response2(KURL(), "image/png", 0, "en-US", + String()); - response2.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("300")); + response2.setHTTPHeaderField(String("Content-Length"), String("300")); response2.setHTTPHeaderField( - WebString::fromUTF8("Last-Modified"), - WebString::fromUTF8("Mon, 04 Apr 2005 20:36:01 GMT")); + String("Last-Modified"), + String("Mon, 04 Apr 2005 20:36:01 GMT")); response2.setHTTPHeaderField( - WebString::fromUTF8("Date"), - WebString::fromUTF8("Thu, 11 Sep 2008 18:21:42 GMT")); + String("Date"), + String("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(WebString::fromUTF8("multipart/byteranges")); + ResourceResponse response3(KURL(), "multipart/byteranges", 0, "en-US", + String()); - response3.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("300")); + response3.setHTTPHeaderField(String("Content-Length"), String("300")); response3.setHTTPHeaderField( - WebString::fromUTF8("Last-Modified"), - WebString::fromUTF8("Mon, 04 Apr 2005 20:36:01 GMT")); + String("Last-Modified"), + String("Mon, 04 Apr 2005 20:36:01 GMT")); response3.setHTTPHeaderField( - WebString::fromUTF8("Date"), - WebString::fromUTF8("Thu, 11 Sep 2008 18:21:42 GMT")); + String("Date"), + String("Thu, 11 Sep 2008 18:21:42 GMT")); response3.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8("multipart/byteranges")); + String("Content-type"), + String("multipart/byteranges")); multipart_boundary.clear(); result = MultipartResponseDelegate::ReadMultipartBoundary( @@ -497,15 +452,12 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { EXPECT_EQ(result, false); EXPECT_EQ(multipart_boundary.length(), 0U); - WebURLResponse response4; - response4.initialize(); - response4.setMIMEType(WebString::fromUTF8("multipart/byteranges")); - response4.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); + ResourceResponse response4(KURL(), "multipart/byteranges", 0, "en-US", + String()); + response4.setHTTPHeaderField(String("Content-Length"), String("200")); response4.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8( - "multipart/byteranges; boundary=--bound--; charSet=utf8")); + String("Content-type"), + String("multipart/byteranges; boundary=--bound--; charSet=utf8")); multipart_boundary.clear(); @@ -514,15 +466,12 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { EXPECT_EQ(result, true); EXPECT_EQ(string("--bound--"), multipart_boundary); - WebURLResponse response5; - response5.initialize(); - response5.setMIMEType(WebString::fromUTF8("multipart/byteranges")); - response5.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); + ResourceResponse response5(KURL(), "multipart/byteranges", 0, "en-US", + String()); + response5.setHTTPHeaderField(String("Content-Length"), String("200")); response5.setHTTPHeaderField( - WebString::fromUTF8("Content-type"), - WebString::fromUTF8( - "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8")); + String("Content-type"), + String("multipart/byteranges; boundary=\"--bound--\"; charSet=utf8")); multipart_boundary.clear(); @@ -533,14 +482,12 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) { } TEST(MultipartResponseTest, MultipartContentRangesTest) { - WebURLResponse response1; - response1.initialize(); - response1.setMIMEType(WebString::fromUTF8("application/pdf")); - response1.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); + ResourceResponse response1(KURL(), "application/pdf", 0, "en-US", + String()); + response1.setHTTPHeaderField(String("Content-Length"), String("200")); response1.setHTTPHeaderField( - WebString::fromUTF8("Content-Range"), - WebString::fromUTF8("bytes 1000-1050/5000")); + String("Content-Range"), + String("bytes 1000-1050/5000")); int content_range_lower_bound = 0; int content_range_upper_bound = 0; @@ -553,14 +500,12 @@ TEST(MultipartResponseTest, MultipartContentRangesTest) { EXPECT_EQ(content_range_lower_bound, 1000); EXPECT_EQ(content_range_upper_bound, 1050); - WebURLResponse response2; - response2.initialize(); - response2.setMIMEType(WebString::fromUTF8("application/pdf")); - response2.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), - WebString::fromUTF8("200")); + ResourceResponse response2(KURL(), "application/pdf", 0, "en-US", + String()); + response2.setHTTPHeaderField(String("Content-Length"), String("200")); response2.setHTTPHeaderField( - WebString::fromUTF8("Content-Range"), - WebString::fromUTF8("bytes 1000/1050")); + String("Content-Range"), + String("bytes 1000/1050")); content_range_lower_bound = 0; content_range_upper_bound = 0; diff --git a/webkit/glue/resource_handle_impl.cc b/webkit/glue/resource_handle_impl.cc new file mode 100644 index 0000000..1912094 --- /dev/null +++ b/webkit/glue/resource_handle_impl.cc @@ -0,0 +1,765 @@ +// Copyright (c) 2006-2008 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. +// +// This file replaces WebCore/platform/network/win/ResourceHandleWin.cpp with a +// platform-neutral implementation that simply defers almost entirely to +// ResouceLoaderBridge. +// +// This uses the same ResourceHandle.h header file that the rest of WebKit +// uses, allowing us to avoid complicated changes. Our specific things are +// added on ResourceHandleInternal. The ResourceHandle owns the +// ResourceHandleInternal and passes off almost all processing to it. +// +// The WebKit version of this code keeps the ResourceHandle AddRef'd when +// there are any callbacks. This prevents the callbacks from occuring into +// destroyed objects. However, our destructors should always stop callbacks +// from happening, making this (hopefully) unnecessary. +// +// We preserve this behavior for safety. A client could count on this behavior +// and fire off a request, release it, and wait for callbacks to get the data +// as long as it doesn't care about canceling the request. Although this is +// dumb, we support it. We use pending_ to indicate this extra AddRef, which +// is done in start() and released in OnCompletedRequest. + +#include "config.h" + +#include "base/compiler_specific.h" + +MSVC_PUSH_WARNING_LEVEL(0); +#include "CString.h" +#include "DocLoader.h" +#include "FormData.h" +#include "FrameLoader.h" +#include "Page.h" +#include "ResourceError.h" +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +MSVC_POP_WARNING(); + +#undef LOG +#include "base/logging.h" +#include "base/message_loop.h" +#include "base/process_util.h" +#include "base/time.h" +#include "base/string_util.h" +#include "base/string_tokenizer.h" +#include "webkit/glue/feed_preview.h" +#include "webkit/glue/glue_util.h" +#include "webkit/glue/multipart_response_delegate.h" +#include "webkit/glue/resource_loader_bridge.h" +#include "net/base/data_url.h" +#include "net/base/net_errors.h" +#include "net/base/net_util.h" +#include "net/base/load_flags.h" +#include "net/http/http_response_headers.h" + +using webkit_glue::ResourceLoaderBridge; +using base::Time; +using base::TimeDelta; +using net::HttpResponseHeaders; + +namespace WebCore { + +static ResourceType::Type FromTargetType(ResourceRequest::TargetType type) { + switch (type) { + case ResourceRequest::TargetIsMainFrame: + return ResourceType::MAIN_FRAME; + case ResourceRequest::TargetIsSubFrame: + return ResourceType::SUB_FRAME; + case ResourceRequest::TargetIsSubResource: + return ResourceType::SUB_RESOURCE; + case ResourceRequest::TargetIsObject: + return ResourceType::OBJECT; + case ResourceRequest::TargetIsMedia: + return ResourceType::MEDIA; + default: + NOTREACHED(); + return ResourceType::SUB_RESOURCE; + } +} + +// Extracts the information from a data: url. +static bool GetInfoFromDataUrl(const GURL& url, + ResourceLoaderBridge::ResponseInfo* info, + std::string* data, URLRequestStatus* status) { + std::string mime_type; + std::string charset; + if (net::DataURL::Parse(url, &mime_type, &charset, data)) { + *status = URLRequestStatus(URLRequestStatus::SUCCESS, 0); + info->request_time = Time::Now(); + info->response_time = Time::Now(); + info->headers = NULL; + info->mime_type.swap(mime_type); + info->charset.swap(charset); + info->security_info.clear(); + info->content_length = -1; + + return true; + } + + *status = URLRequestStatus(URLRequestStatus::FAILED, net::ERR_INVALID_URL); + return false; +} + +static void ExtractInfoFromHeaders(const HttpResponseHeaders* headers, + HTTPHeaderMap* header_map, + int* status_code, + String* status_text, + long long* expected_content_length) { + *status_code = headers->response_code(); + + // Set the status text + *status_text = webkit_glue::StdStringToString(headers->GetStatusText()); + + // Set the content length. + std::string length_val; + if (headers->EnumerateHeader(NULL, "content-length", &length_val)) + *expected_content_length = StringToInt64(length_val); + + // Build up the header map. Take care with duplicate headers. + void* iter = NULL; + std::string name, value; + while (headers->EnumerateHeaderLines(&iter, &name, &value)) { + String name_str = webkit_glue::StdStringToString(name); + String value_str = webkit_glue::StdStringToString(value); + + pair<HTTPHeaderMap::iterator, bool> result = + header_map->add(name_str, value_str); + if (!result.second) + result.first->second += ", " + value_str; + } +} + +static ResourceResponse MakeResourceResponse( + const KURL& kurl, + const ResourceLoaderBridge::ResponseInfo& info) { + int status_code = 0; + long long expected_content_length = info.content_length; + String status_text; + HTTPHeaderMap header_map; + + // It's okay if there are no headers + if (info.headers) + ExtractInfoFromHeaders(info.headers, + &header_map, + &status_code, + &status_text, + &expected_content_length); + + // 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::wstring suggested_filename; + if (info.headers) { + std::string disp_val; + if (info.headers->EnumerateHeader(NULL, "content-disposition", &disp_val)) { + suggested_filename = net::GetSuggestedFilename( + webkit_glue::KURLToGURL(kurl), disp_val, "", std::wstring()); + } + } + + ResourceResponse response(kurl, + webkit_glue::StdStringToString(info.mime_type), + expected_content_length, + webkit_glue::StdStringToString(info.charset), + webkit_glue::StdWStringToString(suggested_filename)); + + if (info.headers) { + Time time_val; + if (info.headers->GetLastModifiedValue(&time_val)) + response.setLastModifiedDate(time_val.ToTimeT()); + + // Compute expiration date + TimeDelta freshness_lifetime = + info.headers->GetFreshnessLifetime(info.response_time); + if (freshness_lifetime != TimeDelta()) { + Time now = Time::Now(); + TimeDelta current_age = + info.headers->GetCurrentAge(info.request_time, info.response_time, + now); + time_val = now + freshness_lifetime - current_age; + + response.setExpirationDate(time_val.ToTimeT()); + } else { + // WebKit uses 0 as a special expiration date that means never expire. + // 1 is a small enough value to let it always expire. + response.setExpirationDate(1); + } + } + + response.setHTTPStatusCode(status_code); + response.setHTTPStatusText(status_text); + response.setSecurityInfo(webkit_glue::StdStringToCString(info.security_info)); + response.setAppCacheID(info.app_cache_id); + + // WebKit doesn't provide a way for us to set expected content length after + // calling the constructor, so we parse the headers first and then swap in + // our HTTP header map. Ideally we would like a setter for expected content + // length (perhaps by abstracting ResourceResponse interface into + // ResourceResponseBase) but that would require forking. + const_cast<HTTPHeaderMap*>(&response.httpHeaderFields())->swap(header_map); + + return response; +} + +class ResourceHandleInternal : public ResourceLoaderBridge::Peer { + public: + ResourceHandleInternal(ResourceHandle* job, const ResourceRequest& r, + ResourceHandleClient* c); + ~ResourceHandleInternal(); + + // If the response parameter is null, then an asynchronous load is started. + bool Start(ResourceLoaderBridge::SyncLoadResponse* response); + + // Used to cancel an asynchronous load. + void Cancel(); + + // Used to suspend/resume an asynchronous load. + void SetDefersLoading(bool value); + + // ResourceLoaderBridge::Peer implementation + virtual void OnUploadProgress(uint64 position, uint64 size); + virtual void OnReceivedRedirect(const GURL& new_url); + virtual void OnReceivedResponse( + const ResourceLoaderBridge::ResponseInfo& info, + bool content_filtered); + virtual void OnReceivedData(const char* data, int len); + virtual void OnCompletedRequest(const URLRequestStatus& status, + const std::string& security_info); + virtual std::string GetURLForDebugging(); + + // Handles a data: url internally instead of calling the bridge. + void HandleDataUrl(); + + // This is the bridge implemented by the embedder. + // The bridge is kept alive as long as the request is valid and we + // are ready for callbacks. + scoped_ptr<ResourceLoaderBridge> bridge_; + + // The resource loader that owns us + ResourceHandle* job_; + + // This is the object that receives various status messages (such as when the + // loader has received data). See definition for the exact messages that are + // sent to it. + ResourceHandleClient* client_; + + ResourceRequest request_; + + // Runnable Method Factory used to invoke later HandleDataUrl(). + ScopedRunnableMethodFactory<ResourceHandleInternal> data_url_factory_; + + int load_flags_; + + private: + // Set to true when we're waiting for data from the bridge, also indicating + // we have addrefed our job. + bool pending_; + + // Expected content length of the response + long long expected_content_length_; + + // NULL unless we are handling a multipart/x-mixed-replace request + scoped_ptr<MultipartResponseDelegate> multipart_delegate_; + + // NULL unless we are handling a feed:// request. + scoped_ptr<FeedClientProxy> feed_client_proxy_; +}; + +ResourceHandleInternal::ResourceHandleInternal(ResourceHandle* job, + const ResourceRequest& r, + ResourceHandleClient* c) + : job_(job), + client_(c), + request_(r), +MSVC_SUPPRESS_WARNING(4355) // can use this + data_url_factory_(this), + load_flags_(net::LOAD_NORMAL), + pending_(false), + expected_content_length_(-1), + multipart_delegate_(NULL) { +} + +ResourceHandleInternal::~ResourceHandleInternal() { + DCHECK(!pending_); +} + +void ResourceHandleInternal::HandleDataUrl() { + ResourceLoaderBridge::ResponseInfo info; + URLRequestStatus status; + std::string data; + + if (GetInfoFromDataUrl(webkit_glue::KURLToGURL(request_.url()), &info, &data, + &status)) { + OnReceivedResponse(info, false); + + if (data.size()) + OnReceivedData(data.c_str(), data.size()); + } + + OnCompletedRequest(status, info.security_info); + + // We are done using the object. ResourceHandle and ResourceHandleInternal + // might be destroyed now. + job_->deref(); +} + +bool ResourceHandleInternal::Start( + ResourceLoaderBridge::SyncLoadResponse* sync_load_response) { + DCHECK(!bridge_.get()); + + CString method = request_.httpMethod().latin1(); + GURL referrer(webkit_glue::StringToStdString(request_.httpReferrer())); + + // Compute the URL of the load. + GURL url = webkit_glue::KURLToGURL(request_.url()); + if (url.SchemeIs("feed:")) { + // Feed URLs are special, they actually mean "http". + url_canon::Replacements<char> replacements; + replacements.SetScheme("http", url_parse::Component(0, 4)); + url = url.ReplaceComponents(replacements); + + // Replace our client with a client that understands previewing feeds + // and forwards the feeds along to the original client. + feed_client_proxy_.reset(new FeedClientProxy(client_)); + client_ = feed_client_proxy_.get(); + } + + switch (request_.cachePolicy()) { + case ReloadIgnoringCacheData: + // Required by LayoutTests/http/tests/misc/refresh-headers.php + load_flags_ |= net::LOAD_VALIDATE_CACHE; + break; + case ReturnCacheDataElseLoad: + load_flags_ |= net::LOAD_PREFERRING_CACHE; + break; + case ReturnCacheDataDontLoad: + load_flags_ |= net::LOAD_ONLY_FROM_CACHE; + break; + case UseProtocolCachePolicy: + break; + } + + if (request_.reportUploadProgress()) + load_flags_ |= net::LOAD_ENABLE_UPLOAD_PROGRESS; + + // Translate the table of request headers to a formatted string blob + String headerBuf; + const HTTPHeaderMap& headerMap = request_.httpHeaderFields(); + + // In some cases, WebCore doesn't add an Accept header, but not having the + // header confuses some web servers. See bug 808613. + // Note: headerMap uses case-insenstive keys, so this will find Accept as + // as well. + if (!headerMap.contains("accept")) + request_.addHTTPHeaderField("Accept", "*/*"); + + const String crlf("\r\n"); + const String sep(": "); + for (HTTPHeaderMap::const_iterator it = headerMap.begin(); + it != headerMap.end(); ++it) { + // Skip over referrer headers found in the header map because we already + // pulled it out as a separate parameter. We likewise prune the UA since + // that will be added back by the network layer. + if (equalIgnoringCase((*it).first, "referer") || + equalIgnoringCase((*it).first, "user-agent")) + continue; + + // 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) && + equalIgnoringCase((*it).first, "cache-control") && + (*it).second == "max-age=0") + continue; + + if (!headerBuf.isEmpty()) + headerBuf.append(crlf); + headerBuf.append((*it).first + sep + (*it).second); + } + + // TODO(jcampan): in the non out-of-process plugin case the request does not + // have a requestor_pid. Find a better place to set this. + int requestor_pid = request_.requestorProcessID(); + if (requestor_pid == 0) + requestor_pid = base::GetCurrentProcId(); + + if (url.SchemeIs("data")) { + 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->status); + } else { + pending_ = true; + job_->ref(); // to be released when we get a OnCompletedRequest. + job_->ref(); // to be released when HandleDataUrl is completed. + MessageLoop::current()->PostTask(FROM_HERE, + data_url_factory_.NewRunnableMethod( + &ResourceHandleInternal::HandleDataUrl)); + } + return true; + } + + // TODO(abarth): These are wrong! I need to figure out how to get the right + // strings here. See: http://crbug.com/8706 + std::string frame_origin = + webkit_glue::StringToStdString(request_.firstPartyForCookies().string()); + std::string main_frame_origin = + webkit_glue::StringToStdString(request_.firstPartyForCookies().string()); + + // TODO(darin): is latin1 really correct here? It is if the strings are + // already ASCII (i.e., if they are already escaped properly). + // TODO(brettw) this should take parameter encoding into account when + // creating the GURLs. + bridge_.reset(ResourceLoaderBridge::Create( + webkit_glue::CStringToStdString(method), + url, + webkit_glue::KURLToGURL(request_.firstPartyForCookies()), + referrer, + frame_origin, + main_frame_origin, + webkit_glue::CStringToStdString(headerBuf.latin1()), + load_flags_, + requestor_pid, + FromTargetType(request_.targetType()), + request_.appCacheContextID(), + request_.requestorID())); + if (!bridge_.get()) + return false; + + if (request_.httpBody()) { + // GET and HEAD requests shouldn't have http bodies. + DCHECK(method != "GET" && method != "HEAD"); + const Vector<FormDataElement>& elements = request_.httpBody()->elements(); + size_t n = elements.size(); + for (size_t i = 0; i < n; ++i) { + const FormDataElement& e = elements[static_cast<unsigned>(i)]; + if (e.m_type == FormDataElement::data) { + if (e.m_data.size() > 0) { + // WebKit sometimes gives up empty data to append. These aren't + // necessary so we just optimize those out here. + bridge_->AppendDataToUpload(e.m_data.data(), + static_cast<int>(e.m_data.size())); + } + } else { + bridge_->AppendFileToUpload( + FilePath(webkit_glue::StringToFilePathString(e.m_filename))); + } + } + bridge_->SetUploadIdentifier(request_.httpBody()->identifier()); + } + + if (sync_load_response) { + bridge_->SyncLoad(sync_load_response); + return true; + } + + bool rv = bridge_->Start(this); + if (rv) { + pending_ = true; + job_->ref(); // to be released when we get a OnCompletedRequest. + } else { + bridge_.reset(); + } + + return rv; +} + +void ResourceHandleInternal::Cancel() { + // The bridge will still send OnCompletedRequest, which will deref() us, + // so we don't do that here. + if (bridge_.get()) + bridge_->Cancel(); + + // Ensure that we do not notify the multipart delegate anymore as it has + // its own pointer to the client. + multipart_delegate_.reset(); + + // Do not make any further calls to the client. + client_ = NULL; +} + +void ResourceHandleInternal::SetDefersLoading(bool value) { + if (bridge_.get()) + bridge_->SetDefersLoading(value); +} + +// ResourceLoaderBridge::Peer impl -------------------------------------------- + +void ResourceHandleInternal::OnUploadProgress(uint64 position, uint64 size) { + if (client_) + client_->didSendData(job_, position, size); +} + +void ResourceHandleInternal::OnReceivedRedirect(const GURL& new_url) { + DCHECK(pending_); + + KURL url = webkit_glue::GURLToKURL(new_url); + + // TODO(darin): need a way to properly initialize a ResourceResponse + ResourceResponse response(request_.url(), String(), -1, String(), String()); + + ResourceRequest new_request(url); + + // TODO(darin): we need to setup new_request to reflect the fact that we + // for example drop the httpBody when following a POST request that is + // redirected to a GET request. + + if (client_) + client_->willSendRequest(job_, new_request, response); + + // + // TODO(darin): since new_request is sent as a mutable reference, it is + // possible that willSendRequest may expect to be able to modify it. + // + // andresca on #webkit confirms that that is intentional, so we'll need + // to rework the ResourceLoaderBridge to give us control over what URL + // is really loaded (and with what headers) when a redirect is encountered. + // + + request_ = new_request; +} + +void ResourceHandleInternal::OnReceivedResponse( + const ResourceLoaderBridge::ResponseInfo& info, + bool content_filtered) { + DCHECK(pending_); + + // TODO(darin): need a way to properly initialize a ResourceResponse + ResourceResponse response = MakeResourceResponse(request_.url(), info); + response.setIsContentFiltered(content_filtered); + + expected_content_length_ = response.expectedContentLength(); + + if (client_) + client_->didReceiveResponse(job_, response); + + // we may have been cancelled after didReceiveResponse, which would leave us + // without a client and therefore without much need to do multipart handling. + + DCHECK(!multipart_delegate_.get()); + if (client_ && info.headers && response.isMultipart()) { + std::string content_type; + info.headers->EnumerateHeader(NULL, "content-type", &content_type); + + std::string boundary = net::GetHeaderParamValue(content_type, "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_, job_, + response, boundary)); + } + } + + // TODO(darin): generate willCacheResponse callback. debug mac webkit to + // determine when it should be called. +} + +void ResourceHandleInternal::OnReceivedData(const char* data, int data_len) { + DCHECK(pending_); + + if (client_) { + // TODO(darin): figure out what to pass for lengthReceived. from reading + // the loader code, it looks like this is supposed to be the content-length + // value, but it seems really wacky to include that here! we have to debug + // webkit on mac to figure out what this should be. + + // TODO(jackson): didReceiveData expects an int, but an expected content + // length is an int64, so we do our best to fit it inside an int. The only + // code that cares currently about this value is the Inspector, so beware + // that the Inspector's network panel might under-represent the size of + // some resources if they're larger than a gigabyte. + int lengthReceived = static_cast<int>(expected_content_length_); + if (lengthReceived != expected_content_length_) // overflow occurred + lengthReceived = -1; + + if (!multipart_delegate_.get()) { + client_->didReceiveData(job_, data, data_len, lengthReceived); + } else { + // AddData will make the appropriate calls to client_->didReceiveData + // and client_->didReceiveResponse + multipart_delegate_->OnReceivedData(data, data_len); + } + } +} + +void ResourceHandleInternal::OnCompletedRequest( + const URLRequestStatus& status, + const std::string& security_info) { + if (multipart_delegate_.get()) { + multipart_delegate_->OnCompletedRequest(); + multipart_delegate_.reset(NULL); + } + + pending_ = false; + + if (client_) { + if (status.status() != URLRequestStatus::SUCCESS) { + int error_code; + if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) { + // By marking this request as aborted we insure that we don't navigate + // to an error page. + error_code = net::ERR_ABORTED; + } else { + error_code = status.os_error(); + } + // TODO(tc): fill in these fields properly + ResourceError error(net::kErrorDomain, + error_code, + request_.url().string(), + String() /*localized description*/); + client_->didFail(job_, error); + } else { + client_->didFinishLoading(job_); + } + } + + job_->deref(); // may destroy our owner and hence |this| +} + +std::string ResourceHandleInternal::GetURLForDebugging() { + return webkit_glue::CStringToStdString(request_.url().string().latin1()); +} + +// ResourceHandle ------------------------------------------------------------- + +ResourceHandle::ResourceHandle(const ResourceRequest& request, + ResourceHandleClient* client, + bool defersLoading, + bool shouldContentSniff, + bool mightDownloadFromHandle) +MSVC_SUPPRESS_WARNING(4355) // it's okay to pass |this| here! + : d(new ResourceHandleInternal(this, request, client)) { + // TODO(darin): figure out what to do with the two bool params +} + +PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request, + ResourceHandleClient* client, + Frame* deprecated, + bool defersLoading, + bool shouldContentSniff, + bool mightDownloadFromHandle) { + RefPtr<ResourceHandle> newHandle = + adoptRef(new ResourceHandle(request, client, defersLoading, + shouldContentSniff, mightDownloadFromHandle)); + + if (newHandle->start(NULL)) + return newHandle.release(); + + return NULL; +} + +const ResourceRequest& ResourceHandle::request() const { + return d->request_; +} + +ResourceHandleClient* ResourceHandle::client() const { + return d->client_; +} + +void ResourceHandle::setClient(ResourceHandleClient* client) { + d->client_ = client; +} + +void ResourceHandle::setDefersLoading(bool value) { + d->SetDefersLoading(value); +} + +bool ResourceHandle::start(Frame* deprecated) { + return d->Start(NULL); +} + +void ResourceHandle::clearAuthentication() { + // TODO(darin): do something here. it looks like the ResourceLoader calls + // this method when it is canceled. i have no idea why it does this. +} + +void ResourceHandle::cancel() { + d->Cancel(); +} + +ResourceHandle::~ResourceHandle() { +} + +PassRefPtr<SharedBuffer> ResourceHandle::bufferedData() { + return NULL; +} + +/*static*/ bool ResourceHandle::loadsBlocked() { + return false; // this seems to be related to sync XMLHttpRequest... +} + +/*static*/ bool ResourceHandle::supportsBufferedData() { + return false; // the loader will buffer manually if it needs to +} + +/*static*/ void ResourceHandle::loadResourceSynchronously( + const ResourceRequest& request, StoredCredentials, ResourceError& error, + ResourceResponse& response, Vector<char>& data, Frame*) { + + RefPtr<ResourceHandle> handle = + adoptRef(new ResourceHandle(request, NULL, false, false, false)); + + ResourceLoaderBridge::SyncLoadResponse sync_load_response; + if (!handle->d->Start(&sync_load_response)) { + response = + ResourceResponse(request.url(), String(), 0, String(), String()); + // TODO(darin): what should the error code really be? + error = ResourceError(net::kErrorDomain, + net::ERR_FAILED, + request.url().string(), + String() /* localized description */); + return; + } + + KURL kurl = webkit_glue::GURLToKURL(sync_load_response.url); + + // TODO(tc): For file loads, we may want to include a more descriptive + // status code or status text. + const URLRequestStatus::Status& status = sync_load_response.status.status(); + if (status != URLRequestStatus::SUCCESS && + status != URLRequestStatus::HANDLED_EXTERNALLY) { + response = ResourceResponse(kurl, String(), 0, String(), String()); + error = ResourceError(net::kErrorDomain, + sync_load_response.status.os_error(), + kurl.string(), + String() /* localized description */); + return; + } + + response = MakeResourceResponse(kurl, sync_load_response); + + data.clear(); + data.append(sync_load_response.data.data(), + sync_load_response.data.size()); +} + +// static +bool ResourceHandle::willLoadFromCache(ResourceRequest& request) { + // + // This method is used to determine if a POST request can be repeated from + // cache, but you cannot really know until you actually try to read from the + // cache. Even if we checked now, something else could come along and wipe + // out the cache entry by the time we fetch it. + // + // So, we always say yes here, which allows us to generate an ERR_CACHE_MISS + // if the request cannot be serviced from cache. We force the 'DontLoad' + // cache policy at this point to ensure that we never hit the network for + // this request. + // + DCHECK(request.httpMethod() == "POST"); + request.setCachePolicy(ReturnCacheDataDontLoad); + return true; +} + +} // namespace WebCore diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index 91152f4..e075686 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -14,12 +14,10 @@ #include "webkit/api/public/WebString.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/webplugininfo.h" -#include "webkit/glue/weburlloader_impl.h" using WebKit::WebData; using WebKit::WebPluginListBuilder; using WebKit::WebThemeEngine; -using WebKit::WebURLLoader; namespace webkit_glue { @@ -36,10 +34,6 @@ WebThemeEngine* WebKitClientImpl::themeEngine() { #endif } -WebURLLoader* WebKitClientImpl::createURLLoader() { - return new WebURLLoaderImpl(); -} - void WebKitClientImpl::getPluginList(bool refresh, WebPluginListBuilder* builder) { std::vector<WebPluginInfo> plugins; diff --git a/webkit/glue/webkitclient_impl.h b/webkit/glue/webkitclient_impl.h index 54f691c..679cb61 100644 --- a/webkit/glue/webkitclient_impl.h +++ b/webkit/glue/webkitclient_impl.h @@ -21,7 +21,6 @@ class WebKitClientImpl : public WebKit::WebKitClient { // WebKitClient methods (partial implementation): virtual WebKit::WebThemeEngine* themeEngine(); - virtual WebKit::WebURLLoader* createURLLoader(); virtual void getPluginList(bool refresh, WebKit::WebPluginListBuilder*); virtual void decrementStatsCounter(const char* name); virtual void incrementStatsCounter(const char* name); diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc index e783c0d..0441000 100644 --- a/webkit/glue/webplugin_impl.cc +++ b/webkit/glue/webplugin_impl.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "config.h" +#include "webkit/glue/webplugin_impl.h" #include "Cursor.h" #include "Document.h" @@ -48,66 +49,44 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "net/base/escape.h" -#include "webkit/api/public/WebData.h" -#include "webkit/api/public/WebHTTPBody.h" #include "webkit/api/public/WebInputEvent.h" #include "webkit/api/public/WebKit.h" #include "webkit/api/public/WebKitClient.h" #include "webkit/api/public/WebString.h" #include "webkit/api/public/WebURL.h" -#include "webkit/api/public/WebURLLoader.h" -#include "webkit/api/public/WebURLLoaderClient.h" -#include "webkit/api/public/WebURLResponse.h" #include "webkit/glue/chrome_client_impl.h" #include "webkit/glue/event_conversion.h" #include "webkit/glue/glue_util.h" #include "webkit/glue/multipart_response_delegate.h" #include "webkit/glue/webcursor.h" #include "webkit/glue/webkit_glue.h" -#include "webkit/glue/webplugin_impl.h" #include "webkit/glue/plugins/plugin_host.h" #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/stacking_order_iterator.h" #include "webkit/glue/webview_impl.h" #include "googleurl/src/gurl.h" -using WebKit::WebData; -using WebKit::WebHTTPBody; -using WebKit::WebInputEvent; using WebKit::WebKeyboardEvent; +using WebKit::WebInputEvent; using WebKit::WebMouseEvent; -using WebKit::WebString; -using WebKit::WebURLError; -using WebKit::WebURLLoader; -using WebKit::WebURLLoaderClient; -using WebKit::WebURLRequest; -using WebKit::WebURLResponse; -using webkit_glue::MultipartResponseDelegate; // This class handles individual multipart responses. It is instantiated when // we receive HTTP status code 206 in the HTTP response. This indicates // that the response could have multiple parts each separated by a boundary // specified in the response header. -class MultiPartResponseClient : public WebURLLoaderClient { +class MultiPartResponseClient : public WebCore::ResourceHandleClient { public: MultiPartResponseClient(WebPluginResourceClient* resource_client) : resource_client_(resource_client) { Clear(); } - virtual void willSendRequest( - WebURLLoader*, WebURLRequest&, const WebURLResponse&) {} - virtual void didSendData( - WebURLLoader*, unsigned long long, unsigned long long) {} - // Called when the multipart parser encounters an embedded multipart // response. - virtual void didReceiveResponse( - WebURLLoader*, const WebURLResponse& response) { + virtual void didReceiveResponse(WebCore::ResourceHandle* handle, + const WebCore::ResourceResponse& response) { if (!MultipartResponseDelegate::ReadContentRanges( - response, - &byte_range_lower_bound_, - &byte_range_upper_bound_)) { + response, &byte_range_lower_bound_, &byte_range_upper_bound_)) { NOTREACHED(); return; } @@ -116,23 +95,21 @@ class MultiPartResponseClient : public WebURLLoaderClient { } // Receives individual part data from a multipart response. - virtual void didReceiveData( - WebURLLoader*, const char* data, int data_size, long long) { + virtual void didReceiveData(WebCore::ResourceHandle* handle, + const char* data, int data_size, + int reserved) { resource_client_->DidReceiveData( data, data_size, byte_range_lower_bound_); } - virtual void didFinishLoading(WebURLLoader*) {} - virtual void didFail(WebURLLoader*, const WebURLError&) {} - void Clear() { - resource_response_.reset(); + resource_response_ = WebCore::ResourceResponse(); byte_range_lower_bound_ = 0; byte_range_upper_bound_ = 0; } private: - WebURLResponse resource_response_; + WebCore::ResourceResponse resource_response_; // The lower bound of the byte range. int byte_range_lower_bound_; // The upper bound of the byte range. @@ -141,32 +118,6 @@ class MultiPartResponseClient : public WebURLLoaderClient { WebPluginResourceClient* resource_client_; }; -static std::wstring GetAllHeaders(const WebCore::ResourceResponse& response) { - std::wstring result; - const WebCore::String& status = response.httpStatusText(); - if (status.isEmpty()) - return result; - - result.append(L"HTTP "); - result.append(FormatNumber(response.httpStatusCode())); - result.append(L" "); - result.append(webkit_glue::StringToStdWString(status)); - result.append(L"\n"); - - WebCore::HTTPHeaderMap::const_iterator it = - response.httpHeaderFields().begin(); - for (; it != response.httpHeaderFields().end(); ++it) { - if (!it->first.isEmpty() && !it->second.isEmpty()) { - result.append(webkit_glue::StringToStdWString(it->first)); - result.append(L": "); - result.append(webkit_glue::StringToStdWString(it->second)); - result.append(L"\n"); - } - } - - return result; -} - WebPluginContainer::WebPluginContainer(WebPluginImpl* impl) : impl_(impl), ignore_response_error_(false) { @@ -303,7 +254,7 @@ void WebPluginContainer::didReceiveResponse( impl_->delegate_->DidReceiveManualResponse( http_response_info.url, base::SysWideToNativeMB(http_response_info.mime_type), - base::SysWideToNativeMB(GetAllHeaders(response)), + base::SysWideToNativeMB(impl_->GetAllHeaders(response)), http_response_info.expected_length, http_response_info.last_modified); } @@ -464,16 +415,17 @@ bool WebPluginImpl::ExecuteScript(const std::string& url, void WebPluginImpl::CancelResource(int id) { for (size_t i = 0; i < clients_.size(); ++i) { if (clients_[i].id == id) { - if (clients_[i].loader.get()) { - clients_[i].loader->cancel(); + if (clients_[i].handle) { + clients_[i].handle->cancel(); RemoveClient(i); } + return; } } } -bool WebPluginImpl::SetPostData(WebURLRequest* request, +bool WebPluginImpl::SetPostData(WebCore::ResourceRequest* request, const char *buf, uint32 length) { std::vector<std::string> names; @@ -481,26 +433,19 @@ bool WebPluginImpl::SetPostData(WebURLRequest* request, std::vector<char> body; bool rv = NPAPI::PluginHost::SetPostData(buf, length, &names, &values, &body); - for (size_t i = 0; i < names.size(); ++i) { - request->addHTTPHeaderField(webkit_glue::StdStringToWebString(names[i]), - webkit_glue::StdStringToWebString(values[i])); - } + for (size_t i = 0; i < names.size(); ++i) + request->addHTTPHeaderField(webkit_glue::StdStringToString(names[i]), + webkit_glue::StdStringToString(values[i])); - WebString content_type_header = WebString::fromUTF8("Content-Type"); - const WebString& content_type = - request->httpHeaderField(content_type_header); - if (content_type.isEmpty()) { - request->setHTTPHeaderField( - content_type_header, - WebString::fromUTF8("application/x-www-form-urlencoded")); - } + WebCore::String content_type = request->httpContentType(); + if (content_type.isEmpty()) + request->setHTTPContentType("application/x-www-form-urlencoded"); - WebHTTPBody http_body; - if (body.size()) { - http_body.initialize(); - http_body.appendData(WebData(&body[0], body.size())); - } - request->setHTTPBody(http_body); + RefPtr<WebCore::FormData> data = WebCore::FormData::create(); + if (body.size()) + data->appendData(&body.front(), body.size()); + + request->setHTTPBody(data.release()); return rv; } @@ -552,8 +497,8 @@ RoutingStatus WebPluginImpl::RouteToFrame(const char *method, } *completeURL = webkit_glue::KURLToGURL(complete_url_kurl); - WebURLRequest request(webkit_glue::KURLToWebURL(complete_url_kurl)); - request.setHTTPMethod(WebString::fromUTF8(method)); + WebCore::ResourceRequest request(complete_url_kurl); + request.setHTTPMethod(method); if (len > 0) { if (!is_file_data) { if (!SetPostData(&request, buf, len)) { @@ -569,8 +514,7 @@ RoutingStatus WebPluginImpl::RouteToFrame(const char *method, return ROUTED; } } - WebCore::FrameLoadRequest load_request( - *webkit_glue::WebURLRequestToResourceRequest(&request)); + WebCore::FrameLoadRequest load_request(request); load_request.setFrameName(str_target); WebCore::FrameLoader *loader = frame()->loader(); // we actually don't know whether usergesture is true or false, @@ -885,10 +829,10 @@ NPObject* WebPluginImpl::GetPluginScriptableObject() { return delegate_->GetPluginScriptableObject(); } -WebPluginResourceClient* WebPluginImpl::GetClientFromLoader( - WebURLLoader* loader) { +WebPluginResourceClient* WebPluginImpl::GetClientFromHandle( + WebCore::ResourceHandle* handle) { for (size_t i = 0; i < clients_.size(); ++i) { - if (clients_[i].loader.get() == loader) + if (clients_[i].handle.get() == handle) return clients_[i].client; } @@ -897,34 +841,54 @@ WebPluginResourceClient* WebPluginImpl::GetClientFromLoader( } -void WebPluginImpl::willSendRequest(WebURLLoader* loader, - WebURLRequest& request, - const WebURLResponse&) { - WebPluginResourceClient* client = GetClientFromLoader(loader); - if (client) - client->WillSendRequest(request.url()); +void WebPluginImpl::willSendRequest(WebCore::ResourceHandle* handle, + WebCore::ResourceRequest& request, + const WebCore::ResourceResponse&) { + WebPluginResourceClient* client = GetClientFromHandle(handle); + if (client) { + GURL gurl(webkit_glue::KURLToGURL(request.url())); + client->WillSendRequest(gurl); + } } -void WebPluginImpl::didSendData(WebURLLoader* loader, - unsigned long long bytes_sent, - unsigned long long total_bytes_to_be_sent) { +std::wstring WebPluginImpl::GetAllHeaders( + const WebCore::ResourceResponse& response) { + std::wstring result; + const WebCore::String& status = response.httpStatusText(); + if (status.isEmpty()) + return result; + + result.append(L"HTTP "); + result.append(FormatNumber(response.httpStatusCode())); + result.append(L" "); + result.append(webkit_glue::StringToStdWString(status)); + result.append(L"\n"); + + WebCore::HTTPHeaderMap::const_iterator it = + response.httpHeaderFields().begin(); + for (; it != response.httpHeaderFields().end(); ++it) { + if (!it->first.isEmpty() && !it->second.isEmpty()) { + result.append(webkit_glue::StringToStdWString(it->first)); + result.append(L": "); + result.append(webkit_glue::StringToStdWString(it->second)); + result.append(L"\n"); + } + } + + return result; } -void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, - const WebURLResponse& response) { +void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle, + const WebCore::ResourceResponse& response) { static const int kHttpPartialResponseStatusCode = 206; static const int kHttpResponseSuccessStatusCode = 200; - WebPluginResourceClient* client = GetClientFromLoader(loader); + WebPluginResourceClient* client = GetClientFromHandle(handle); if (!client) return; - - const WebCore::ResourceResponse& resource_response = - *webkit_glue::WebURLResponseToResourceResponse(&response); WebPluginContainer::HttpResponseInfo http_response_info; - WebPluginContainer::ReadHttpResponseInfo(resource_response, - &http_response_info); + WebPluginContainer::ReadHttpResponseInfo(response, &http_response_info); bool cancel = false; bool request_is_seekable = true; @@ -942,7 +906,7 @@ void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, // continue to remain valid. // 2. Create a new plugin instance and notify it about the response // received here. - if (!ReinitializePluginForResponse(loader)) { + if (!ReinitializePluginForResponse(handle)) { NOTREACHED(); return; } @@ -956,7 +920,7 @@ void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, // Create a new resource client for this request. for (size_t i = 0; i < clients_.size(); ++i) { - if (clients_[i].loader.get() == loader) { + if (clients_[i].handle.get() == handle) { WebPluginResourceClient* resource_client = delegate_->CreateResourceClient(clients_[i].id, plugin_url_.spec().c_str(), @@ -973,13 +937,13 @@ void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, client->DidReceiveResponse( base::SysWideToNativeMB(http_response_info.mime_type), - base::SysWideToNativeMB(GetAllHeaders(resource_response)), + base::SysWideToNativeMB(GetAllHeaders(response)), http_response_info.expected_length, http_response_info.last_modified, request_is_seekable, &cancel); if (cancel) { - loader->cancel(); - RemoveClient(loader); + handle->cancel(); + RemoveClient(handle); return; } @@ -988,41 +952,41 @@ void WebPluginImpl::didReceiveResponse(WebURLLoader* loader, // fate of the HTTP requests issued via NPN_GetURLNotify. Webkit and FF // destroy the stream and invoke the NPP_DestroyStream function on the // plugin if the HTTP request fails. - const GURL& url = response.url(); - if (url.SchemeIs("http") || url.SchemeIs("https")) { + const WebCore::String& protocol_scheme = response.url().protocol(); + if ((protocol_scheme == "http") || (protocol_scheme == "https")) { if (response.httpStatusCode() < 100 || response.httpStatusCode() >= 400) { // The plugin instance could be in the process of deletion here. // Verify if the WebPluginResourceClient instance still exists before // use. - WebPluginResourceClient* resource_client = GetClientFromLoader(loader); + WebPluginResourceClient* resource_client = GetClientFromHandle(handle); if (resource_client) { - loader->cancel(); + handle->cancel(); resource_client->DidFail(); - RemoveClient(loader); + RemoveClient(handle); } } } } -void WebPluginImpl::didReceiveData(WebURLLoader* loader, +void WebPluginImpl::didReceiveData(WebCore::ResourceHandle* handle, const char *buffer, - int length, long long) { - WebPluginResourceClient* client = GetClientFromLoader(loader); - if (!client) - return; - MultiPartResponseHandlerMap::iterator index = - multi_part_response_map_.find(client); - if (index != multi_part_response_map_.end()) { - MultipartResponseDelegate* multi_part_handler = (*index).second; - DCHECK(multi_part_handler != NULL); - multi_part_handler->OnReceivedData(buffer, length); - } else { - client->DidReceiveData(buffer, length, 0); + int length, int) { + WebPluginResourceClient* client = GetClientFromHandle(handle); + if (client) { + MultiPartResponseHandlerMap::iterator index = + multi_part_response_map_.find(client); + if (index != multi_part_response_map_.end()) { + MultipartResponseDelegate* multi_part_handler = (*index).second; + DCHECK(multi_part_handler != NULL); + multi_part_handler->OnReceivedData(buffer, length); + } else { + client->DidReceiveData(buffer, length, 0); + } } } -void WebPluginImpl::didFinishLoading(WebURLLoader* loader) { - WebPluginResourceClient* client = GetClientFromLoader(loader); +void WebPluginImpl::didFinishLoading(WebCore::ResourceHandle* handle) { + WebPluginResourceClient* client = GetClientFromHandle(handle); if (client) { MultiPartResponseHandlerMap::iterator index = multi_part_response_map_.find(client); @@ -1036,25 +1000,25 @@ void WebPluginImpl::didFinishLoading(WebURLLoader* loader) { client->DidFinishLoading(); } - RemoveClient(loader); + RemoveClient(handle); } -void WebPluginImpl::didFail(WebURLLoader* loader, - const WebURLError&) { - WebPluginResourceClient* client = GetClientFromLoader(loader); +void WebPluginImpl::didFail(WebCore::ResourceHandle* handle, + const WebCore::ResourceError&) { + WebPluginResourceClient* client = GetClientFromHandle(handle); if (client) client->DidFail(); - RemoveClient(loader); + RemoveClient(handle); } void WebPluginImpl::RemoveClient(size_t i) { clients_.erase(clients_.begin() + i); } -void WebPluginImpl::RemoveClient(WebURLLoader* loader) { +void WebPluginImpl::RemoveClient(WebCore::ResourceHandle* handle) { for (size_t i = 0; i < clients_.size(); ++i) { - if (clients_[i].loader.get() == loader) { + if (clients_[i].handle.get() == handle) { RemoveClient(i); return; } @@ -1186,19 +1150,18 @@ bool WebPluginImpl::InitiateHTTPRequest(int resource_id, return false; } + WebCore::KURL kurl = webkit_glue::GURLToKURL(url); + ClientInfo info; info.id = resource_id; info.client = client; - info.request.initialize(); - info.request.setURL(url); + info.request.setURL(kurl); info.request.setRequestorProcessID(delegate_->GetProcessId()); - info.request.setTargetType(WebURLRequest::TargetIsObject); - info.request.setHTTPMethod(WebString::fromUTF8(method)); + info.request.setTargetType(WebCore::ResourceRequest::TargetIsObject); + info.request.setHTTPMethod(method); - if (range_info) { - info.request.addHTTPHeaderField(WebString::fromUTF8("Range"), - WebString::fromUTF8(range_info)); - } + if (range_info) + info.request.addHTTPHeaderField("Range", range_info); WebCore::String referrer; // GetURL/PostURL requests initiated explicitly by plugins should specify the @@ -1209,11 +1172,8 @@ bool WebPluginImpl::InitiateHTTPRequest(int resource_id, referrer = frame()->loader()->outgoingReferrer(); } - if (!WebCore::FrameLoader::shouldHideReferrer(webkit_glue::GURLToKURL(url), - referrer)) { - info.request.setHTTPHeaderField(WebString::fromUTF8("Referer"), - webkit_glue::StringToWebString(referrer)); - } + if (!WebCore::FrameLoader::shouldHideReferrer(kurl, referrer)) + info.request.setHTTPReferrer(referrer); if (strcmp(method, "POST") == 0) { // Adds headers or form data to a request. This must be called before @@ -1224,15 +1184,13 @@ bool WebPluginImpl::InitiateHTTPRequest(int resource_id, // Sets the routing id to associate the ResourceRequest with the RenderView. WebCore::ResourceResponse response; frame()->loader()->client()->dispatchWillSendRequest( - NULL, - 0, - *webkit_glue::WebURLRequestToMutableResourceRequest(&info.request), - response); + NULL, 0, info.request, response); - info.loader.reset(WebKit::webKitClient()->createURLLoader()); - if (!info.loader.get()) + info.handle = WebCore::ResourceHandle::create( + info.request, this, NULL, false, false); + if (!info.handle) { return false; - info.loader->loadAsynchronously(info.request, this); + } clients_.push_back(info); return true; @@ -1263,7 +1221,7 @@ void WebPluginImpl::InitiateHTTPRangeRequest(const char* url, } void WebPluginImpl::HandleHttpMultipartResponse( - const WebURLResponse& response, + const WebCore::ResourceResponse& response, WebPluginResourceClient* client) { std::string multipart_boundary; if (!MultipartResponseDelegate::ReadMultipartBoundary( @@ -1286,7 +1244,7 @@ void WebPluginImpl::HandleHttpMultipartResponse( } bool WebPluginImpl::ReinitializePluginForResponse( - WebURLLoader* loader) { + WebCore::ResourceHandle* response_handle) { WebFrameImpl* web_frame = WebFrameImpl::FromFrame(frame()); if (!web_frame) return false; @@ -1298,7 +1256,7 @@ bool WebPluginImpl::ReinitializePluginForResponse( WebPluginContainer* container_widget = widget_; // Destroy the current plugin instance. - TearDownPluginInstance(loader); + TearDownPluginInstance(response_handle); widget_ = container_widget; webframe_ = web_frame; @@ -1352,7 +1310,7 @@ void WebPluginImpl::ArrayToVector(int total_values, char** values, } void WebPluginImpl::TearDownPluginInstance( - WebURLLoader* loader_to_ignore) { + WebCore::ResourceHandle* response_handle_to_ignore) { // The frame maintains a list of JSObjects which are related to this // plugin. Tell the frame we're gone so that it can invalidate all // of those sub JSObjects. @@ -1374,13 +1332,13 @@ void WebPluginImpl::TearDownPluginInstance( while (client_index != clients_.end()) { ClientInfo& client_info = *client_index; - if (loader_to_ignore == client_info.loader) { + if (response_handle_to_ignore == client_info.handle) { client_index++; continue; } - if (client_info.loader.get()) - client_info.loader->cancel(); + if (client_info.handle) + client_info.handle->cancel(); WebPluginResourceClient* resource_client = client_info.client; client_index = clients_.erase(client_index); diff --git a/webkit/glue/webplugin_impl.h b/webkit/glue/webplugin_impl.h index 1c3be91..8d14792 100644 --- a/webkit/glue/webplugin_impl.h +++ b/webkit/glue/webplugin_impl.h @@ -9,43 +9,41 @@ #include <map> #include <vector> +#include "config.h" +#include "base/compiler_specific.h" +#include "base/gfx/native_widget_types.h" + +MSVC_PUSH_WARNING_LEVEL(0); +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +#include "ResourceRequest.h" #include "Widget.h" +MSVC_POP_WARNING(); #include "base/basictypes.h" -#include "base/gfx/native_widget_types.h" -#include "base/linked_ptr.h" -#include "webkit/api/public/WebURLLoaderClient.h" -#include "webkit/api/public/WebURLRequest.h" #include "webkit/glue/webframe_impl.h" #include "webkit/glue/webplugin.h" #include "webkit/glue/webplugin_delegate.h" - class WebFrameImpl; class WebPluginDelegate; class WebPluginImpl; +class MultipartResponseDelegate; namespace WebCore { -class Event; -class Frame; -class HTMLPlugInElement; -class IntRect; -class KeyboardEvent; -class KURL; -class MouseEvent; -class ResourceError; -class ResourceResponse; -class ScrollView; -class String; -class Widget; -} - -namespace WebKit { -class WebURLResponse; -} - -namespace webkit_glue { -class MultipartResponseDelegate; + class Event; + class Frame; + class HTMLPlugInElement; + class IntRect; + class KeyboardEvent; + class KURL; + class MouseEvent; + class ResourceHandle; + class ResourceError; + class ResourceResponse; + class ScrollView; + class String; + class Widget; } // Implements WebCore::Widget functions that WebPluginImpl needs. This class @@ -117,7 +115,7 @@ class WebPluginContainer : public WebCore::Widget { // after changing out of WebCore types, to a delegate. The delegate will // be in a different process. class WebPluginImpl : public WebPlugin, - public WebKit::WebURLLoaderClient { + public WebCore::ResourceHandleClient { public: // Creates a WebPlugin instance, as long as the delegate's initialization // succeeds. If it fails, the delegate is deleted and NULL is returned. @@ -136,7 +134,7 @@ class WebPluginImpl : public WebPlugin, virtual NPObject* GetPluginScriptableObject(); // Helper function for sorting post data. - static bool SetPostData(WebKit::WebURLRequest* request, + static bool SetPostData(WebCore::ResourceRequest* request, const char* buf, uint32 length); @@ -242,28 +240,27 @@ class WebPluginImpl : public WebPlugin, // Destroys the plugin instance. // The response_handle_to_ignore parameter if not NULL indicates the // resource handle to be left valid during plugin shutdown. - void TearDownPluginInstance(WebKit::WebURLLoader* loader_to_ignore); + void TearDownPluginInstance( + WebCore::ResourceHandle* response_handle_to_ignore); WebCore::ScrollView* parent() const; - // WebURLLoaderClient implementation. We implement this interface in the + // ResourceHandleClient implementation. We implement this interface in the // renderer process, and then use the simple WebPluginResourceClient interface // to relay the callbacks to the plugin. - virtual void willSendRequest(WebKit::WebURLLoader* loader, - WebKit::WebURLRequest& request, - const WebKit::WebURLResponse&); - virtual void didSendData(WebKit::WebURLLoader* loader, - unsigned long long bytes_sent, - unsigned long long total_bytes_to_be_sent); - virtual void didReceiveResponse(WebKit::WebURLLoader* loader, - const WebKit::WebURLResponse& response); - virtual void didReceiveData(WebKit::WebURLLoader* loader, const char *buffer, - int length, long long total_length); - virtual void didFinishLoading(WebKit::WebURLLoader* loader); - virtual void didFail(WebKit::WebURLLoader* loader, const WebKit::WebURLError&); + void willSendRequest(WebCore::ResourceHandle* handle, + WebCore::ResourceRequest& request, + const WebCore::ResourceResponse&); + + void didReceiveResponse(WebCore::ResourceHandle* handle, + const WebCore::ResourceResponse& response); + void didReceiveData(WebCore::ResourceHandle* handle, const char *buffer, + int length, int); + void didFinishLoading(WebCore::ResourceHandle* handle); + void didFail(WebCore::ResourceHandle* handle, const WebCore::ResourceError&); // Helper function - WebPluginResourceClient* GetClientFromLoader(WebKit::WebURLLoader* loader); + WebPluginResourceClient* GetClientFromHandle(WebCore::ResourceHandle* handle); // Helper function to remove the stored information about a resource // request given its index in m_clients. @@ -271,7 +268,10 @@ class WebPluginImpl : public WebPlugin, // Helper function to remove the stored information about a resource // request given a handle. - void RemoveClient(WebKit::WebURLLoader* loader); + void RemoveClient(WebCore::ResourceHandle* handle); + + // Returns all the response headers in one string, including the status code. + std::wstring GetAllHeaders(const WebCore::ResourceResponse& response); WebCore::Frame* frame() { return webframe_ ? webframe_->frame() : NULL; } @@ -300,7 +300,7 @@ class WebPluginImpl : public WebPlugin, // Handles HTTP multipart responses, i.e. responses received with a HTTP // status code of 206. - void HandleHttpMultipartResponse(const WebKit::WebURLResponse& response, + void HandleHttpMultipartResponse(const WebCore::ResourceResponse& response, WebPluginResourceClient* client); void HandleURLRequestInternal(const char *method, bool is_javascript_url, @@ -311,8 +311,8 @@ class WebPluginImpl : public WebPlugin, bool use_plugin_src_as_referrer); // Tears down the existing plugin instance and creates a new plugin instance - // to handle the response identified by the loader parameter. - bool ReinitializePluginForResponse(WebKit::WebURLLoader* loader); + // to handle the response identified by the response_handle parameter. + bool ReinitializePluginForResponse(WebCore::ResourceHandle* response_handle); // Helper functions to convert an array of names/values to a vector. static void ArrayToVector(int total_values, char** values, @@ -321,8 +321,8 @@ class WebPluginImpl : public WebPlugin, struct ClientInfo { int id; WebPluginResourceClient* client; - WebKit::WebURLRequest request; - linked_ptr<WebKit::WebURLLoader> loader; + WebCore::ResourceRequest request; + RefPtr<WebCore::ResourceHandle> handle; }; std::vector<ClientInfo> clients_; @@ -336,8 +336,7 @@ class WebPluginImpl : public WebPlugin, WebPluginContainer* widget_; - typedef std::map<WebPluginResourceClient*, - webkit_glue::MultipartResponseDelegate*> + typedef std::map<WebPluginResourceClient*, MultipartResponseDelegate*> MultiPartResponseHandlerMap; // Tracks HTTP multipart response handlers instantiated for // a WebPluginResourceClient instance. diff --git a/webkit/glue/webplugin_impl_unittest.cc b/webkit/glue/webplugin_impl_unittest.cc index b6c62f6..b518361 100644 --- a/webkit/glue/webplugin_impl_unittest.cc +++ b/webkit/glue/webplugin_impl_unittest.cc @@ -4,21 +4,18 @@ #include "config.h" -// Avoid collisions with the LOG macro -#include <wtf/Assertions.h> +#include "testing/gtest/include/gtest/gtest.h" + +#include "base/compiler_specific.h" + +MSVC_PUSH_WARNING_LEVEL(0); +#include "ResourceRequest.h" +#include "CString.h" +MSVC_POP_WARNING(); #undef LOG -#include "base/string_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "webkit/api/public/WebString.h" -#include "webkit/api/public/WebURLRequest.h" -#include "webkit/glue/glue_util.h" #include "webkit/glue/webplugin_impl.h" -using WebKit::WebHTTPBody; -using WebKit::WebString; -using WebKit::WebURLRequest; - namespace { class WebPluginImplTest : public testing::Test { @@ -33,34 +30,6 @@ std::ostream& operator<<(std::ostream& out, const WebCore::String& str) return out << str.latin1().data(); } -static std::string GetHeader(const WebURLRequest& request, const char* name) { - std::string result; - TrimWhitespace( - webkit_glue::WebStringToStdString( - request.httpHeaderField(WebString::fromUTF8(name))), - TRIM_ALL, - &result); - return result; -} - -static std::string GetBodyText(const WebURLRequest& request) { - const WebHTTPBody& body = request.httpBody(); - if (body.isNull()) - return std::string(); - - std::string result; - size_t i = 0; - WebHTTPBody::Element element; - while (body.elementAt(i++, element)) { - if (element.type == WebHTTPBody::Element::TypeData) { - result.append(element.data.data(), element.data.size()); - } else { - NOTREACHED() << "unexpected element type encountered!"; - } - } - return result; -} - // The Host functions for NPN_PostURL and NPN_PostURLNotify // need to parse out some HTTP headers. Make sure it works // with the following tests @@ -68,47 +37,46 @@ static std::string GetBodyText(const WebURLRequest& request) { TEST(WebPluginImplTest, PostParserSimple) { // Test a simple case with headers & data const char *ex1 = "foo: bar\nContent-length: 10\n\nabcdefghij"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ("bar", GetHeader(request, "foo")); - EXPECT_EQ(0U, GetHeader(request, "bar").length()); - EXPECT_EQ(0U, GetHeader(request, "Content-length").length()); - EXPECT_EQ("abcdefghij", GetBodyText(request)); + EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace()); + EXPECT_EQ(0U, request.httpHeaderField("bar").length()); + EXPECT_EQ(0U, request.httpHeaderField("Content-length").length()); + EXPECT_EQ("abcdefghij", request.httpBody()->flattenToString()); } TEST(WebPluginImplTest, PostParserLongHeader) { // Test a simple case with long headers const char *ex1 = "foo: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n\nabcdefghij"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ(100U, GetHeader(request, "foo").length()); + EXPECT_EQ(100U, request.httpHeaderField("foo").stripWhiteSpace().length()); } TEST(WebPluginImplTest, PostParserManyHeaders) { // Test a simple case with long headers const char *ex1 = "h1:h1\nh2:h2\nh3:h3\nh4:h4\nh5:h5\nh6:h6\nh7:h7\nh8:h8\nh9:h9\nh10:h10\n\nbody"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ("h1", GetHeader(request, "h1")); - EXPECT_EQ("h2", GetHeader(request, "h2")); - EXPECT_EQ("h3", GetHeader(request, "h3")); - EXPECT_EQ("h4", GetHeader(request, "h4")); - EXPECT_EQ("h5", GetHeader(request, "h5")); - EXPECT_EQ("h6", GetHeader(request, "h6")); - EXPECT_EQ("h7", GetHeader(request, "h7")); - EXPECT_EQ("h8", GetHeader(request, "h8")); - EXPECT_EQ("h9", GetHeader(request, "h9")); - EXPECT_EQ("h10", GetHeader(request, "h10")); - EXPECT_EQ("body", GetBodyText(request)); + EXPECT_EQ("h1", request.httpHeaderField("h1").stripWhiteSpace()); + EXPECT_EQ("h2", request.httpHeaderField("h2").stripWhiteSpace()); + EXPECT_EQ("h3", request.httpHeaderField("h3").stripWhiteSpace()); + EXPECT_EQ("h4", request.httpHeaderField("h4").stripWhiteSpace()); + EXPECT_EQ("h5", request.httpHeaderField("h5").stripWhiteSpace()); + EXPECT_EQ("h6", request.httpHeaderField("h6").stripWhiteSpace()); + EXPECT_EQ("h7", request.httpHeaderField("h7").stripWhiteSpace()); + EXPECT_EQ("h8", request.httpHeaderField("h8").stripWhiteSpace()); + EXPECT_EQ("h9", request.httpHeaderField("h9").stripWhiteSpace()); + EXPECT_EQ("h10", request.httpHeaderField("h10").stripWhiteSpace()); + WebCore::FormData *form_data = request.httpBody(); + WebCore::String string_data = form_data->flattenToString(); + EXPECT_EQ(string_data, "body"); } TEST(WebPluginImplTest, PostParserDuplicateHeaders) { @@ -116,8 +84,7 @@ TEST(WebPluginImplTest, PostParserDuplicateHeaders) { // What value gets returned doesn't really matter. It shouldn't error // out. const char *ex1 = "h1:h1\nh1:h2\n\nbody"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); @@ -126,47 +93,43 @@ TEST(WebPluginImplTest, PostParserDuplicateHeaders) { TEST(WebPluginImplTest, PostParserNoHeaders) { // Test a simple case with no headers but with data const char *ex1 = "\nabcdefghij"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ(0U, GetHeader(request, "foo").length()); - EXPECT_EQ(0U, GetHeader(request, "bar").length()); - EXPECT_EQ(0U, GetHeader(request, "Content-length").length()); - EXPECT_EQ("abcdefghij", GetBodyText(request)); + EXPECT_EQ(0U, request.httpHeaderField("foo").length()); + EXPECT_EQ(0U, request.httpHeaderField("bar").length()); + EXPECT_EQ(0U, request.httpHeaderField("Content-length").length()); + EXPECT_EQ("abcdefghij", request.httpBody()->flattenToString()); } TEST(WebPluginImplTest, PostParserNoBody) { // Test a simple case with headers and no body const char *ex1 = "Foo:bar\n\n"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ("bar", GetHeader(request, "foo")); - EXPECT_EQ(0U, GetHeader(request, "bar").length()); - EXPECT_EQ(0U, GetHeader(request, "Content-length").length()); - EXPECT_EQ(0U, GetBodyText(request).length()); + EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace()); + EXPECT_EQ(0U, request.httpHeaderField("bar").length()); + EXPECT_EQ(0U, request.httpHeaderField("Content-length").length()); + EXPECT_EQ(0U, request.httpBody()->flattenToString().length()); } TEST(WebPluginImplTest, PostParserBodyWithNewLines) { // Test a simple case with headers and no body const char *ex1 = "Foo:bar\n\n\n\nabcdefg\n\nabcdefg"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ(GetBodyText(request), "\n\nabcdefg\n\nabcdefg"); + EXPECT_EQ(request.httpBody()->flattenToString(), "\n\nabcdefg\n\nabcdefg"); } TEST(WebPluginImplTest, PostParserErrorNoBody) { // Test with headers and no body const char *ex1 = "Foo:bar\n"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); @@ -175,8 +138,7 @@ TEST(WebPluginImplTest, PostParserErrorNoBody) { TEST(WebPluginImplTest, PostParserErrorEmpty) { // Test with an empty string const char *ex1 = ""; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); @@ -185,39 +147,36 @@ TEST(WebPluginImplTest, PostParserErrorEmpty) { TEST(WebPluginImplTest, PostParserEmptyName) { // Test an error case with an empty header name field const char *ex1 = "foo:bar\n:blat\n\nbody"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ("bar", GetHeader(request, "foo")); - EXPECT_EQ("body", GetBodyText(request)); + EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace()); + EXPECT_EQ("body", request.httpBody()->flattenToString()); } TEST(WebPluginImplTest, PostParserEmptyValue) { // Test an error case with an empty value field const char *ex1 = "foo:bar\nbar:\n\nbody"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ("bar", GetHeader(request, "foo")); - EXPECT_EQ(0U, GetHeader(request, "bar").length()); - EXPECT_EQ("body", GetBodyText(request)); + EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace()); + EXPECT_EQ(0U, request.httpHeaderField("bar").length()); + EXPECT_EQ("body", request.httpBody()->flattenToString()); } TEST(WebPluginImplTest, PostParserCRLF) { // Test an error case with an empty value field const char *ex1 = "foo: bar\r\nbar:\r\n\r\nbody\r\n\r\nbody2"; - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, static_cast<uint32>(strlen(ex1))); EXPECT_EQ(true, rv); - EXPECT_EQ("bar", GetHeader(request, "foo")); - EXPECT_EQ(0U, GetHeader(request, "bar").length()); - EXPECT_EQ("body\r\n\r\nbody2", GetBodyText(request)); + EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace()); + EXPECT_EQ(0U, request.httpHeaderField("bar").length()); + EXPECT_EQ("body\r\n\r\nbody2", request.httpBody()->flattenToString()); } TEST(WebPluginImplTest, PostParserBodyWithBinaryData) { @@ -227,19 +186,19 @@ TEST(WebPluginImplTest, PostParserBodyWithBinaryData) { memcpy(ex1 + strlen("foo: bar\nContent-length: 10\n\n"), &binary_data, sizeof(binary_data)); - WebURLRequest request; - request.initialize(); + WebCore::ResourceRequest request; bool rv = WebPluginImpl::SetPostData(&request, ex1, sizeof(ex1)/sizeof(ex1[0])); EXPECT_EQ(true, rv); - EXPECT_EQ("bar", GetHeader(request, "foo")); - EXPECT_EQ(0U, GetHeader(request, "bar").length()); - EXPECT_EQ(0U, GetHeader(request, "Content-length").length()); + EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace()); + EXPECT_EQ(0U, request.httpHeaderField("bar").length()); + EXPECT_EQ(0U, request.httpHeaderField("Content-length").length()); - std::string body = GetBodyText(request); + Vector<char> expected_data; + request.httpBody()->flatten(expected_data); - EXPECT_EQ(0xF0, (unsigned char)body[0]); - EXPECT_EQ(0xFF, (unsigned char)body[1]); - EXPECT_EQ(0xFF, (unsigned char)body[2]); - EXPECT_EQ(0xFF, (unsigned char)body[3]); + EXPECT_EQ(0xF0, (unsigned char)expected_data[0]); + EXPECT_EQ(0xFF, (unsigned char)expected_data[1]); + EXPECT_EQ(0xFF, (unsigned char)expected_data[2]); + EXPECT_EQ(0xFF, (unsigned char)expected_data[3]); } diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc deleted file mode 100644 index da9d2747..0000000 --- a/webkit/glue/weburlloader_impl.cc +++ /dev/null @@ -1,502 +0,0 @@ -// Copyright (c) 2006-2009 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/message_loop.h" -#include "base/process_util.h" -#include "base/string_util.h" -#include "base/time.h" -#include "net/base/data_url.h" -#include "net/base/load_flags.h" -#include "net/base/net_errors.h" -#include "net/base/net_util.h" -#include "net/http/http_response_headers.h" -#include "webkit/api/public/WebHTTPHeaderVisitor.h" -#include "webkit/api/public/WebURL.h" -#include "webkit/api/public/WebURLError.h" -#include "webkit/api/public/WebURLLoaderClient.h" -#include "webkit/api/public/WebURLRequest.h" -#include "webkit/api/public/WebURLResponse.h" -#include "webkit/glue/glue_util.h" -#include "webkit/glue/webkit_glue.h" - -using base::Time; -using base::TimeDelta; -using WebKit::WebData; -using WebKit::WebHTTPBody; -using WebKit::WebHTTPHeaderVisitor; -using WebKit::WebString; -using WebKit::WebURLError; -using WebKit::WebURLLoader; -using WebKit::WebURLLoaderClient; -using WebKit::WebURLRequest; -using WebKit::WebURLResponse; - -namespace webkit_glue { - -namespace { - -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 = WebStringToStdString(name); - const std::string& value_utf8 = WebStringToStdString(value); - - // Skip over referrer headers found in the header map because we already - // pulled it out as a separate parameter. We likewise prune the UA since - // that will be added back by the network layer. - if (LowerCaseEqualsASCII(name_utf8, "referer") || - LowerCaseEqualsASCII(name_utf8, "user-agent")) - 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_; -}; - -ResourceType::Type 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::TargetIsObject: - return ResourceType::OBJECT; - case WebURLRequest::TargetIsMedia: - return ResourceType::MEDIA; - default: - NOTREACHED(); - return ResourceType::SUB_RESOURCE; - } -} - -// Extracts the information from a data: url. -bool GetInfoFromDataURL(const GURL& url, - ResourceLoaderBridge::ResponseInfo* info, - std::string* data, URLRequestStatus* status) { - std::string mime_type; - std::string charset; - if (net::DataURL::Parse(url, &mime_type, &charset, data)) { - *status = URLRequestStatus(URLRequestStatus::SUCCESS, 0); - info->request_time = Time::Now(); - info->response_time = Time::Now(); - info->headers = NULL; - info->mime_type.swap(mime_type); - info->charset.swap(charset); - info->security_info.clear(); - info->content_length = -1; - - return true; - } - - *status = URLRequestStatus(URLRequestStatus::FAILED, net::ERR_INVALID_URL); - return false; -} - -void PopulateURLResponse( - const GURL& url, - const ResourceLoaderBridge::ResponseInfo& info, - WebURLResponse* response) { - response->setURL(url); - response->setMIMEType(StdStringToWebString(info.mime_type)); - response->setTextEncodingName(StdStringToWebString(info.charset)); - response->setExpectedContentLength(info.content_length); - response->setSecurityInfo(info.security_info); - response->setAppCacheID(info.app_cache_id); - - const net::HttpResponseHeaders* headers = info.headers; - if (!headers) - return; - - response->setHTTPStatusCode(headers->response_code()); - response->setHTTPStatusText(StdStringToWebString(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; - if (headers->EnumerateHeader(NULL, "content-disposition", &value)) { - response->setSuggestedFileName(WideToUTF16Hack( - net::GetSuggestedFilename(url, value, "", std::wstring()))); - } - - Time time_val; - if (headers->GetLastModifiedValue(&time_val)) - response->setLastModifiedDate(time_val.ToDoubleT()); - - // Compute expiration date - TimeDelta freshness_lifetime = - headers->GetFreshnessLifetime(info.response_time); - if (freshness_lifetime != TimeDelta()) { - Time now = Time::Now(); - TimeDelta current_age = - headers->GetCurrentAge(info.request_time, info.response_time, now); - time_val = now + freshness_lifetime - current_age; - - response->setExpirationDate(time_val.ToDoubleT()); - } else { - // WebKit uses 0 as a special expiration date that means never expire. - // 1 is a small enough value to let it always expire. - response->setExpirationDate(1); - } - - // Build up the header map. - void* iter = NULL; - std::string name; - while (headers->EnumerateHeaderLines(&iter, &name, &value)) { - response->addHTTPHeaderField(StdStringToWebString(name), - StdStringToWebString(value)); - } -} - -} // namespace - -WebURLLoaderImpl::WebURLLoaderImpl() - : ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), - client_(NULL) { -} - -WebURLLoaderImpl::~WebURLLoaderImpl() { -} - -void WebURLLoaderImpl::loadSynchronously(const WebURLRequest& request, - WebURLResponse& response, - WebURLError& error, - WebData& data) { - ResourceLoaderBridge::SyncLoadResponse sync_load_response; - Start(request, &sync_load_response); - - 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. - const URLRequestStatus::Status& status = sync_load_response.status.status(); - if (status != URLRequestStatus::SUCCESS && - status != URLRequestStatus::HANDLED_EXTERNALLY) { - response.setURL(final_url); - error.domain = WebString::fromUTF8(net::kErrorDomain); - error.reason = sync_load_response.status.os_error(); - 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(!client_); - - client_ = client; - Start(request, NULL); -} - -void WebURLLoaderImpl::cancel() { - // The bridge will still send OnCompletedRequest, which will deref() us, - // so we don't do that here. - if (bridge_.get()) - bridge_->Cancel(); - - // Ensure that we do not notify the multipart delegate anymore as it has - // its own pointer to the client. - multipart_delegate_.reset(); - - // Do not make any further calls to the client. - client_ = NULL; -} - -void WebURLLoaderImpl::setDefersLoading(bool value) { - if (bridge_.get()) - bridge_->SetDefersLoading(value); -} - -void WebURLLoaderImpl::OnUploadProgress(uint64 position, uint64 size) { - if (client_) - client_->didSendData(this, position, size); -} - -void WebURLLoaderImpl::OnReceivedRedirect(const GURL& new_url) { - if (!client_) - return; - - // TODO(darin): We lack sufficient information to construct the - // actual redirect response, so we just simulate it here. - WebURLResponse response(url_); - - // TODO(darin): We lack sufficient information to construct the - // actual request that resulted from the redirect, so we just - // report a GET navigation to the new location. - WebURLRequest new_request(new_url); - - url_ = new_url; - client_->willSendRequest(this, new_request, response); - - // TODO(darin): since new_request is sent as a mutable reference, it is - // possible that willSendRequest may have modified it. - // - // andresca on #webkit confirms that that is intentional, so we'll need - // to rework the ResourceLoaderBridge to give us control over what URL - // is really loaded (and with what headers) when a redirect is encountered. - // TODO(darin): we fail this assertion in some layout tests! - //DCHECK(GURL(new_request.url()) == new_url); -} - -void WebURLLoaderImpl::OnReceivedResponse( - const ResourceLoaderBridge::ResponseInfo& info, - bool content_filtered) { - if (!client_) - return; - - WebURLResponse response; - response.initialize(); - PopulateURLResponse(url_, info, &response); - response.setIsContentFiltered(content_filtered); - - expected_content_length_ = response.expectedContentLength(); - - client_->didReceiveResponse(this, response); - - // we may have been cancelled after didReceiveResponse, which would leave us - // without a client and therefore without much need to do multipart handling. - if (!client_) - return; - - DCHECK(!multipart_delegate_.get()); - if (info.headers && info.mime_type == "multipart/x-mixed-replace") { - std::string content_type; - info.headers->EnumerateHeader(NULL, "content-type", &content_type); - - std::string boundary = net::GetHeaderParamValue(content_type, "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_, this, response, boundary)); - } - } -} - -void WebURLLoaderImpl::OnReceivedData(const char* data, int len) { - if (!client_) - return; - - if (multipart_delegate_.get()) { - // The multipart delegate will make the appropriate calls to - // client_->didReceiveData and client_->didReceiveResponse. - multipart_delegate_->OnReceivedData(data, len); - } else { - client_->didReceiveData(this, data, len, expected_content_length_); - } -} - -void WebURLLoaderImpl::OnCompletedRequest(const URLRequestStatus& status, - const std::string& security_info) { - if (multipart_delegate_.get()) { - multipart_delegate_->OnCompletedRequest(); - multipart_delegate_.reset(NULL); - } - - if (!client_) - return; - - if (status.status() != URLRequestStatus::SUCCESS) { - int error_code; - if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) { - // By marking this request as aborted we insure that we don't navigate - // to an error page. - error_code = net::ERR_ABORTED; - } else { - error_code = status.os_error(); - } - WebURLError error; - error.domain = WebString::fromUTF8(net::kErrorDomain); - error.reason = error_code; - error.unreachableURL = url_; - client_->didFail(this, error); - } else { - client_->didFinishLoading(this); - } -} - -std::string WebURLLoaderImpl::GetURLForDebugging() { - return url_.spec(); -} - -void WebURLLoaderImpl::Start( - const WebURLRequest& request, - ResourceLoaderBridge::SyncLoadResponse* sync_load_response) { - DCHECK(!bridge_.get()); - - url_ = request.url(); - if (url_.SchemeIs("data")) { - 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->status); - } else { - MessageLoop::current()->PostTask(FROM_HERE, - task_factory_.NewRunnableMethod(&WebURLLoaderImpl::HandleDataURL)); - } - return; - } - - GURL referrer_url(WebStringToStdString( - request.httpHeaderField(WebString::fromUTF8("Referer")))); - const std::string& method = WebStringToStdString(request.httpMethod()); - - 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; - - // TODO(jcampan): in the non out-of-process plugin case the request does not - // have a requestor_pid. Find a better place to set this. - int requestor_pid = request.requestorProcessID(); - if (requestor_pid == 0) - requestor_pid = base::GetCurrentProcId(); - - HeaderFlattener flattener(load_flags); - request.visitHTTPHeaderFields(&flattener); - - // TODO(abarth): These are wrong! I need to figure out how to get the right - // strings here. See: http://crbug.com/8706 - std::string frame_origin = request.firstPartyForCookies().spec(); - std::string main_frame_origin = request.firstPartyForCookies().spec(); - - // TODO(brettw) this should take parameter encoding into account when - // creating the GURLs. - bridge_.reset(ResourceLoaderBridge::Create( - method, - url_, - request.firstPartyForCookies(), - referrer_url, - frame_origin, - main_frame_origin, - flattener.GetBuffer(), - load_flags, - requestor_pid, - FromTargetType(request.targetType()), - request.appCacheContextID(), - request.requestorID())); - - 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; - 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. - bridge_->AppendDataToUpload( - element.data.data(), static_cast<int>(element.data.size())); - } - break; - case WebHTTPBody::Element::TypeFile: - bridge_->AppendFileToUpload( - FilePath(WebStringToFilePathString(element.filePath))); - break; - default: - NOTREACHED(); - } - } - bridge_->SetUploadIdentifier(request.httpBody().identifier()); - } - - if (sync_load_response) { - bridge_->SyncLoad(sync_load_response); - return; - } - - if (!bridge_->Start(this)) - bridge_.reset(); -} - -void WebURLLoaderImpl::HandleDataURL() { - if (!client_) - return; - - ResourceLoaderBridge::ResponseInfo info; - URLRequestStatus status; - std::string data; - - if (GetInfoFromDataURL(url_, &info, &data, &status)) { - OnReceivedResponse(info, false); - if (!data.empty()) - OnReceivedData(data.data(), data.size()); - } - - OnCompletedRequest(status, info.security_info); -} - -} // namespace webkit_glue diff --git a/webkit/glue/weburlloader_impl.h b/webkit/glue/weburlloader_impl.h deleted file mode 100644 index 2ad50c3..0000000 --- a/webkit/glue/weburlloader_impl.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2009 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/scoped_ptr.h" -#include "base/task.h" -#include "webkit/api/public/WebURLLoader.h" -#include "webkit/glue/multipart_response_delegate.h" -#include "webkit/glue/resource_loader_bridge.h" - -namespace webkit_glue { - -class WebURLLoaderImpl : public WebKit::WebURLLoader, - public ResourceLoaderBridge::Peer { - public: - WebURLLoaderImpl(); - ~WebURLLoaderImpl(); - - // 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); - - // ResourceLoaderBridge::Peer methods: - virtual void OnUploadProgress(uint64 position, uint64 size); - virtual void OnReceivedRedirect(const GURL& new_url); - virtual void OnReceivedResponse( - const ResourceLoaderBridge::ResponseInfo& info, bool content_filtered); - virtual void OnReceivedData(const char* data, int len); - virtual void OnCompletedRequest( - const URLRequestStatus& status, const std::string& security_info); - virtual std::string GetURLForDebugging(); - - private: - void Start( - const WebKit::WebURLRequest& request, - ResourceLoaderBridge::SyncLoadResponse* sync_load_response); - void HandleDataURL(); - - ScopedRunnableMethodFactory<WebURLLoaderImpl> task_factory_; - - GURL url_; - WebKit::WebURLLoaderClient* client_; - scoped_ptr<ResourceLoaderBridge> bridge_; - scoped_ptr<MultipartResponseDelegate> multipart_delegate_; - int64 expected_content_length_; -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_WEBURLLOADER_IMPL_H_ |