summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-30 21:16:51 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-30 21:16:51 +0000
commit35cb9e1d4ad928a981a305a8f1d1d805c65e0cd5 (patch)
treeff56ff6e26a5a926bfaeb080c6c5bea124c2a87a /webkit
parent335fb4f3221673af83ecae7414b666bfecf42e2b (diff)
downloadchromium_src-35cb9e1d4ad928a981a305a8f1d1d805c65e0cd5.zip
chromium_src-35cb9e1d4ad928a981a305a8f1d1d805c65e0cd5.tar.gz
chromium_src-35cb9e1d4ad928a981a305a8f1d1d805c65e0cd5.tar.bz2
Start using WebURLLoader, et. al. from the WebKit API.
Moves our ResourceHandle to webkit/api/src/ResourceHandle.cpp from webkit/glue/resource_handle_impl.cc. A portion of resource_handle_impl.cc was moved into weburlloader_impl.{h,cc}, which now contains our implementation of WebURLLoader. The annoying parts of this CL involve WebPluginImpl. I had to convert it over to using WebURLLoader instead of ResourceHandle so that MultipartResourceDelegate can be shared. There is some complexity in WebURLRequest / WebURLResponse to make it cheap to wrap a ResourceRequest / ResourceResponse. I think this is worth it since there is a lot of conversion between the two types. BUG=10038 TEST=covered by existing tests R=dglazkov Review URL: http://codereview.chromium.org/113928 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17290 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/api/public/WebHTTPBody.h51
-rw-r--r--webkit/api/public/WebHTTPHeaderVisitor.h44
-rw-r--r--webkit/api/public/WebKitClient.h4
-rw-r--r--webkit/api/public/WebNonCopyable.h49
-rw-r--r--webkit/api/public/WebURLError.h9
-rw-r--r--webkit/api/public/WebURLLoader.h8
-rw-r--r--webkit/api/public/WebURLLoaderClient.h18
-rw-r--r--webkit/api/public/WebURLRequest.h78
-rw-r--r--webkit/api/public/WebURLResponse.h77
-rw-r--r--webkit/api/src/ResourceHandle.cpp279
-rw-r--r--webkit/api/src/WebDragData.cpp5
-rw-r--r--webkit/api/src/WebHTTPBody.cpp124
-rw-r--r--webkit/api/src/WebURLError.cpp69
-rw-r--r--webkit/api/src/WebURLRequest.cpp246
-rw-r--r--webkit/api/src/WebURLRequestPrivate.h53
-rw-r--r--webkit/api/src/WebURLResponse.cpp259
-rw-r--r--webkit/api/src/WebURLResponsePrivate.h50
-rw-r--r--webkit/api/src/WrappedResourceRequest.h67
-rw-r--r--webkit/api/src/WrappedResourceResponse.h68
-rw-r--r--webkit/glue/glue_util.cc42
-rw-r--r--webkit/glue/glue_util.h20
-rw-r--r--webkit/glue/multipart_response_delegate.cc162
-rw-r--r--webkit/glue/multipart_response_delegate.h57
-rw-r--r--webkit/glue/multipart_response_delegate_unittest.cc277
-rw-r--r--webkit/glue/resource_handle_impl.cc765
-rw-r--r--webkit/glue/webkitclient_impl.cc6
-rw-r--r--webkit/glue/webkitclient_impl.h1
-rw-r--r--webkit/glue/webplugin_impl.cc288
-rw-r--r--webkit/glue/webplugin_impl.h99
-rw-r--r--webkit/glue/webplugin_impl_unittest.cc171
-rw-r--r--webkit/glue/weburlloader_impl.cc501
-rw-r--r--webkit/glue/weburlloader_impl.h61
-rw-r--r--webkit/webkit.gyp19
33 files changed, 2726 insertions, 1301 deletions
diff --git a/webkit/api/public/WebHTTPBody.h b/webkit/api/public/WebHTTPBody.h
index 1a4f49c..06d37fe 100644
--- a/webkit/api/public/WebHTTPBody.h
+++ b/webkit/api/public/WebHTTPBody.h
@@ -31,23 +31,62 @@
#ifndef WebHTTPBody_h
#define WebHTTPBody_h
-#error "This header file is still a work in progress; do not include!"
-
#include "WebData.h"
+#include "WebNonCopyable.h"
#include "WebString.h"
-#include "WebVector.h"
+
+#if WEBKIT_IMPLEMENTATION
+namespace WebCore { class FormData; }
+namespace WTF { template <typename T> class PassRefPtr; }
+#endif
namespace WebKit {
+ class WebHTTPBodyPrivate;
- struct WebHTTPBody {
+ class WebHTTPBody : public WebNonCopyable {
+ public:
struct Element {
enum { TypeData, TypeFile } type;
WebData data;
- WebString fileName;
+ WebString filePath;
};
- WebVector<Element> elements;
+
+ ~WebHTTPBody() { reset(); }
+
+ WebHTTPBody() : m_private(0) { }
+
+ bool isNull() const { return m_private == 0; }
+
+ WEBKIT_API void initialize();
+ WEBKIT_API void reset();
+
+ // Returns the number of elements comprising the http body.
+ WEBKIT_API size_t elementCount() const;
+
+ // Sets the values of the element at the given index. Returns false if
+ // index is out of bounds.
+ WEBKIT_API bool elementAt(size_t index, Element&) const;
+
+ // Append to the list of elements.
+ WEBKIT_API void appendData(const WebData&);
+ WEBKIT_API void appendFile(const WebString&);
+
+ // Identifies a particular form submission instance. A value of 0 is
+ // used to indicate an unspecified identifier.
+ WEBKIT_API long long identifier() const;
+ WEBKIT_API void setIdentifier(long long);
+
+#if WEBKIT_IMPLEMENTATION
+ void rebind(WTF::PassRefPtr<WebCore::FormData>);
+ operator WTF::PassRefPtr<WebCore::FormData>() const;
+#endif
+
+ private:
+ void assign(WebHTTPBodyPrivate*);
+ WebHTTPBodyPrivate* m_private;
};
+
} // namespace WebKit
#endif
diff --git a/webkit/api/public/WebHTTPHeaderVisitor.h b/webkit/api/public/WebHTTPHeaderVisitor.h
new file mode 100644
index 0000000..b61d3da
--- /dev/null
+++ b/webkit/api/public/WebHTTPHeaderVisitor.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebHTTPHeaderVisitor_h
+#define WebHTTPHeaderVisitor_h
+
+namespace WebKit {
+ class WebString;
+
+ class WebHTTPHeaderVisitor {
+ public:
+ virtual void visitHeader(const WebString& name, const WebString& value) = 0;
+ };
+
+} // namespace WebKit
+
+#endif
diff --git a/webkit/api/public/WebKitClient.h b/webkit/api/public/WebKitClient.h
index 5b136d5..87ff7b7e 100644
--- a/webkit/api/public/WebKitClient.h
+++ b/webkit/api/public/WebKitClient.h
@@ -42,6 +42,7 @@ namespace WebKit {
class WebString;
class WebThemeEngine;
class WebURL;
+ class WebURLLoader;
struct WebPluginInfo;
template <typename T> class WebVector;
@@ -81,6 +82,9 @@ namespace WebKit {
// A suggestion to prefetch IP information for the given hostname.
virtual void prefetchHostName(const WebString&) = 0;
+ // Returns a new WebURLLoader instance.
+ virtual WebURLLoader* createURLLoader() = 0;
+
// Plugins -------------------------------------------------------------
diff --git a/webkit/api/public/WebNonCopyable.h b/webkit/api/public/WebNonCopyable.h
new file mode 100644
index 0000000..df4b482
--- /dev/null
+++ b/webkit/api/public/WebNonCopyable.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebNonCopyable_h
+#define WebNonCopyable_h
+
+namespace WebKit {
+
+ // A base class to extend from if you do not support copying.
+ class WebNonCopyable {
+ protected:
+ WebNonCopyable() { }
+ ~WebNonCopyable() { }
+
+ private:
+ WebNonCopyable(const WebNonCopyable&);
+ WebNonCopyable& operator=(const WebNonCopyable&);
+ };
+
+} // namespace WebKit
+
+#endif
diff --git a/webkit/api/public/WebURLError.h b/webkit/api/public/WebURLError.h
index 6332b5e..c4cfe46 100644
--- a/webkit/api/public/WebURLError.h
+++ b/webkit/api/public/WebURLError.h
@@ -31,8 +31,6 @@
#ifndef WebURLError_h
#define WebURLError_h
-#error "This header file is still a work in progress; do not include!"
-
#include "WebString.h"
#include "WebURL.h"
@@ -48,9 +46,10 @@ namespace WebKit {
// string as it will just be passed via callbacks to the consumer.
WebString domain;
- // A numeric reason for the error. WebKit does not care about the
- // value of this field as it will just be passed via callbacks to the
- // consumer.
+ // A numeric error code detailing the reason for this error. A value
+ // of 0 means no error. WebKit does not interpret the meaning of other
+ // values and normally just forwards this error information back to the
+ // embedder (see for example WebFrameClient).
int reason;
// The url that failed to load.
diff --git a/webkit/api/public/WebURLLoader.h b/webkit/api/public/WebURLLoader.h
index 721fe60..8bc8a94 100644
--- a/webkit/api/public/WebURLLoader.h
+++ b/webkit/api/public/WebURLLoader.h
@@ -31,16 +31,14 @@
#ifndef WebURLLoader_h
#define WebURLLoader_h
-#error "This header file is still a work in progress; do not include!"
-
#include "WebCommon.h"
namespace WebKit {
- class WebCString;
- class WebURLError;
+ class WebData;
class WebURLLoaderClient;
class WebURLRequest;
class WebURLResponse;
+ struct WebURLError;
class WebURLLoader {
public:
@@ -50,7 +48,7 @@ namespace WebKit {
// caller upon completion. There is no mechanism to interrupt a
// synchronous load!!
virtual void loadSynchronously(const WebURLRequest&,
- WebURLResponse&, WebURLError&, WebCString& data) = 0;
+ WebURLResponse&, WebURLError&, WebData& data) = 0;
// Load the request asynchronously, sending notifications to the given
// client. The client will receive no further notifications if the
diff --git a/webkit/api/public/WebURLLoaderClient.h b/webkit/api/public/WebURLLoaderClient.h
index 3a0a761..16ea87e 100644
--- a/webkit/api/public/WebURLLoaderClient.h
+++ b/webkit/api/public/WebURLLoaderClient.h
@@ -31,33 +31,35 @@
#ifndef WebURLLoaderClient_h
#define WebURLLoaderClient_h
-#error "This header file is still a work in progress; do not include!"
-
namespace WebKit {
+ class WebURLLoader;
+ class WebURLRequest;
+ class WebURLResponse;
+ struct WebURLError;
class WebURLLoaderClient {
public:
// Called when following a redirect. |newRequest| contains the request
// generated by the redirect. The client may modify |newRequest|.
virtual void willSendRequest(
- WebURLRequest& newRequest, const WebURLResponse& redirectResponse) = 0;
+ WebURLLoader*, WebURLRequest& newRequest, const WebURLResponse& redirectResponse) = 0;
// Called to report upload progress. The bytes reported correspond to
// the HTTP message body.
virtual void didSendData(
- unsigned long long bytesSent, unsigned long long totalBytesToBeSent) = 0;
+ WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) = 0;
// Called when response headers are received.
- virtual void didReceiveResponse(const WebURLResponse&) = 0;
+ virtual void didReceiveResponse(WebURLLoader*, const WebURLResponse&) = 0;
// Called when a chunk of response data is received.
- virtual void didReceiveData(const char* data, int dataLength, int totalDataLength) = 0;
+ virtual void didReceiveData(WebURLLoader*, const char* data, int dataLength, long long totalDataLength) = 0;
// Called when the load completes successfully.
- virtual void didFinishLoading() = 0;
+ virtual void didFinishLoading(WebURLLoader*) = 0;
// Called when the load completes with an error.
- virtual void didFail(const WebURLError&) = 0;
+ virtual void didFail(WebURLLoader*, const WebURLError&) = 0;
};
} // namespace WebKit
diff --git a/webkit/api/public/WebURLRequest.h b/webkit/api/public/WebURLRequest.h
index c7b9bec..8399624 100644
--- a/webkit/api/public/WebURLRequest.h
+++ b/webkit/api/public/WebURLRequest.h
@@ -31,14 +31,17 @@
#ifndef WebURLRequest_h
#define WebURLRequest_h
-#error "This header file is still a work in progress; do not include!"
-
#include "WebCommon.h"
#include "WebHTTPBody.h"
+#if defined(WEBKIT_IMPLEMENTATION)
+namespace WebCore { struct ResourceRequest; }
+#endif
+
namespace WebKit {
class WebCString;
class WebHTTPBody;
+ class WebHTTPHeaderVisitor;
class WebString;
class WebURL;
class WebURLRequestPrivate;
@@ -66,58 +69,75 @@ namespace WebKit {
WebURLRequest(const WebURLRequest& r) : m_private(0) { assign(r); }
WebURLRequest& operator=(const WebURLRequest& r) { assign(r); return *this; }
+ explicit WebURLRequest(const WebURL& url) : m_private(0)
+ {
+ initialize();
+ setURL(url);
+ }
+
WEBKIT_API void initialize();
WEBKIT_API void reset();
WEBKIT_API void assign(const WebURLRequest&);
bool isNull() const { return m_private == 0; }
- WEBKIT_API WebURL url() const = 0;
- WEBKIT_API void setURL(const WebURL&) = 0;
+ WEBKIT_API WebURL url() const;
+ WEBKIT_API void setURL(const WebURL&);
// Used to implement third-party cookie blocking.
- WEBKIT_API WebURL firstPartyForCookies() const = 0;
- WEBKIT_API void setFirstPartyForCookies(const WebURL&) = 0;
+ WEBKIT_API WebURL firstPartyForCookies() const;
+ WEBKIT_API void setFirstPartyForCookies(const WebURL&);
+
+ WEBKIT_API CachePolicy cachePolicy() const;
+ WEBKIT_API void setCachePolicy(CachePolicy);
- WEBKIT_API CachePolicy cachePolicy() const = 0;
- WEBKIT_API void setCachePolicy(CachePolicy) = 0;
+ WEBKIT_API WebString httpMethod() const;
+ WEBKIT_API void setHTTPMethod(const WebString&);
- WEBKIT_API WebString httpMethod() const = 0;
- WEBKIT_API void setHTTPMethod(const WebString&) = 0;
+ WEBKIT_API WebString httpHeaderField(const WebString& name) const;
+ WEBKIT_API void setHTTPHeaderField(const WebString& name, const WebString& value);
+ WEBKIT_API void addHTTPHeaderField(const WebString& name, const WebString& value);
+ WEBKIT_API void clearHTTPHeaderField(const WebString& name);
+ WEBKIT_API void visitHTTPHeaderFields(WebHTTPHeaderVisitor*) const;
- WEBKIT_API WebString httpHeaderField(const WebString& name) const = 0;
- WEBKIT_API void setHTTPHeaderField(const WebString& name, const WebString& value) = 0;
- WEBKIT_API void addHTTPHeaderField(const WebString& name, const WebString& value) = 0;
- WEBKIT_API void clearHTTPHeaderField(const WebString& name) = 0;
+ WEBKIT_API const WebHTTPBody& httpBody() const;
+ WEBKIT_API void setHTTPBody(const WebHTTPBody&);
- WEBKIT_API bool hasHTTPBody() const = 0;
- WEBKIT_API void httpBody(WebHTTPBody&) const = 0;
- WEBKIT_API void setHTTPBody(const WebHTTPBody&) = 0;
- WEBKIT_API void appendToHTTPBody(const WebHTTPBody::Element&) = 0;
-
// Controls whether upload progress events are generated when a request
// has a body.
- WEBKIT_API bool reportUploadProgress() const = 0;
- WEBKIT_API void setReportUploadProgress(bool) = 0;
+ WEBKIT_API bool reportUploadProgress() const;
+ WEBKIT_API void setReportUploadProgress(bool);
- WEBKIT_API TargetType targetType() const = 0;
- WEBKIT_API void setTargetType(const TargetType&) = 0;
+ WEBKIT_API TargetType targetType() const;
+ WEBKIT_API void setTargetType(TargetType);
// A consumer controlled value intended to be used to identify the
// requestor.
- WEBKIT_API int requestorID() const = 0;
- WEBKIT_API void setRequestorID(int) = 0;
+ WEBKIT_API int requestorID() const;
+ WEBKIT_API void setRequestorID(int);
// A consumer controlled value intended to be used to identify the
// process of the requestor.
- WEBKIT_API int requestorProcessID() const = 0;
- WEBKIT_API void setRequestorProcessID(int) = 0;
+ WEBKIT_API int requestorProcessID() const;
+ WEBKIT_API void setRequestorProcessID(int);
+
+ // Allows the request to be matched up with its app cache context.
+ WEBKIT_API int appCacheContextID() const;
+ WEBKIT_API void setAppCacheContextID(int id);
// A consumer controlled value intended to be used to record opaque
// security info related to this request.
// FIXME: This really doesn't belong here!
- WEBKIT_API WebCString securityInfo() const = 0;
- WEBKIT_API void setSecurityInfo(const WebCString&) = 0;
+ WEBKIT_API WebCString securityInfo() const;
+ WEBKIT_API void setSecurityInfo(const WebCString&);
+
+#if defined(WEBKIT_IMPLEMENTATION)
+ WebCore::ResourceRequest& toMutableResourceRequest();
+ const WebCore::ResourceRequest& toResourceRequest() const;
+#endif
+
+ protected:
+ void assign(WebURLRequestPrivate*);
private:
WebURLRequestPrivate* m_private;
diff --git a/webkit/api/public/WebURLResponse.h b/webkit/api/public/WebURLResponse.h
index 30d2641..c26f213 100644
--- a/webkit/api/public/WebURLResponse.h
+++ b/webkit/api/public/WebURLResponse.h
@@ -31,12 +31,15 @@
#ifndef WebURLResponse_h
#define WebURLResponse_h
-#error "This header file is still a work in progress; do not include!"
-
#include "WebCommon.h"
+#if defined(WEBKIT_IMPLEMENTATION)
+namespace WebCore { class ResourceResponse; }
+#endif
+
namespace WebKit {
class WebCString;
+ class WebHTTPHeaderVisitor;
class WebString;
class WebURL;
class WebURLResponsePrivate;
@@ -49,51 +52,69 @@ namespace WebKit {
WebURLResponse(const WebURLResponse& r) : m_private(0) { assign(r); }
WebURLResponse& operator=(const WebURLResponse& r) { assign(r); return *this; }
+ explicit WebURLResponse(const WebURL& url) : m_private(0)
+ {
+ initialize();
+ setURL(url);
+ }
+
WEBKIT_API void initialize();
WEBKIT_API void reset();
WEBKIT_API void assign(const WebURLResponse&);
bool isNull() const { return m_private == 0; }
- WEBKIT_API WebURL url() const = 0;
- WEBKIT_API void setURL(const WebURL&) = 0;
+ WEBKIT_API WebURL url() const;
+ WEBKIT_API void setURL(const WebURL&);
- WEBKIT_API WebString mimeType() const = 0;
- WEBKIT_API void setMIMEType(const WebString&) = 0;
+ WEBKIT_API WebString mimeType() const;
+ WEBKIT_API void setMIMEType(const WebString&);
- WEBKIT_API long long expectedContentLength() const = 0;
- WEBKIT_API void setExpectedContentLength(long long) = 0;
+ WEBKIT_API long long expectedContentLength() const;
+ WEBKIT_API void setExpectedContentLength(long long);
- WEBKIT_API WebString textEncodingName() const = 0;
- WEBKIT_API void setTextEncodingName(const WebString&) = 0;
+ WEBKIT_API WebString textEncodingName() const;
+ WEBKIT_API void setTextEncodingName(const WebString&);
- WEBKIT_API WebString suggestedFileName() const = 0;
- WEBKIT_API void setSuggestedFileName(const WebString&) = 0;
+ WEBKIT_API WebString suggestedFileName() const;
+ WEBKIT_API void setSuggestedFileName(const WebString&);
- WEBKIT_API int httpStatusCode() const = 0;
- WEBKIT_API void setHTTPStatusCode(int) = 0;
+ WEBKIT_API int httpStatusCode() const;
+ WEBKIT_API void setHTTPStatusCode(int);
- WEBKIT_API WebString httpStatusText() const = 0;
- WEBKIT_API void setHTTPStatusText(const WebString&) = 0;
+ WEBKIT_API WebString httpStatusText() const;
+ WEBKIT_API void setHTTPStatusText(const WebString&);
- WEBKIT_API WebString httpHeaderField(const WebString& name) const = 0;
- WEBKIT_API void setHTTPHeaderField(const WebString& name, const WebString& value) = 0;
- WEBKIT_API void addHTTPHeaderField(const WebString& name, const WebString& value) = 0;
- WEBKIT_API void clearHTTPHeaderField(const WebString& name) = 0;
+ WEBKIT_API WebString httpHeaderField(const WebString& name) const;
+ WEBKIT_API void setHTTPHeaderField(const WebString& name, const WebString& value);
+ WEBKIT_API void addHTTPHeaderField(const WebString& name, const WebString& value);
+ WEBKIT_API void clearHTTPHeaderField(const WebString& name);
+ WEBKIT_API void visitHTTPHeaderFields(WebHTTPHeaderVisitor*) const;
- WEBKIT_API double expirationDate() const = 0;
- WEBKIT_API void setExpirationDate(double) = 0;
+ WEBKIT_API double expirationDate() const;
+ WEBKIT_API void setExpirationDate(double);
- WEBKIT_API double lastModifiedDate() const = 0;
- WEBKIT_API void setLastModifiedDate(double) = 0;
+ WEBKIT_API double lastModifiedDate() const;
+ WEBKIT_API void setLastModifiedDate(double);
- WEBKIT_API bool isContentFiltered() const = 0;
- WEBKIT_API void setIsContentFiltered(bool) = 0;
+ WEBKIT_API bool isContentFiltered() const;
+ WEBKIT_API void setIsContentFiltered(bool);
+
+ WEBKIT_API long long appCacheID() const;
+ WEBKIT_API void setAppCacheID(long long);
// A consumer controlled value intended to be used to record opaque
// security info related to this request.
- WEBKIT_API WebCString securityInfo() const = 0;
- WEBKIT_API void setSecurityInfo(const WebCString&) = 0;
+ WEBKIT_API WebCString securityInfo() const;
+ WEBKIT_API void setSecurityInfo(const WebCString&);
+
+#if defined(WEBKIT_IMPLEMENTATION)
+ WebCore::ResourceResponse& toMutableResourceResponse();
+ const WebCore::ResourceResponse& toResourceResponse() const;
+#endif
+
+ protected:
+ void assign(WebURLResponsePrivate*);
private:
WebURLResponsePrivate* m_private;
diff --git a/webkit/api/src/ResourceHandle.cpp b/webkit/api/src/ResourceHandle.cpp
new file mode 100644
index 0000000..b7def8d
--- /dev/null
+++ b/webkit/api/src/ResourceHandle.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ResourceHandle.h"
+
+#include "WebKit.h"
+#include "WebKitClient.h"
+#include "WebURLError.h"
+#include "WebURLLoader.h"
+#include "WebURLLoaderClient.h"
+#include "WebURLRequest.h"
+#include "WebURLResponse.h"
+#include "WrappedResourceRequest.h"
+#include "WrappedResourceResponse.h"
+
+#include "ResourceHandleClient.h"
+#include "ResourceRequest.h"
+
+using namespace WebKit;
+
+namespace WebCore {
+
+// ResourceHandleInternal -----------------------------------------------------
+
+class ResourceHandleInternal : public WebURLLoaderClient {
+public:
+ ResourceHandleInternal(const ResourceRequest& request, ResourceHandleClient* client)
+ : m_request(request)
+ , m_owner(0)
+ , m_client(client)
+ {
+ }
+
+ void start();
+ void cancel();
+ void setDefersLoading(bool);
+
+ // WebURLLoaderClient methods:
+ virtual void willSendRequest(WebURLLoader*, WebURLRequest&, const WebURLResponse&);
+ virtual void didSendData(
+ WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
+ virtual void didReceiveResponse(WebURLLoader*, const WebURLResponse&);
+ virtual void didReceiveData(
+ WebURLLoader*, const char* data, int dataLength, long long totalDataLength);
+ virtual void didFinishLoading(WebURLLoader*);
+ virtual void didFail(WebURLLoader*, const WebURLError&);
+
+ ResourceRequest m_request;
+ ResourceHandle* m_owner;
+ ResourceHandleClient* m_client;
+ OwnPtr<WebURLLoader> m_loader;
+};
+
+void ResourceHandleInternal::start()
+{
+ m_loader.set(webKitClient()->createURLLoader());
+ ASSERT(m_loader.get());
+
+ WrappedResourceRequest wrappedRequest(m_request);
+ m_loader->loadAsynchronously(wrappedRequest, this);
+}
+
+void ResourceHandleInternal::cancel()
+{
+ m_loader->cancel();
+
+ // Do not make any further calls to the client.
+ m_client = 0;
+}
+
+void ResourceHandleInternal::setDefersLoading(bool value)
+{
+ m_loader->setDefersLoading(value);
+}
+
+void ResourceHandleInternal::willSendRequest(
+ WebURLLoader*, WebURLRequest& request, const WebURLResponse& response)
+{
+ ASSERT(m_client);
+ ASSERT(!request.isNull());
+ ASSERT(!response.isNull());
+ m_client->willSendRequest(m_owner, request.toMutableResourceRequest(), response.toResourceResponse());
+}
+
+void ResourceHandleInternal::didSendData(
+ WebURLLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+ ASSERT(m_client);
+ m_client->didSendData(m_owner, bytesSent, totalBytesToBeSent);
+}
+
+void ResourceHandleInternal::didReceiveResponse(WebURLLoader*, const WebURLResponse& response)
+{
+ ASSERT(m_client);
+ ASSERT(!response.isNull());
+ m_client->didReceiveResponse(m_owner, response.toResourceResponse());
+}
+
+void ResourceHandleInternal::didReceiveData(
+ WebURLLoader*, const char* data, int dataLength, long long totalDataLength)
+{
+ ASSERT(m_client);
+
+ // FIXME: ResourceHandleClient::didReceiveData should take a 'long long'
+ int lengthReceived = static_cast<int>(totalDataLength);
+ if (lengthReceived != totalDataLength) // overflow occurred
+ lengthReceived = -1;
+
+ m_client->didReceiveData(m_owner, data, dataLength, lengthReceived);
+}
+
+void ResourceHandleInternal::didFinishLoading(WebURLLoader*)
+{
+ ASSERT(m_client);
+ m_client->didFinishLoading(m_owner);
+}
+
+void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error)
+{
+ ASSERT(m_client);
+ m_client->didFail(m_owner, error);
+}
+
+// ResourceHandle -------------------------------------------------------------
+
+ResourceHandle::ResourceHandle(const ResourceRequest& request,
+ ResourceHandleClient* client,
+ bool defersLoading,
+ bool shouldContentSniff,
+ bool mightDownloadFromHandle)
+ : d(new ResourceHandleInternal(request, client))
+{
+ d->m_owner = this;
+
+ // FIXME: Figure out what to do with the 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(deprecated))
+ return newHandle.release();
+
+ return 0;
+}
+
+const ResourceRequest& ResourceHandle::request() const
+{
+ return d->m_request;
+}
+
+ResourceHandleClient* ResourceHandle::client() const
+{
+ return d->m_client;
+}
+
+void ResourceHandle::setClient(ResourceHandleClient* client)
+{
+ d->m_client = client;
+}
+
+void ResourceHandle::setDefersLoading(bool value)
+{
+ d->setDefersLoading(value);
+}
+
+bool ResourceHandle::start(Frame* deprecated)
+{
+ d->start();
+ return true;
+}
+
+void ResourceHandle::clearAuthentication()
+{
+}
+
+void ResourceHandle::cancel()
+{
+ d->cancel();
+}
+
+ResourceHandle::~ResourceHandle()
+{
+ d->m_owner = 0;
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ return 0;
+}
+
+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 unused,
+ ResourceError& error,
+ ResourceResponse& response,
+ Vector<char>& data,
+ Frame* deprecated)
+{
+ OwnPtr<WebURLLoader> loader(webKitClient()->createURLLoader());
+ ASSERT(loader.get());
+
+ WrappedResourceRequest requestIn(request);
+ WrappedResourceResponse responseOut(response);
+ WebURLError errorOut;
+ WebData dataOut;
+
+ loader->loadSynchronously(requestIn, responseOut, errorOut, dataOut);
+
+ error = errorOut;
+ data.clear();
+ data.append(dataOut.data(), dataOut.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.
+ //
+ ASSERT(request.httpMethod() == "POST");
+ request.setCachePolicy(ReturnCacheDataDontLoad);
+ return true;
+}
+
+} // namespace WebCore
diff --git a/webkit/api/src/WebDragData.cpp b/webkit/api/src/WebDragData.cpp
index 426ceea..a8210ac 100644
--- a/webkit/api/src/WebDragData.cpp
+++ b/webkit/api/src/WebDragData.cpp
@@ -53,10 +53,7 @@ void WebDragData::initialize()
void WebDragData::reset()
{
- if (m_private) {
- m_private->deref();
- m_private = 0;
- }
+ assign(0);
}
void WebDragData::assign(const WebDragData& other)
diff --git a/webkit/api/src/WebHTTPBody.cpp b/webkit/api/src/WebHTTPBody.cpp
new file mode 100644
index 0000000..69875e7
--- /dev/null
+++ b/webkit/api/src/WebHTTPBody.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebHTTPBody.h"
+
+#include "FormData.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+class WebHTTPBodyPrivate : public FormData {
+};
+
+void WebHTTPBody::initialize()
+{
+ assign(static_cast<WebHTTPBodyPrivate*>(FormData::create().releaseRef()));
+}
+
+void WebHTTPBody::reset()
+{
+ assign(0);
+}
+
+size_t WebHTTPBody::elementCount() const
+{
+ return m_private->elements().size();
+}
+
+bool WebHTTPBody::elementAt(size_t index, Element& result) const
+{
+ if (index >= m_private->elements().size())
+ return false;
+
+ const FormDataElement& element = m_private->elements()[index];
+
+ switch (element.m_type) {
+ case FormDataElement::data:
+ result.type = Element::TypeData;
+ result.data.assign(element.m_data.data(), element.m_data.size());
+ result.filePath.reset();
+ break;
+ case FormDataElement::encodedFile:
+ result.type = Element::TypeFile;
+ result.data.reset();
+ result.filePath = element.m_filename;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ return true;
+}
+
+void WebHTTPBody::appendData(const WebData& data)
+{
+ // FIXME: FormDataElement::m_data should be a SharedBuffer<char>. Then we
+ // could avoid this buffer copy.
+ m_private->appendData(data.data(), data.size());
+}
+
+void WebHTTPBody::appendFile(const WebString& filePath)
+{
+ m_private->appendFile(filePath);
+}
+
+long long WebHTTPBody::identifier() const
+{
+ return m_private->identifier();
+}
+
+void WebHTTPBody::setIdentifier(long long identifier)
+{
+ return m_private->setIdentifier(identifier);
+}
+
+void WebHTTPBody::rebind(PassRefPtr<FormData> formData)
+{
+ assign(static_cast<WebHTTPBodyPrivate*>(formData.releaseRef()));
+}
+
+WebHTTPBody::operator PassRefPtr<FormData>() const
+{
+ return m_private;
+}
+
+void WebHTTPBody::assign(WebHTTPBodyPrivate* p)
+{
+ // p is already ref'd for us by the caller
+ if (m_private)
+ m_private->deref();
+ m_private = p;
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/WebURLError.cpp b/webkit/api/src/WebURLError.cpp
new file mode 100644
index 0000000..cd7d72d
--- /dev/null
+++ b/webkit/api/src/WebURLError.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebURLError.h"
+
+#include "CString.h"
+#include "KURL.h"
+#include "ResourceError.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebURLError::WebURLError(const ResourceError& error)
+{
+ *this = error;
+}
+
+WebURLError& WebURLError::operator=(const ResourceError& error)
+{
+ if (error.isNull())
+ *this = WebURLError();
+ else {
+ domain = error.domain();
+ reason = error.errorCode();
+ unreachableURL = KURL(error.failingURL());
+ }
+ return *this;
+}
+
+WebURLError::operator ResourceError() const
+{
+ if (reason == 0)
+ return ResourceError();
+ CString spec = unreachableURL.spec();
+ return ResourceError(domain, reason,
+ String::fromUTF8(spec.data(), spec.length()),
+ String());
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/WebURLRequest.cpp b/webkit/api/src/WebURLRequest.cpp
new file mode 100644
index 0000000..66483f9
--- /dev/null
+++ b/webkit/api/src/WebURLRequest.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebURLRequest.h"
+
+#include "WebHTTPHeaderVisitor.h"
+#include "WebURL.h"
+#include "WebURLRequestPrivate.h"
+
+#include "ResourceRequest.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// The standard implementation of WebURLRequestPrivate, which maintains
+// ownership of a ResourceRequest instance.
+class WebURLRequestPrivateImpl : public WebURLRequestPrivate {
+public:
+ WebURLRequestPrivateImpl()
+ {
+ m_resourceRequest = &m_resourceRequestAllocation;
+ }
+
+ WebURLRequestPrivateImpl(const WebURLRequestPrivate* p)
+ : m_resourceRequestAllocation(*p->m_resourceRequest)
+ {
+ m_resourceRequest = &m_resourceRequestAllocation;
+ }
+
+ virtual void dispose() { delete this; }
+
+ ResourceRequest m_resourceRequestAllocation;
+};
+
+void WebURLRequest::initialize()
+{
+ assign(new WebURLRequestPrivateImpl());
+}
+
+void WebURLRequest::reset()
+{
+ assign(0);
+}
+
+void WebURLRequest::assign(const WebURLRequest& r)
+{
+ assign(r.m_private ? new WebURLRequestPrivateImpl(r.m_private) : 0);
+}
+
+WebURL WebURLRequest::url() const
+{
+ return m_private->m_resourceRequest->url();
+}
+
+void WebURLRequest::setURL(const WebURL& url)
+{
+ m_private->m_resourceRequest->setURL(url);
+}
+
+WebURL WebURLRequest::firstPartyForCookies() const
+{
+ return m_private->m_resourceRequest->firstPartyForCookies();
+}
+
+void WebURLRequest::setFirstPartyForCookies(const WebURL& firstPartyForCookies)
+{
+ m_private->m_resourceRequest->setFirstPartyForCookies(firstPartyForCookies);
+}
+
+WebURLRequest::CachePolicy WebURLRequest::cachePolicy() const
+{
+ return static_cast<WebURLRequest::CachePolicy>(
+ m_private->m_resourceRequest->cachePolicy());
+}
+
+void WebURLRequest::setCachePolicy(CachePolicy cachePolicy)
+{
+ m_private->m_resourceRequest->setCachePolicy(
+ static_cast<ResourceRequestCachePolicy>(cachePolicy));
+}
+
+WebString WebURLRequest::httpMethod() const
+{
+ return m_private->m_resourceRequest->httpMethod();
+}
+
+void WebURLRequest::setHTTPMethod(const WebString& httpMethod)
+{
+ m_private->m_resourceRequest->setHTTPMethod(httpMethod);
+}
+
+WebString WebURLRequest::httpHeaderField(const WebString& name) const
+{
+ return m_private->m_resourceRequest->httpHeaderField(String(name));
+}
+
+void WebURLRequest::setHTTPHeaderField(const WebString& name, const WebString& value)
+{
+ m_private->m_resourceRequest->setHTTPHeaderField(String(name), value);
+}
+
+void WebURLRequest::addHTTPHeaderField(const WebString& name, const WebString& value)
+{
+ m_private->m_resourceRequest->addHTTPHeaderField(String(name), value);
+}
+
+void WebURLRequest::clearHTTPHeaderField(const WebString& name)
+{
+ // FIXME: Add a clearHTTPHeaderField method to ResourceRequest.
+ const HTTPHeaderMap& map = m_private->m_resourceRequest->httpHeaderFields();
+ const_cast<HTTPHeaderMap*>(&map)->remove(String(name));
+}
+
+void WebURLRequest::visitHTTPHeaderFields(WebHTTPHeaderVisitor* visitor) const
+{
+ const HTTPHeaderMap& map = m_private->m_resourceRequest->httpHeaderFields();
+ for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it)
+ visitor->visitHeader(String(it->first), it->second);
+}
+
+const WebHTTPBody& WebURLRequest::httpBody() const
+{
+ m_private->m_httpBody.rebind(m_private->m_resourceRequest->httpBody());
+ return m_private->m_httpBody;
+}
+
+void WebURLRequest::setHTTPBody(const WebHTTPBody& httpBody)
+{
+ m_private->m_resourceRequest->setHTTPBody(httpBody);
+ m_private->m_httpBody.rebind(0); // Free memory of the old body
+}
+
+bool WebURLRequest::reportUploadProgress() const
+{
+ return m_private->m_resourceRequest->reportUploadProgress();
+}
+
+void WebURLRequest::setReportUploadProgress(bool reportUploadProgress)
+{
+ m_private->m_resourceRequest->setReportUploadProgress(reportUploadProgress);
+}
+
+WebURLRequest::TargetType WebURLRequest::targetType() const
+{
+ return static_cast<TargetType>(m_private->m_resourceRequest->targetType());
+}
+
+void WebURLRequest::setTargetType(TargetType targetType)
+{
+ m_private->m_resourceRequest->setTargetType(
+ static_cast<ResourceRequest::TargetType>(targetType));
+}
+
+int WebURLRequest::requestorID() const
+{
+ return m_private->m_resourceRequest->requestorID();
+}
+
+void WebURLRequest::setRequestorID(int requestorID)
+{
+ m_private->m_resourceRequest->setRequestorID(requestorID);
+}
+
+int WebURLRequest::requestorProcessID() const
+{
+ return m_private->m_resourceRequest->requestorProcessID();
+}
+
+void WebURLRequest::setRequestorProcessID(int requestorProcessID)
+{
+ m_private->m_resourceRequest->setRequestorProcessID(requestorProcessID);
+}
+
+int WebURLRequest::appCacheContextID() const
+{
+ return m_private->m_resourceRequest->appCacheContextID();
+}
+
+void WebURLRequest::setAppCacheContextID(int appCacheContextID)
+{
+ m_private->m_resourceRequest->setAppCacheContextID(appCacheContextID);
+}
+
+WebCString WebURLRequest::securityInfo() const
+{
+ return m_private->m_resourceRequest->securityInfo();
+}
+
+void WebURLRequest::setSecurityInfo(const WebCString& securityInfo)
+{
+ m_private->m_resourceRequest->setSecurityInfo(securityInfo);
+}
+
+ResourceRequest& WebURLRequest::toMutableResourceRequest()
+{
+ ASSERT(m_private);
+ ASSERT(m_private->m_resourceRequest);
+
+ return *m_private->m_resourceRequest;
+}
+
+const ResourceRequest& WebURLRequest::toResourceRequest() const
+{
+ ASSERT(m_private);
+ ASSERT(m_private->m_resourceRequest);
+
+ return *m_private->m_resourceRequest;
+}
+
+void WebURLRequest::assign(WebURLRequestPrivate* p)
+{
+ if (m_private)
+ m_private->dispose();
+ m_private = p;
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/WebURLRequestPrivate.h b/webkit/api/src/WebURLRequestPrivate.h
new file mode 100644
index 0000000..57ef3d1
--- /dev/null
+++ b/webkit/api/src/WebURLRequestPrivate.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebURLRequestPrivate_h
+#define WebURLRequestPrivate_h
+
+#include "WebHTTPBody.h"
+
+namespace WebCore { struct ResourceRequest; }
+
+namespace WebKit {
+
+ class WebURLRequestPrivate {
+ public:
+ WebURLRequestPrivate() : m_resourceRequest(0) { }
+
+ // Called by WebURLRequest when it no longer needs this object.
+ virtual void dispose() = 0;
+
+ WebCore::ResourceRequest* m_resourceRequest;
+ WebHTTPBody m_httpBody;
+ };
+
+} // namespace WebKit
+
+#endif
diff --git a/webkit/api/src/WebURLResponse.cpp b/webkit/api/src/WebURLResponse.cpp
new file mode 100644
index 0000000..52e193f
--- /dev/null
+++ b/webkit/api/src/WebURLResponse.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebURLResponse.h"
+
+#include "WebHTTPHeaderVisitor.h"
+#include "WebString.h"
+#include "WebURL.h"
+#include "WebURLResponsePrivate.h"
+
+#include "ResourceResponse.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// The standard implementation of WebURLResponsePrivate, which maintains
+// ownership of a ResourceResponse instance.
+class WebURLResponsePrivateImpl : public WebURLResponsePrivate {
+public:
+ WebURLResponsePrivateImpl()
+ {
+ m_resourceResponse = &m_resourceResponseAllocation;
+ }
+
+ WebURLResponsePrivateImpl(const WebURLResponsePrivate* p)
+ : m_resourceResponseAllocation(*p->m_resourceResponse)
+ {
+ m_resourceResponse = &m_resourceResponseAllocation;
+ }
+
+ virtual void dispose() { delete this; }
+
+ ResourceResponse m_resourceResponseAllocation;
+};
+
+void WebURLResponse::initialize()
+{
+ assign(new WebURLResponsePrivateImpl());
+}
+
+void WebURLResponse::reset()
+{
+ assign(0);
+}
+
+void WebURLResponse::assign(const WebURLResponse& r)
+{
+ assign(r.m_private ? new WebURLResponsePrivateImpl(r.m_private) : 0);
+}
+
+WebURL WebURLResponse::url() const
+{
+ return m_private->m_resourceResponse->url();
+}
+
+void WebURLResponse::setURL(const WebURL& url)
+{
+ m_private->m_resourceResponse->setURL(url);
+}
+
+WebString WebURLResponse::mimeType() const
+{
+ return m_private->m_resourceResponse->mimeType();
+}
+
+void WebURLResponse::setMIMEType(const WebString& mimeType)
+{
+ m_private->m_resourceResponse->setMimeType(mimeType);
+}
+
+long long WebURLResponse::expectedContentLength() const
+{
+ return m_private->m_resourceResponse->expectedContentLength();
+}
+
+void WebURLResponse::setExpectedContentLength(long long expectedContentLength)
+{
+ m_private->m_resourceResponse->setExpectedContentLength(expectedContentLength);
+}
+
+WebString WebURLResponse::textEncodingName() const
+{
+ return m_private->m_resourceResponse->textEncodingName();
+}
+
+void WebURLResponse::setTextEncodingName(const WebString& textEncodingName)
+{
+ m_private->m_resourceResponse->setTextEncodingName(textEncodingName);
+}
+
+WebString WebURLResponse::suggestedFileName() const
+{
+ return m_private->m_resourceResponse->suggestedFilename();
+}
+
+void WebURLResponse::setSuggestedFileName(const WebString& suggestedFileName)
+{
+ m_private->m_resourceResponse->setSuggestedFilename(suggestedFileName);
+}
+
+int WebURLResponse::httpStatusCode() const
+{
+ return m_private->m_resourceResponse->httpStatusCode();
+}
+
+void WebURLResponse::setHTTPStatusCode(int httpStatusCode)
+{
+ m_private->m_resourceResponse->setHTTPStatusCode(httpStatusCode);
+}
+
+WebString WebURLResponse::httpStatusText() const
+{
+ return m_private->m_resourceResponse->httpStatusText();
+}
+
+void WebURLResponse::setHTTPStatusText(const WebString& httpStatusText)
+{
+ m_private->m_resourceResponse->setHTTPStatusText(httpStatusText);
+}
+
+WebString WebURLResponse::httpHeaderField(const WebString& name) const
+{
+ return m_private->m_resourceResponse->httpHeaderField(String(name));
+}
+
+void WebURLResponse::setHTTPHeaderField(const WebString& name, const WebString& value)
+{
+ m_private->m_resourceResponse->setHTTPHeaderField(String(name), value);
+}
+
+void WebURLResponse::addHTTPHeaderField(const WebString& name, const WebString& value)
+{
+ // FIXME: Add an addHTTPHeaderField method to ResourceResponse.
+ const HTTPHeaderMap& map = m_private->m_resourceResponse->httpHeaderFields();
+ String valueStr(value);
+ pair<HTTPHeaderMap::iterator, bool> result =
+ const_cast<HTTPHeaderMap*>(&map)->add(String(name), valueStr);
+ if (!result.second)
+ result.first->second += "," + valueStr;
+}
+
+void WebURLResponse::clearHTTPHeaderField(const WebString& name)
+{
+ // FIXME: Add a clearHTTPHeaderField method to ResourceResponse.
+ const HTTPHeaderMap& map = m_private->m_resourceResponse->httpHeaderFields();
+ const_cast<HTTPHeaderMap*>(&map)->remove(String(name));
+}
+
+void WebURLResponse::visitHTTPHeaderFields(WebHTTPHeaderVisitor* visitor) const
+{
+ const HTTPHeaderMap& map = m_private->m_resourceResponse->httpHeaderFields();
+ for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it)
+ visitor->visitHeader(String(it->first), it->second);
+}
+
+double WebURLResponse::expirationDate() const
+{
+ return static_cast<double>(m_private->m_resourceResponse->expirationDate());
+}
+
+void WebURLResponse::setExpirationDate(double expirationDate)
+{
+ m_private->m_resourceResponse->setExpirationDate(static_cast<time_t>(expirationDate));
+}
+
+double WebURLResponse::lastModifiedDate() const
+{
+ return static_cast<double>(m_private->m_resourceResponse->lastModifiedDate());
+}
+
+void WebURLResponse::setLastModifiedDate(double lastModifiedDate)
+{
+ m_private->m_resourceResponse->setLastModifiedDate(static_cast<time_t>(lastModifiedDate));
+}
+
+bool WebURLResponse::isContentFiltered() const
+{
+ return m_private->m_resourceResponse->isContentFiltered();
+}
+
+void WebURLResponse::setIsContentFiltered(bool isContentFiltered)
+{
+ m_private->m_resourceResponse->setIsContentFiltered(isContentFiltered);
+}
+
+long long WebURLResponse::appCacheID() const
+{
+ return m_private->m_resourceResponse->getAppCacheID();
+}
+
+void WebURLResponse::setAppCacheID(long long appCacheID)
+{
+ m_private->m_resourceResponse->setAppCacheID(appCacheID);
+}
+
+WebCString WebURLResponse::securityInfo() const
+{
+ // FIXME: getSecurityInfo is misnamed.
+ return m_private->m_resourceResponse->getSecurityInfo();
+}
+
+void WebURLResponse::setSecurityInfo(const WebCString& securityInfo)
+{
+ m_private->m_resourceResponse->setSecurityInfo(securityInfo);
+}
+
+ResourceResponse& WebURLResponse::toMutableResourceResponse()
+{
+ ASSERT(m_private);
+ ASSERT(m_private->m_resourceResponse);
+
+ return *m_private->m_resourceResponse;
+}
+
+const ResourceResponse& WebURLResponse::toResourceResponse() const
+{
+ ASSERT(m_private);
+ ASSERT(m_private->m_resourceResponse);
+
+ return *m_private->m_resourceResponse;
+}
+
+void WebURLResponse::assign(WebURLResponsePrivate* p)
+{
+ if (m_private)
+ m_private->dispose();
+ m_private = p;
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/WebURLResponsePrivate.h b/webkit/api/src/WebURLResponsePrivate.h
new file mode 100644
index 0000000..d421c1a
--- /dev/null
+++ b/webkit/api/src/WebURLResponsePrivate.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebURLResponsePrivate_h
+#define WebURLResponsePrivate_h
+
+namespace WebCore { class ResourceResponse; }
+
+namespace WebKit {
+
+ class WebURLResponsePrivate {
+ public:
+ WebURLResponsePrivate() : m_resourceResponse(0) { }
+
+ // Called by WebURLResponse when it no longer needs this object.
+ virtual void dispose() = 0;
+
+ WebCore::ResourceResponse* m_resourceResponse;
+ };
+
+} // namespace WebKit
+
+#endif
diff --git a/webkit/api/src/WrappedResourceRequest.h b/webkit/api/src/WrappedResourceRequest.h
new file mode 100644
index 0000000..58188c1
--- /dev/null
+++ b/webkit/api/src/WrappedResourceRequest.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WebURLRequestPrivate.h"
+
+namespace WebKit {
+
+ class WrappedResourceRequest : public WebURLRequest {
+ public:
+ ~WrappedResourceRequest()
+ {
+ reset(); // Need to drop reference to m_handle
+ }
+
+ WrappedResourceRequest(WebCore::ResourceRequest& resourceRequest)
+ {
+ bind(&resourceRequest);
+ }
+
+ WrappedResourceRequest(const WebCore::ResourceRequest& resourceRequest)
+ {
+ bind(const_cast<WebCore::ResourceRequest*>(&resourceRequest));
+ }
+
+ private:
+ void bind(WebCore::ResourceRequest* resourceRequest)
+ {
+ m_handle.m_resourceRequest = resourceRequest;
+ assign(&m_handle);
+ }
+
+ class Handle : public WebURLRequestPrivate {
+ public:
+ virtual void dispose() { m_resourceRequest = 0; }
+ };
+
+ Handle m_handle;
+ };
+
+} // namespace WebKit
diff --git a/webkit/api/src/WrappedResourceResponse.h b/webkit/api/src/WrappedResourceResponse.h
new file mode 100644
index 0000000..fe7bb99
--- /dev/null
+++ b/webkit/api/src/WrappedResourceResponse.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WebURLResponse.h"
+#include "WebURLResponsePrivate.h"
+
+namespace WebKit {
+
+ class WrappedResourceResponse : public WebURLResponse {
+ public:
+ ~WrappedResourceResponse()
+ {
+ reset(); // Need to drop reference to m_handle
+ }
+
+ WrappedResourceResponse(WebCore::ResourceResponse& resourceResponse)
+ {
+ bind(&resourceResponse);
+ }
+
+ WrappedResourceResponse(const WebCore::ResourceResponse& resourceResponse)
+ {
+ bind(const_cast<WebCore::ResourceResponse*>(&resourceResponse));
+ }
+
+ private:
+ void bind(WebCore::ResourceResponse* resourceResponse)
+ {
+ m_handle.m_resourceResponse = resourceResponse;
+ assign(&m_handle);
+ }
+
+ class Handle : public WebURLResponsePrivate {
+ public:
+ virtual void dispose() { m_resourceResponse = 0; }
+ };
+
+ Handle m_handle;
+ };
+
+} // namespace WebKit
diff --git a/webkit/glue/glue_util.cc b/webkit/glue/glue_util.cc
index 5f7228f..b85ad71 100644
--- a/webkit/glue/glue_util.cc
+++ b/webkit/glue/glue_util.cc
@@ -35,6 +35,8 @@
#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 {
@@ -71,10 +73,9 @@ WebCore::String String16ToString(const string16& str) {
}
std::string StringToStdString(const WebCore::String& str) {
- if (str.length() == 0)
- return std::string();
std::string ret;
- UTF16ToUTF8(str.characters(), str.length(), &ret);
+ if (!str.isNull())
+ UTF16ToUTF8(str.characters(), str.length(), &ret);
return ret;
}
@@ -108,6 +109,17 @@ 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);
@@ -214,4 +226,28 @@ 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 4bcebad..553802c 100644
--- a/webkit/glue/glue_util.h
+++ b/webkit/glue/glue_util.h
@@ -17,7 +17,9 @@ class IntPoint;
class IntRect;
class IntSize;
class KURL;
+class ResourceResponse;
class String;
+struct ResourceRequest;
}
namespace WebKit {
@@ -25,6 +27,8 @@ class WebCString;
class WebDragData;
class WebString;
class WebURL;
+class WebURLRequest;
+class WebURLResponse;
struct WebPoint;
struct WebRect;
struct WebSize;
@@ -68,6 +72,10 @@ 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);
@@ -99,6 +107,18 @@ 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 9e8e67d..2000b61 100644
--- a/webkit/glue/multipart_response_delegate.cc
+++ b/webkit/glue/multipart_response_delegate.cc
@@ -2,32 +2,64 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#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();
+#include "webkit/glue/multipart_response_delegate.h"
-#undef LOG
#include "base/logging.h"
#include "base/string_util.h"
-#include "webkit/glue/multipart_response_delegate.h"
-#include "webkit/glue/glue_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/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
MultipartResponseDelegate::MultipartResponseDelegate(
- WebCore::ResourceHandleClient* client,
- WebCore::ResourceHandle* job,
- const WebCore::ResourceResponse& response,
+ WebURLLoaderClient* client,
+ WebURLLoader* loader,
+ const WebURLResponse& response,
const std::string& boundary)
: client_(client),
- job_(job),
+ loader_(loader),
original_response_(response),
boundary_("--"),
first_received_data_(true),
@@ -41,7 +73,8 @@ 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.
@@ -49,8 +82,7 @@ void MultipartResponseDelegate::OnReceivedData(const char* data, int data_len) {
return;
// TODO(tc): Figure out what to use for length_received. Maybe we can just
- // pass the value on from our caller. See note in
- // resource_handle_win.cc:ResourceHandleInternal::OnReceivedData.
+ // pass the value on from our caller.
int length_received = -1;
data_.append(data, data_len);
@@ -98,8 +130,10 @@ void MultipartResponseDelegate::OnReceivedData(const char* data, int data_len) {
while ((boundary_pos = FindBoundary()) != std::string::npos) {
if (boundary_pos > 0) {
// Send the last data chunk.
- client_->didReceiveData(job_, data_.substr(0, boundary_pos).data(),
- static_cast<int>(boundary_pos), length_received);
+ client_->didReceiveData(loader_,
+ 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]) {
@@ -128,12 +162,15 @@ 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(job_, data_.data(),
- static_cast<int>(data_.length()), length_received);
+ client_->didReceiveData(loader_,
+ 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;
@@ -175,47 +212,28 @@ bool MultipartResponseDelegate::ParseHeaders() {
headers.append(data_.substr(0, line_end_pos));
data_ = data_.substr(line_end_pos);
- // Create a ResourceResponse based on the original set of headers + the
+ // Create a WebURLResponse based on the original set of headers + the
// replacement headers. We only replace the same few headers that gecko
// does. See netwerk/streamconv/converters/nsMultiMixedConv.cpp.
std::string mime_type = net::GetSpecificHeader(headers, "content-type");
std::string charset = net::GetHeaderParamValue(mime_type, "charset");
- 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]);
+ 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]);
std::string value = net::GetSpecificHeader(headers, name);
if (!value.empty()) {
- response.setHTTPHeaderField(webkit_glue::StdStringToString(name.c_str()),
- webkit_glue::StdStringToString(value.c_str()));
+ response.setHTTPHeaderField(StdStringToWebString(name),
+ StdStringToWebString(value));
}
}
// Send the response!
- client_->didReceiveResponse(job_, response);
+ client_->didReceiveResponse(loader_, response);
return true;
}
@@ -239,29 +257,27 @@ size_t MultipartResponseDelegate::FindBoundary() {
}
bool MultipartResponseDelegate::ReadMultipartBoundary(
- const WebCore::ResourceResponse& response,
+ const WebURLResponse& response,
std::string* multipart_boundary) {
- WebCore::String content_type = response.httpHeaderField("Content-Type");
- std::string content_type_as_string =
- webkit_glue::StringToStdString(content_type);
+ std::string content_type = WebStringToStdString(
+ response.httpHeaderField(WebString::fromUTF8("Content-Type")));
- size_t boundary_start_offset = content_type_as_string.find("boundary=");
+ size_t boundary_start_offset = content_type.find("boundary=");
if (boundary_start_offset == std::wstring::npos) {
return false;
}
boundary_start_offset += strlen("boundary=");
- size_t boundary_end_offset =
- content_type_as_string.find(';', boundary_start_offset);
+ size_t boundary_end_offset = content_type.find(';', boundary_start_offset);
if (boundary_end_offset == std::string::npos)
- boundary_end_offset = content_type_as_string.length();
+ boundary_end_offset = content_type.length();
size_t boundary_length = boundary_end_offset - boundary_start_offset;
*multipart_boundary =
- content_type_as_string.substr(boundary_start_offset, boundary_length);
+ content_type.substr(boundary_start_offset, boundary_length);
// The byte range response can have quoted boundary strings. This is legal
// as per MIME specifications. Individual data fragements however don't
// contain quoted boundary strings.
@@ -270,16 +286,14 @@ bool MultipartResponseDelegate::ReadMultipartBoundary(
}
bool MultipartResponseDelegate::ReadContentRanges(
- const WebCore::ResourceResponse& response,
+ const WebURLResponse& response,
int* content_range_lower_bound,
int* content_range_upper_bound) {
- std::string content_range =
- webkit_glue::StringToStdString(
- response.httpHeaderField("Content-Range"));
+ std::string content_range = WebStringToStdString(
+ response.httpHeaderField(WebString::fromUTF8("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;
}
@@ -321,3 +335,5 @@ 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 41d09c2..3676a78 100644
--- a/webkit/glue/multipart_response_delegate.h
+++ b/webkit/glue/multipart_response_delegate.h
@@ -1,11 +1,10 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
//
-// 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.
+// A delegate class of WebURLLoaderImpl that handles multipart/x-mixed-replace
+// data. We special case multipart/x-mixed-replace because WebCore expects a
+// separate didReceiveResponse for each new message part.
//
// Most of the logic and edge case handling are based on the Mozilla's
// implementation in netwerk/streamconv/converters/nsMultiMixedConv.cpp.
@@ -47,28 +46,28 @@
*
* ***** END LICENSE BLOCK ***** */
+#ifndef WEBKIT_GLUE_MULTIPART_RESPONSE_DELEGATE_H_
+#define WEBKIT_GLUE_MULTIPART_RESPONSE_DELEGATE_H_
+
#include <string>
-#include "config.h"
+#include "webkit/api/public/WebURLResponse.h"
-#include "base/compiler_specific.h"
+namespace WebKit {
+class WebURLLoader;
+class WebURLLoaderClient;
+}
-MSVC_PUSH_WARNING_LEVEL(0);
-#include "ResourceResponse.h"
-MSVC_POP_WARNING();
+namespace webkit_glue {
-namespace WebCore {
- class ResourceHandle;
- class ResourceHandleClient;
-}
+// Used by unit tests to access private members.
+class MultipartResponseDelegateTester;
class MultipartResponseDelegate {
- friend class MultipartResponseTest_Functions_Test; // For unittests.
-
public:
- MultipartResponseDelegate(WebCore::ResourceHandleClient* client,
- WebCore::ResourceHandle* job,
- const WebCore::ResourceResponse& response,
+ MultipartResponseDelegate(WebKit::WebURLLoaderClient* client,
+ WebKit::WebURLLoader* loader,
+ const WebKit::WebURLResponse& response,
const std::string& boundary);
// Passed through from ResourceHandleInternal
@@ -78,25 +77,27 @@ class MultipartResponseDelegate {
// Returns the multi part boundary string from the Content-type header
// in the response.
// Returns true on success.
- static bool ReadMultipartBoundary(const WebCore::ResourceResponse& response,
+ static bool ReadMultipartBoundary(const WebKit::WebURLResponse& response,
std::string* multipart_boundary);
// Returns the lower and higher content ranges from an individual multipart
// in a multipart response.
// Returns true on success.
- static bool ReadContentRanges(const WebCore::ResourceResponse& response,
+ static bool ReadContentRanges(const WebKit::WebURLResponse& response,
int* content_range_lower_bound,
int* content_range_upper_bound);
private:
- // Pointers back to our owning object so we can make callbacks as we parse
- // pieces of data.
- WebCore::ResourceHandleClient* client_;
- WebCore::ResourceHandle* job_;
+ friend class MultipartResponseDelegateTester; // For unittests.
+
+ // Pointers to the client and associated loader so we can make callbacks as
+ // we parse pieces of data.
+ WebKit::WebURLLoaderClient* client_;
+ WebKit::WebURLLoader* loader_;
// The original resource response for this request. We use this as a
// starting point for each parts response.
- WebCore::ResourceResponse original_response_;
+ WebKit::WebURLResponse original_response_;
// Checks to see if data[pos] character is a line break; handles crlf, lflf,
// lf, or cr. Returns the number of characters to skip over (0, 1 or 2).
@@ -128,3 +129,7 @@ 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 e05879d..3cafba2 100644
--- a/webkit/glue/multipart_response_delegate_unittest.cc
+++ b/webkit/glue/multipart_response_delegate_unittest.cc
@@ -4,71 +4,104 @@
#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 namespace WebCore;
-using namespace std;
+using std::string;
+using WebKit::WebString;
+using WebKit::WebURL;
+using WebKit::WebURLError;
+using WebKit::WebURLLoader;
+using WebKit::WebURLLoaderClient;
+using WebKit::WebURLRequest;
+using WebKit::WebURLResponse;
+using webkit_glue::MultipartResponseDelegate;
+using webkit_glue::MultipartResponseDelegateTester;
+
+namespace webkit_glue {
+
+class MultipartResponseDelegateTester {
+ public:
+ MultipartResponseDelegateTester(MultipartResponseDelegate* delegate)
+ : delegate_(delegate) {
+ }
+
+ int PushOverLine(const std::string& data, size_t pos) {
+ return delegate_->PushOverLine(data, pos);
+ }
+ bool ParseHeaders() { return delegate_->ParseHeaders(); }
+ size_t FindBoundary() { return delegate_->FindBoundary(); }
+ std::string& boundary() { return delegate_->boundary_; }
+ std::string& data() { return delegate_->data_; }
+
+ private:
+ MultipartResponseDelegate* delegate_;
+};
+
+} // namespace webkit_glue
namespace {
class MultipartResponseTest : public testing::Test {
};
-class MockResourceHandleClient : public ResourceHandleClient {
+class MockWebURLLoaderClient : public WebURLLoaderClient {
public:
- MockResourceHandleClient() { Reset(); }
+ MockWebURLLoaderClient() { Reset(); }
- virtual void didReceiveResponse(ResourceHandle* handle,
- const ResourceResponse& response) {
+ virtual void willSendRequest(
+ WebURLLoader*, WebURLRequest&, const WebURLResponse&) {}
+ virtual void didSendData(
+ WebURLLoader*, unsigned long long, unsigned long long) {}
+
+ virtual void didReceiveResponse(WebURLLoader* loader,
+ const WebURLResponse& response) {
++received_response_;
- resource_response_ = response;
+ response_ = response;
data_.clear();
}
- virtual void didReceiveData(ResourceHandle* handle,
+ virtual void didReceiveData(WebURLLoader* loader,
const char* data, int data_length,
- int length_received) {
+ long long 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();
- resource_response_ = ResourceResponse();
+ response_.reset();
}
int received_response_, received_data_;
string data_;
- ResourceResponse resource_response_;
+ WebURLResponse 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
- 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;
+ 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;
MultipartResponseDelegate delegate(&client, NULL, response, "bound");
+ MultipartResponseDelegateTester delegate_tester(&delegate);
struct {
const char* input;
@@ -90,8 +123,8 @@ TEST(MultipartResponseTest, Functions) {
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(line_tests); ++i) {
EXPECT_EQ(line_tests[i].expected,
- delegate.PushOverLine(line_tests[i].input,
- line_tests[i].position));
+ delegate_tester.PushOverLine(line_tests[i].input,
+ line_tests[i].position));
}
// ParseHeaders tests
@@ -112,33 +145,33 @@ TEST(MultipartResponseTest, Functions) {
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(header_tests); ++i) {
client.Reset();
- delegate.data_.assign(header_tests[i].data);
+ delegate_tester.data().assign(header_tests[i].data);
EXPECT_EQ(header_tests[i].rv,
- delegate.ParseHeaders());
+ delegate_tester.ParseHeaders());
EXPECT_EQ(header_tests[i].received_response_calls,
client.received_response_);
EXPECT_EQ(string(header_tests[i].newdata),
- delegate.data_);
+ delegate_tester.data());
}
// Test that the resource response is filled in correctly when parsing
// headers.
client.Reset();
string test_header("content-type: image/png\ncontent-length: 10\n\n");
- delegate.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"));
+ 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"));
// This header is passed from the original request.
- EXPECT_EQ(webkit_glue::StringToStdWString(
- client.resource_response_.httpHeaderField(String("foo"))),
- wstring(L"Bar"));
+ EXPECT_EQ(webkit_glue::WebStringToStdString(
+ client.response_.httpHeaderField(WebString::fromUTF8("foo"))),
+ string("Bar"));
// FindBoundary tests
struct {
@@ -154,21 +187,22 @@ TEST(MultipartResponseTest, Functions) {
{ "bound", "--boundbound", 0 },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(boundary_tests); ++i) {
- delegate.boundary_.assign(boundary_tests[i].boundary);
- delegate.data_.assign(boundary_tests[i].data);
+ delegate_tester.boundary().assign(boundary_tests[i].boundary);
+ delegate_tester.data().assign(boundary_tests[i].data);
EXPECT_EQ(boundary_tests[i].position,
- delegate.FindBoundary());
+ delegate_tester.FindBoundary());
}
}
-namespace {
-
TEST(MultipartResponseTest, MissingBoundaries) {
- 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;
+ 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;
MultipartResponseDelegate delegate(&client, NULL, response, "bound");
// No start boundary
@@ -228,11 +262,14 @@ TEST(MultipartResponseTest, MissingBoundaries) {
TEST(MultipartResponseTest, MalformedBoundary) {
// Some servers send a boundary that is prefixed by "--". See bug 5786.
- 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;
+ 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;
MultipartResponseDelegate delegate(&client, NULL, response, "--bound");
string data(
@@ -272,13 +309,14 @@ void VariousChunkSizesTest(const TestChunk chunks[], int chunks_size, int respon
"foofoofoofoofoo" // 86-100
"--bound--"); // 101-109
- ResourceResponse response(KURL(), "multipart/x-mixed-replace", 0, "en-US",
- String());
- MockResourceHandleClient client;
+ WebURLResponse response;
+ response.initialize();
+ response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace"));
+ MockWebURLLoaderClient client;
MultipartResponseDelegate delegate(&client, NULL, response, "bound");
for (int i = 0; i < chunks_size; ++i) {
- ASSERT(chunks[i].start_pos < chunks[i].end_pos);
+ ASSERT_TRUE(chunks[i].start_pos < chunks[i].end_pos);
string chunk = data.substr(chunks[i].start_pos,
chunks[i].end_pos - chunks[i].start_pos);
delegate.OnReceivedData(chunk.c_str(), static_cast<int>(chunk.length()));
@@ -385,9 +423,10 @@ TEST(MultipartResponseTest, BreakInData) {
TEST(MultipartResponseTest, MultipleBoundaries) {
// Test multiple boundaries back to back
- ResourceResponse response(KURL(), "multipart/x-mixed-replace", 0, "en-US",
- String());
- MockResourceHandleClient client;
+ WebURLResponse response;
+ response.initialize();
+ response.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace"));
+ MockWebURLLoaderClient client;
MultipartResponseDelegate delegate(&client, NULL, response, "bound");
string data("--bound\r\n\r\n--bound\r\n\r\nfoofoo--bound--");
@@ -402,12 +441,14 @@ TEST(MultipartResponseTest, MultipleBoundaries) {
TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
// Test multipart/byteranges based boundary parsing.
- ResourceResponse response1(KURL(), "multipart/byteranges", 0, "en-US",
- String());
- response1.setHTTPHeaderField(String("Content-Length"), String("200"));
+ WebURLResponse response1;
+ response1.initialize();
+ response1.setMIMEType(WebString::fromUTF8("multipart/x-mixed-replace"));
+ response1.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
+ WebString::fromUTF8("200"));
response1.setHTTPHeaderField(
- String("Content-type"),
- String("multipart/byteranges; boundary=--bound--"));
+ WebString::fromUTF8("Content-type"),
+ WebString::fromUTF8("multipart/byteranges; boundary=--bound--"));
std::string multipart_boundary;
bool result = MultipartResponseDelegate::ReadMultipartBoundary(
@@ -416,35 +457,39 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
EXPECT_EQ(string("--bound--"),
multipart_boundary);
- ResourceResponse response2(KURL(), "image/png", 0, "en-US",
- String());
+ WebURLResponse response2;
+ response2.initialize();
+ response2.setMIMEType(WebString::fromUTF8("image/png"));
- response2.setHTTPHeaderField(String("Content-Length"), String("300"));
+ response2.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
+ WebString::fromUTF8("300"));
response2.setHTTPHeaderField(
- String("Last-Modified"),
- String("Mon, 04 Apr 2005 20:36:01 GMT"));
+ WebString::fromUTF8("Last-Modified"),
+ WebString::fromUTF8("Mon, 04 Apr 2005 20:36:01 GMT"));
response2.setHTTPHeaderField(
- String("Date"),
- String("Thu, 11 Sep 2008 18:21:42 GMT"));
+ WebString::fromUTF8("Date"),
+ WebString::fromUTF8("Thu, 11 Sep 2008 18:21:42 GMT"));
multipart_boundary.clear();
result = MultipartResponseDelegate::ReadMultipartBoundary(
response2, &multipart_boundary);
EXPECT_EQ(result, false);
- ResourceResponse response3(KURL(), "multipart/byteranges", 0, "en-US",
- String());
+ WebURLResponse response3;
+ response3.initialize();
+ response3.setMIMEType(WebString::fromUTF8("multipart/byteranges"));
- response3.setHTTPHeaderField(String("Content-Length"), String("300"));
+ response3.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
+ WebString::fromUTF8("300"));
response3.setHTTPHeaderField(
- String("Last-Modified"),
- String("Mon, 04 Apr 2005 20:36:01 GMT"));
+ WebString::fromUTF8("Last-Modified"),
+ WebString::fromUTF8("Mon, 04 Apr 2005 20:36:01 GMT"));
response3.setHTTPHeaderField(
- String("Date"),
- String("Thu, 11 Sep 2008 18:21:42 GMT"));
+ WebString::fromUTF8("Date"),
+ WebString::fromUTF8("Thu, 11 Sep 2008 18:21:42 GMT"));
response3.setHTTPHeaderField(
- String("Content-type"),
- String("multipart/byteranges"));
+ WebString::fromUTF8("Content-type"),
+ WebString::fromUTF8("multipart/byteranges"));
multipart_boundary.clear();
result = MultipartResponseDelegate::ReadMultipartBoundary(
@@ -452,12 +497,15 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
EXPECT_EQ(result, false);
EXPECT_EQ(multipart_boundary.length(), 0U);
- ResourceResponse response4(KURL(), "multipart/byteranges", 0, "en-US",
- String());
- response4.setHTTPHeaderField(String("Content-Length"), String("200"));
+ WebURLResponse response4;
+ response4.initialize();
+ response4.setMIMEType(WebString::fromUTF8("multipart/byteranges"));
+ response4.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
+ WebString::fromUTF8("200"));
response4.setHTTPHeaderField(
- String("Content-type"),
- String("multipart/byteranges; boundary=--bound--; charSet=utf8"));
+ WebString::fromUTF8("Content-type"),
+ WebString::fromUTF8(
+ "multipart/byteranges; boundary=--bound--; charSet=utf8"));
multipart_boundary.clear();
@@ -466,12 +514,15 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
EXPECT_EQ(result, true);
EXPECT_EQ(string("--bound--"), multipart_boundary);
- ResourceResponse response5(KURL(), "multipart/byteranges", 0, "en-US",
- String());
- response5.setHTTPHeaderField(String("Content-Length"), String("200"));
+ WebURLResponse response5;
+ response5.initialize();
+ response5.setMIMEType(WebString::fromUTF8("multipart/byteranges"));
+ response5.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
+ WebString::fromUTF8("200"));
response5.setHTTPHeaderField(
- String("Content-type"),
- String("multipart/byteranges; boundary=\"--bound--\"; charSet=utf8"));
+ WebString::fromUTF8("Content-type"),
+ WebString::fromUTF8(
+ "multipart/byteranges; boundary=\"--bound--\"; charSet=utf8"));
multipart_boundary.clear();
@@ -482,12 +533,14 @@ TEST(MultipartResponseTest, MultipartByteRangeParsingTest) {
}
TEST(MultipartResponseTest, MultipartContentRangesTest) {
- ResourceResponse response1(KURL(), "application/pdf", 0, "en-US",
- String());
- response1.setHTTPHeaderField(String("Content-Length"), String("200"));
+ WebURLResponse response1;
+ response1.initialize();
+ response1.setMIMEType(WebString::fromUTF8("application/pdf"));
+ response1.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
+ WebString::fromUTF8("200"));
response1.setHTTPHeaderField(
- String("Content-Range"),
- String("bytes 1000-1050/5000"));
+ WebString::fromUTF8("Content-Range"),
+ WebString::fromUTF8("bytes 1000-1050/5000"));
int content_range_lower_bound = 0;
int content_range_upper_bound = 0;
@@ -500,12 +553,14 @@ TEST(MultipartResponseTest, MultipartContentRangesTest) {
EXPECT_EQ(content_range_lower_bound, 1000);
EXPECT_EQ(content_range_upper_bound, 1050);
- ResourceResponse response2(KURL(), "application/pdf", 0, "en-US",
- String());
- response2.setHTTPHeaderField(String("Content-Length"), String("200"));
+ WebURLResponse response2;
+ response2.initialize();
+ response2.setMIMEType(WebString::fromUTF8("application/pdf"));
+ response2.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
+ WebString::fromUTF8("200"));
response2.setHTTPHeaderField(
- String("Content-Range"),
- String("bytes 1000/1050"));
+ WebString::fromUTF8("Content-Range"),
+ WebString::fromUTF8("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
deleted file mode 100644
index 1912094..0000000
--- a/webkit/glue/resource_handle_impl.cc
+++ /dev/null
@@ -1,765 +0,0 @@
-// 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 e075686..91152f4 100644
--- a/webkit/glue/webkitclient_impl.cc
+++ b/webkit/glue/webkitclient_impl.cc
@@ -14,10 +14,12 @@
#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 {
@@ -34,6 +36,10 @@ 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 679cb61..54f691c 100644
--- a/webkit/glue/webkitclient_impl.h
+++ b/webkit/glue/webkitclient_impl.h
@@ -21,6 +21,7 @@ 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 0441000..e783c0d 100644
--- a/webkit/glue/webplugin_impl.cc
+++ b/webkit/glue/webplugin_impl.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "config.h"
-#include "webkit/glue/webplugin_impl.h"
#include "Cursor.h"
#include "Document.h"
@@ -49,44 +48,66 @@
#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::WebKeyboardEvent;
+using WebKit::WebData;
+using WebKit::WebHTTPBody;
using WebKit::WebInputEvent;
+using WebKit::WebKeyboardEvent;
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 WebCore::ResourceHandleClient {
+class MultiPartResponseClient : public WebURLLoaderClient {
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(WebCore::ResourceHandle* handle,
- const WebCore::ResourceResponse& response) {
+ virtual void didReceiveResponse(
+ WebURLLoader*, const WebURLResponse& response) {
if (!MultipartResponseDelegate::ReadContentRanges(
- response, &byte_range_lower_bound_, &byte_range_upper_bound_)) {
+ response,
+ &byte_range_lower_bound_,
+ &byte_range_upper_bound_)) {
NOTREACHED();
return;
}
@@ -95,21 +116,23 @@ class MultiPartResponseClient : public WebCore::ResourceHandleClient {
}
// Receives individual part data from a multipart response.
- virtual void didReceiveData(WebCore::ResourceHandle* handle,
- const char* data, int data_size,
- int reserved) {
+ virtual void didReceiveData(
+ WebURLLoader*, const char* data, int data_size, long long) {
resource_client_->DidReceiveData(
data, data_size, byte_range_lower_bound_);
}
+ virtual void didFinishLoading(WebURLLoader*) {}
+ virtual void didFail(WebURLLoader*, const WebURLError&) {}
+
void Clear() {
- resource_response_ = WebCore::ResourceResponse();
+ resource_response_.reset();
byte_range_lower_bound_ = 0;
byte_range_upper_bound_ = 0;
}
private:
- WebCore::ResourceResponse resource_response_;
+ WebURLResponse resource_response_;
// The lower bound of the byte range.
int byte_range_lower_bound_;
// The upper bound of the byte range.
@@ -118,6 +141,32 @@ class MultiPartResponseClient : public WebCore::ResourceHandleClient {
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) {
@@ -254,7 +303,7 @@ void WebPluginContainer::didReceiveResponse(
impl_->delegate_->DidReceiveManualResponse(
http_response_info.url,
base::SysWideToNativeMB(http_response_info.mime_type),
- base::SysWideToNativeMB(impl_->GetAllHeaders(response)),
+ base::SysWideToNativeMB(GetAllHeaders(response)),
http_response_info.expected_length,
http_response_info.last_modified);
}
@@ -415,17 +464,16 @@ 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].handle) {
- clients_[i].handle->cancel();
+ if (clients_[i].loader.get()) {
+ clients_[i].loader->cancel();
RemoveClient(i);
}
-
return;
}
}
}
-bool WebPluginImpl::SetPostData(WebCore::ResourceRequest* request,
+bool WebPluginImpl::SetPostData(WebURLRequest* request,
const char *buf,
uint32 length) {
std::vector<std::string> names;
@@ -433,19 +481,26 @@ bool WebPluginImpl::SetPostData(WebCore::ResourceRequest* 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::StdStringToString(names[i]),
- webkit_glue::StdStringToString(values[i]));
-
- WebCore::String content_type = request->httpContentType();
- if (content_type.isEmpty())
- request->setHTTPContentType("application/x-www-form-urlencoded");
+ for (size_t i = 0; i < names.size(); ++i) {
+ request->addHTTPHeaderField(webkit_glue::StdStringToWebString(names[i]),
+ webkit_glue::StdStringToWebString(values[i]));
+ }
- RefPtr<WebCore::FormData> data = WebCore::FormData::create();
- if (body.size())
- data->appendData(&body.front(), body.size());
+ 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"));
+ }
- request->setHTTPBody(data.release());
+ WebHTTPBody http_body;
+ if (body.size()) {
+ http_body.initialize();
+ http_body.appendData(WebData(&body[0], body.size()));
+ }
+ request->setHTTPBody(http_body);
return rv;
}
@@ -497,8 +552,8 @@ RoutingStatus WebPluginImpl::RouteToFrame(const char *method,
}
*completeURL = webkit_glue::KURLToGURL(complete_url_kurl);
- WebCore::ResourceRequest request(complete_url_kurl);
- request.setHTTPMethod(method);
+ WebURLRequest request(webkit_glue::KURLToWebURL(complete_url_kurl));
+ request.setHTTPMethod(WebString::fromUTF8(method));
if (len > 0) {
if (!is_file_data) {
if (!SetPostData(&request, buf, len)) {
@@ -514,7 +569,8 @@ RoutingStatus WebPluginImpl::RouteToFrame(const char *method,
return ROUTED;
}
}
- WebCore::FrameLoadRequest load_request(request);
+ WebCore::FrameLoadRequest load_request(
+ *webkit_glue::WebURLRequestToResourceRequest(&request));
load_request.setFrameName(str_target);
WebCore::FrameLoader *loader = frame()->loader();
// we actually don't know whether usergesture is true or false,
@@ -829,10 +885,10 @@ NPObject* WebPluginImpl::GetPluginScriptableObject() {
return delegate_->GetPluginScriptableObject();
}
-WebPluginResourceClient* WebPluginImpl::GetClientFromHandle(
- WebCore::ResourceHandle* handle) {
+WebPluginResourceClient* WebPluginImpl::GetClientFromLoader(
+ WebURLLoader* loader) {
for (size_t i = 0; i < clients_.size(); ++i) {
- if (clients_[i].handle.get() == handle)
+ if (clients_[i].loader.get() == loader)
return clients_[i].client;
}
@@ -841,54 +897,34 @@ WebPluginResourceClient* WebPluginImpl::GetClientFromHandle(
}
-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::willSendRequest(WebURLLoader* loader,
+ WebURLRequest& request,
+ const WebURLResponse&) {
+ WebPluginResourceClient* client = GetClientFromLoader(loader);
+ if (client)
+ client->WillSendRequest(request.url());
}
-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::didSendData(WebURLLoader* loader,
+ unsigned long long bytes_sent,
+ unsigned long long total_bytes_to_be_sent) {
}
-void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle,
- const WebCore::ResourceResponse& response) {
+void WebPluginImpl::didReceiveResponse(WebURLLoader* loader,
+ const WebURLResponse& response) {
static const int kHttpPartialResponseStatusCode = 206;
static const int kHttpResponseSuccessStatusCode = 200;
- WebPluginResourceClient* client = GetClientFromHandle(handle);
+ WebPluginResourceClient* client = GetClientFromLoader(loader);
if (!client)
return;
+
+ const WebCore::ResourceResponse& resource_response =
+ *webkit_glue::WebURLResponseToResourceResponse(&response);
WebPluginContainer::HttpResponseInfo http_response_info;
- WebPluginContainer::ReadHttpResponseInfo(response, &http_response_info);
+ WebPluginContainer::ReadHttpResponseInfo(resource_response,
+ &http_response_info);
bool cancel = false;
bool request_is_seekable = true;
@@ -906,7 +942,7 @@ void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle,
// continue to remain valid.
// 2. Create a new plugin instance and notify it about the response
// received here.
- if (!ReinitializePluginForResponse(handle)) {
+ if (!ReinitializePluginForResponse(loader)) {
NOTREACHED();
return;
}
@@ -920,7 +956,7 @@ void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle,
// Create a new resource client for this request.
for (size_t i = 0; i < clients_.size(); ++i) {
- if (clients_[i].handle.get() == handle) {
+ if (clients_[i].loader.get() == loader) {
WebPluginResourceClient* resource_client =
delegate_->CreateResourceClient(clients_[i].id,
plugin_url_.spec().c_str(),
@@ -937,13 +973,13 @@ void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle,
client->DidReceiveResponse(
base::SysWideToNativeMB(http_response_info.mime_type),
- base::SysWideToNativeMB(GetAllHeaders(response)),
+ base::SysWideToNativeMB(GetAllHeaders(resource_response)),
http_response_info.expected_length,
http_response_info.last_modified, request_is_seekable, &cancel);
if (cancel) {
- handle->cancel();
- RemoveClient(handle);
+ loader->cancel();
+ RemoveClient(loader);
return;
}
@@ -952,41 +988,41 @@ void WebPluginImpl::didReceiveResponse(WebCore::ResourceHandle* handle,
// 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 WebCore::String& protocol_scheme = response.url().protocol();
- if ((protocol_scheme == "http") || (protocol_scheme == "https")) {
+ const GURL& url = response.url();
+ if (url.SchemeIs("http") || url.SchemeIs("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 = GetClientFromHandle(handle);
+ WebPluginResourceClient* resource_client = GetClientFromLoader(loader);
if (resource_client) {
- handle->cancel();
+ loader->cancel();
resource_client->DidFail();
- RemoveClient(handle);
+ RemoveClient(loader);
}
}
}
}
-void WebPluginImpl::didReceiveData(WebCore::ResourceHandle* handle,
+void WebPluginImpl::didReceiveData(WebURLLoader* loader,
const char *buffer,
- 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);
- }
+ 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);
}
}
-void WebPluginImpl::didFinishLoading(WebCore::ResourceHandle* handle) {
- WebPluginResourceClient* client = GetClientFromHandle(handle);
+void WebPluginImpl::didFinishLoading(WebURLLoader* loader) {
+ WebPluginResourceClient* client = GetClientFromLoader(loader);
if (client) {
MultiPartResponseHandlerMap::iterator index =
multi_part_response_map_.find(client);
@@ -1000,25 +1036,25 @@ void WebPluginImpl::didFinishLoading(WebCore::ResourceHandle* handle) {
client->DidFinishLoading();
}
- RemoveClient(handle);
+ RemoveClient(loader);
}
-void WebPluginImpl::didFail(WebCore::ResourceHandle* handle,
- const WebCore::ResourceError&) {
- WebPluginResourceClient* client = GetClientFromHandle(handle);
+void WebPluginImpl::didFail(WebURLLoader* loader,
+ const WebURLError&) {
+ WebPluginResourceClient* client = GetClientFromLoader(loader);
if (client)
client->DidFail();
- RemoveClient(handle);
+ RemoveClient(loader);
}
void WebPluginImpl::RemoveClient(size_t i) {
clients_.erase(clients_.begin() + i);
}
-void WebPluginImpl::RemoveClient(WebCore::ResourceHandle* handle) {
+void WebPluginImpl::RemoveClient(WebURLLoader* loader) {
for (size_t i = 0; i < clients_.size(); ++i) {
- if (clients_[i].handle.get() == handle) {
+ if (clients_[i].loader.get() == loader) {
RemoveClient(i);
return;
}
@@ -1150,18 +1186,19 @@ 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.setURL(kurl);
+ info.request.initialize();
+ info.request.setURL(url);
info.request.setRequestorProcessID(delegate_->GetProcessId());
- info.request.setTargetType(WebCore::ResourceRequest::TargetIsObject);
- info.request.setHTTPMethod(method);
+ info.request.setTargetType(WebURLRequest::TargetIsObject);
+ info.request.setHTTPMethod(WebString::fromUTF8(method));
- if (range_info)
- info.request.addHTTPHeaderField("Range", range_info);
+ if (range_info) {
+ info.request.addHTTPHeaderField(WebString::fromUTF8("Range"),
+ WebString::fromUTF8(range_info));
+ }
WebCore::String referrer;
// GetURL/PostURL requests initiated explicitly by plugins should specify the
@@ -1172,8 +1209,11 @@ bool WebPluginImpl::InitiateHTTPRequest(int resource_id,
referrer = frame()->loader()->outgoingReferrer();
}
- if (!WebCore::FrameLoader::shouldHideReferrer(kurl, referrer))
- info.request.setHTTPReferrer(referrer);
+ if (!WebCore::FrameLoader::shouldHideReferrer(webkit_glue::GURLToKURL(url),
+ referrer)) {
+ info.request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
+ webkit_glue::StringToWebString(referrer));
+ }
if (strcmp(method, "POST") == 0) {
// Adds headers or form data to a request. This must be called before
@@ -1184,13 +1224,15 @@ 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, info.request, response);
+ NULL,
+ 0,
+ *webkit_glue::WebURLRequestToMutableResourceRequest(&info.request),
+ response);
- info.handle = WebCore::ResourceHandle::create(
- info.request, this, NULL, false, false);
- if (!info.handle) {
+ info.loader.reset(WebKit::webKitClient()->createURLLoader());
+ if (!info.loader.get())
return false;
- }
+ info.loader->loadAsynchronously(info.request, this);
clients_.push_back(info);
return true;
@@ -1221,7 +1263,7 @@ void WebPluginImpl::InitiateHTTPRangeRequest(const char* url,
}
void WebPluginImpl::HandleHttpMultipartResponse(
- const WebCore::ResourceResponse& response,
+ const WebURLResponse& response,
WebPluginResourceClient* client) {
std::string multipart_boundary;
if (!MultipartResponseDelegate::ReadMultipartBoundary(
@@ -1244,7 +1286,7 @@ void WebPluginImpl::HandleHttpMultipartResponse(
}
bool WebPluginImpl::ReinitializePluginForResponse(
- WebCore::ResourceHandle* response_handle) {
+ WebURLLoader* loader) {
WebFrameImpl* web_frame = WebFrameImpl::FromFrame(frame());
if (!web_frame)
return false;
@@ -1256,7 +1298,7 @@ bool WebPluginImpl::ReinitializePluginForResponse(
WebPluginContainer* container_widget = widget_;
// Destroy the current plugin instance.
- TearDownPluginInstance(response_handle);
+ TearDownPluginInstance(loader);
widget_ = container_widget;
webframe_ = web_frame;
@@ -1310,7 +1352,7 @@ void WebPluginImpl::ArrayToVector(int total_values, char** values,
}
void WebPluginImpl::TearDownPluginInstance(
- WebCore::ResourceHandle* response_handle_to_ignore) {
+ WebURLLoader* loader_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.
@@ -1332,13 +1374,13 @@ void WebPluginImpl::TearDownPluginInstance(
while (client_index != clients_.end()) {
ClientInfo& client_info = *client_index;
- if (response_handle_to_ignore == client_info.handle) {
+ if (loader_to_ignore == client_info.loader) {
client_index++;
continue;
}
- if (client_info.handle)
- client_info.handle->cancel();
+ if (client_info.loader.get())
+ client_info.loader->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 8d14792..1c3be91 100644
--- a/webkit/glue/webplugin_impl.h
+++ b/webkit/glue/webplugin_impl.h
@@ -9,41 +9,43 @@
#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 ResourceHandle;
- class ResourceError;
- class ResourceResponse;
- class ScrollView;
- class String;
- class Widget;
+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;
}
// Implements WebCore::Widget functions that WebPluginImpl needs. This class
@@ -115,7 +117,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 WebCore::ResourceHandleClient {
+ public WebKit::WebURLLoaderClient {
public:
// Creates a WebPlugin instance, as long as the delegate's initialization
// succeeds. If it fails, the delegate is deleted and NULL is returned.
@@ -134,7 +136,7 @@ class WebPluginImpl : public WebPlugin,
virtual NPObject* GetPluginScriptableObject();
// Helper function for sorting post data.
- static bool SetPostData(WebCore::ResourceRequest* request,
+ static bool SetPostData(WebKit::WebURLRequest* request,
const char* buf,
uint32 length);
@@ -240,27 +242,28 @@ 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(
- WebCore::ResourceHandle* response_handle_to_ignore);
+ void TearDownPluginInstance(WebKit::WebURLLoader* loader_to_ignore);
WebCore::ScrollView* parent() const;
- // ResourceHandleClient implementation. We implement this interface in the
+ // WebURLLoaderClient implementation. We implement this interface in the
// renderer process, and then use the simple WebPluginResourceClient interface
// to relay the callbacks to the plugin.
- 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&);
+ 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&);
// Helper function
- WebPluginResourceClient* GetClientFromHandle(WebCore::ResourceHandle* handle);
+ WebPluginResourceClient* GetClientFromLoader(WebKit::WebURLLoader* loader);
// Helper function to remove the stored information about a resource
// request given its index in m_clients.
@@ -268,10 +271,7 @@ class WebPluginImpl : public WebPlugin,
// Helper function to remove the stored information about a resource
// request given a handle.
- void RemoveClient(WebCore::ResourceHandle* handle);
-
- // Returns all the response headers in one string, including the status code.
- std::wstring GetAllHeaders(const WebCore::ResourceResponse& response);
+ void RemoveClient(WebKit::WebURLLoader* loader);
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 WebCore::ResourceResponse& response,
+ void HandleHttpMultipartResponse(const WebKit::WebURLResponse& 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 response_handle parameter.
- bool ReinitializePluginForResponse(WebCore::ResourceHandle* response_handle);
+ // to handle the response identified by the loader parameter.
+ bool ReinitializePluginForResponse(WebKit::WebURLLoader* loader);
// 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;
- WebCore::ResourceRequest request;
- RefPtr<WebCore::ResourceHandle> handle;
+ WebKit::WebURLRequest request;
+ linked_ptr<WebKit::WebURLLoader> loader;
};
std::vector<ClientInfo> clients_;
@@ -336,7 +336,8 @@ class WebPluginImpl : public WebPlugin,
WebPluginContainer* widget_;
- typedef std::map<WebPluginResourceClient*, MultipartResponseDelegate*>
+ typedef std::map<WebPluginResourceClient*,
+ webkit_glue::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 b518361..b6c62f6 100644
--- a/webkit/glue/webplugin_impl_unittest.cc
+++ b/webkit/glue/webplugin_impl_unittest.cc
@@ -4,18 +4,21 @@
#include "config.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();
+// Avoid collisions with the LOG macro
+#include <wtf/Assertions.h>
#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 {
@@ -30,6 +33,34 @@ 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
@@ -37,46 +68,47 @@ std::ostream& operator<<(std::ostream& out, const WebCore::String& str)
TEST(WebPluginImplTest, PostParserSimple) {
// Test a simple case with headers & data
const char *ex1 = "foo: bar\nContent-length: 10\n\nabcdefghij";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- 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());
+ 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));
}
TEST(WebPluginImplTest, PostParserLongHeader) {
// Test a simple case with long headers
const char *ex1 = "foo: 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n\nabcdefghij";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- EXPECT_EQ(100U, request.httpHeaderField("foo").stripWhiteSpace().length());
+ EXPECT_EQ(100U, GetHeader(request, "foo").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";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- 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");
+ 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));
}
TEST(WebPluginImplTest, PostParserDuplicateHeaders) {
@@ -84,7 +116,8 @@ 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";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
@@ -93,43 +126,47 @@ TEST(WebPluginImplTest, PostParserDuplicateHeaders) {
TEST(WebPluginImplTest, PostParserNoHeaders) {
// Test a simple case with no headers but with data
const char *ex1 = "\nabcdefghij";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- 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());
+ 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));
}
TEST(WebPluginImplTest, PostParserNoBody) {
// Test a simple case with headers and no body
const char *ex1 = "Foo:bar\n\n";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- 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());
+ 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());
}
TEST(WebPluginImplTest, PostParserBodyWithNewLines) {
// Test a simple case with headers and no body
const char *ex1 = "Foo:bar\n\n\n\nabcdefg\n\nabcdefg";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- EXPECT_EQ(request.httpBody()->flattenToString(), "\n\nabcdefg\n\nabcdefg");
+ EXPECT_EQ(GetBodyText(request), "\n\nabcdefg\n\nabcdefg");
}
TEST(WebPluginImplTest, PostParserErrorNoBody) {
// Test with headers and no body
const char *ex1 = "Foo:bar\n";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
@@ -138,7 +175,8 @@ TEST(WebPluginImplTest, PostParserErrorNoBody) {
TEST(WebPluginImplTest, PostParserErrorEmpty) {
// Test with an empty string
const char *ex1 = "";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
@@ -147,36 +185,39 @@ 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";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace());
- EXPECT_EQ("body", request.httpBody()->flattenToString());
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ("body", GetBodyText(request));
}
TEST(WebPluginImplTest, PostParserEmptyValue) {
// Test an error case with an empty value field
const char *ex1 = "foo:bar\nbar:\n\nbody";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace());
- EXPECT_EQ(0U, request.httpHeaderField("bar").length());
- EXPECT_EQ("body", request.httpBody()->flattenToString());
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ("body", GetBodyText(request));
}
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";
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
static_cast<uint32>(strlen(ex1)));
EXPECT_EQ(true, rv);
- EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace());
- EXPECT_EQ(0U, request.httpHeaderField("bar").length());
- EXPECT_EQ("body\r\n\r\nbody2", request.httpBody()->flattenToString());
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ("body\r\n\r\nbody2", GetBodyText(request));
}
TEST(WebPluginImplTest, PostParserBodyWithBinaryData) {
@@ -186,19 +227,19 @@ TEST(WebPluginImplTest, PostParserBodyWithBinaryData) {
memcpy(ex1 + strlen("foo: bar\nContent-length: 10\n\n"), &binary_data,
sizeof(binary_data));
- WebCore::ResourceRequest request;
+ WebURLRequest request;
+ request.initialize();
bool rv = WebPluginImpl::SetPostData(&request, ex1,
sizeof(ex1)/sizeof(ex1[0]));
EXPECT_EQ(true, rv);
- EXPECT_EQ("bar", request.httpHeaderField("foo").stripWhiteSpace());
- EXPECT_EQ(0U, request.httpHeaderField("bar").length());
- EXPECT_EQ(0U, request.httpHeaderField("Content-length").length());
+ EXPECT_EQ("bar", GetHeader(request, "foo"));
+ EXPECT_EQ(0U, GetHeader(request, "bar").length());
+ EXPECT_EQ(0U, GetHeader(request, "Content-length").length());
- Vector<char> expected_data;
- request.httpBody()->flatten(expected_data);
+ std::string body = GetBodyText(request);
- 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]);
+ 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]);
}
diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc
new file mode 100644
index 0000000..ceb5fc8
--- /dev/null
+++ b/webkit/glue/weburlloader_impl.cc
@@ -0,0 +1,501 @@
+// 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.
+ 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
new file mode 100644
index 0000000..2ad50c3
--- /dev/null
+++ b/webkit/glue/weburlloader_impl.h
@@ -0,0 +1,61 @@
+// 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_
diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp
index 534ce7d..844acc1 100644
--- a/webkit/webkit.gyp
+++ b/webkit/webkit.gyp
@@ -4208,6 +4208,7 @@
'api/public/WebData.h',
'api/public/WebDragData.h',
'api/public/WebFindOptions.h',
+ 'api/public/WebHTTPBody.h',
'api/public/WebImage.h',
'api/public/WebInputEvent.h',
'api/public/WebKit.h',
@@ -4215,6 +4216,7 @@
'api/public/WebMediaPlayer.h',
'api/public/WebMediaPlayerClient.h',
'api/public/WebMimeRegistry.h',
+ 'api/public/WebNonCopyable.h',
'api/public/WebPluginListBuilder.h',
'api/public/WebPoint.h',
'api/public/WebRect.h',
@@ -4223,6 +4225,11 @@
'api/public/WebSize.h',
'api/public/WebString.h',
'api/public/WebURL.h',
+ 'api/public/WebURLError.h',
+ 'api/public/WebURLLoader.h',
+ 'api/public/WebURLLoaderClient.h',
+ 'api/public/WebURLRequest.h',
+ 'api/public/WebURLResponse.h',
'api/public/WebVector.h',
'api/public/win/WebInputEventFactory.h',
'api/public/win/WebSandboxSupport.h',
@@ -4236,11 +4243,13 @@
'api/src/mac/WebInputEventFactory.mm',
'api/src/mac/WebScreenInfoFactory.mm',
'api/src/MediaPlayerPrivateChromium.cpp',
+ 'api/src/ResourceHandle.cpp',
'api/src/TemporaryGlue.h',
'api/src/WebCache.cpp',
'api/src/WebCString.cpp',
'api/src/WebData.cpp',
'api/src/WebDragData.cpp',
+ 'api/src/WebHTTPBody.cpp',
'api/src/WebImageSkia.cpp',
'api/src/WebInputEvent.cpp',
'api/src/WebKit.cpp',
@@ -4250,6 +4259,13 @@
'api/src/WebPluginListBuilderImpl.h',
'api/src/WebString.cpp',
'api/src/WebURL.cpp',
+ 'api/src/WebURLRequest.cpp',
+ 'api/src/WebURLRequestPrivate.h',
+ 'api/src/WebURLResponse.cpp',
+ 'api/src/WebURLResponsePrivate.h',
+ 'api/src/WebURLError.cpp',
+ 'api/src/WrappedResourceRequest.h',
+ 'api/src/WrappedResourceResponse.h',
'api/src/win/WebInputEventFactory.cpp',
'api/src/win/WebScreenInfoFactory.cpp',
],
@@ -4510,7 +4526,6 @@
'glue/password_form_dom_manager.h',
'glue/resource_fetcher.cc',
'glue/resource_fetcher.h',
- 'glue/resource_handle_impl.cc',
'glue/resource_loader_bridge.cc',
'glue/resource_loader_bridge.h',
'glue/resource_type.h',
@@ -4577,6 +4592,8 @@
'glue/webtextinput_impl.cc',
'glue/webtextinput_impl.h',
'glue/webthemeengine_impl_win.cc',
+ 'glue/weburlloader_impl.cc',
+ 'glue/weburlloader_impl.h',
'glue/weburlrequest.h',
'glue/weburlrequest_impl.cc',
'glue/weburlrequest_impl.h',