+2006-11-03 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Adele.
+
+ - replaced receivedRedirect with new willSendRequest delegate
+ - removed most mac-specific loader functions
+ - use ResourceResponse more in loader code
+
+ * WebCore.xcodeproj/project.pbxproj: Add new files.
+ * bridge/mac/WebCoreFrameBridge.mm:
+ (-[WebCoreFrameBridge getData:andResponse:forURL:]): Adapted
+ for CachedResource method renames.
+ (-[WebCoreFrameBridge getAllResourceDatas:andResponses:]):
+ Ditto.
+ * loader/CachedCSSStyleSheet.cpp:
+ (WebCore::CachedCSSStyleSheet::checkNotify): simplified
+ based on ResourceResponse
+ * loader/CachedImage.cpp:
+ (WebCore::CachedImage::createImage): adapt for ResourceResponse
+ * loader/CachedResource.cpp:
+ (WebCore::CachedResource::CachedResource): store a ResourceResponse;
+ platform response is now called platformResponse and expiration date
+ is removed.
+ (WebCore::CachedResource::~CachedResource): ditto
+ (WebCore::CachedResource::isExpired): ditto
+ * loader/CachedResource.h:
+ (WebCore::CachedResource::platformResponse): ditto
+ (WebCore::CachedResource::setResponse): ditto
+ (WebCore::CachedResource::canDelete): ditto
+ * loader/LoaderFunctions.h:
+ * loader/loader.cpp:
+ (WebCore::Loader::receivedResponse): Adjusted for renames.
+ (WebCore::Loader::didReceiveResponse): Store whole ResourceResponse
+ in the CachedResource.
+ * loader/loader.h:
+ * loader/mac/FormDataStream.h:
+ * loader/mac/FormDataStream.m:
+ (WebCore::getStreamFormDatas): Rearranged things so it's
+ possible to get a FormData back out of a form data stream.
+ (WebCore::formCreate): ditto
+ (WebCore::formFinalize): ditto
+ (WebCore::httpBodyFromStream): ditto
+ * loader/mac/ImageDocumentMac.mm:
+ (WebCore::finishImageLoad): s/response/platformResponse/
+ * loader/mac/LoaderFunctionsMac.mm:
+ (WebCore::CheckCacheObjectStatus): ditto
+ (WebCore::CachedResource::setPlatformResponse): ditto
+ * loader/mac/SubresourceLoaderMac.mm:
+ (WebCore::SubresourceLoader::willSendRequest): send redirect
+ to client appropriately
+ * platform/network/ResourceHandle.h:
+ * platform/network/ResourceHandleClient.h:
+ (WebCore::ResourceHandleClient::willSendRequest): new entry
+ point for SubresourceLoader, dispatch to client.
+ * platform/network/ResourceRequest.h:
+ (WebCore::ResourceRequest::allowHTTPCookies): implemented
+ (WebCore::ResourceRequest::setAllowHTTPCookies): ditto
+ * platform/network/ResourceResponse.h:
+ (WebCore::ResourceResponse::ResourceResponse): initialize expiration
+ date(!)
+ * platform/network/cf/FormDataStreamCFNet.cpp: Added.
+ (WebCore::getStreamFormDatas): Added this, ported from NSURL version.
+ (WebCore::openNextStream): ditto
+ (WebCore::formCreate): ditto
+ (WebCore::formFinalize): ditto
+ (WebCore::formCanRead): ditto
+ (WebCore::formEventCallback): ditto
+ (WebCore::setHTTPBody): ditto
+ (WebCore::httpBodyFromStream): ditto
+ * platform/network/cf/FormDataStreamCFNet.h: Added.
+ * platform/network/cf/ResourceHandleCFNet.cpp:
+ (WebCore::willSendRequest): implemented
+ (WebCore::ResourceHandle::start): use new ResourceRequest stuff
+ * platform/network/cf/ResourceResponseCFNet.cpp:
+ (WebCore::getResourceResponse): do nothing for a null response
+ * platform/network/mac/ResourceHandleMac.mm:
+ (WebCore::ResourceHandle::willSendRequest): Implemented; dispatch to client.
+ * platform/network/mac/ResourceRequestMac.h: Added.
+ * platform/network/mac/ResourceRequestMac.mm: Added.
+ (WebCore::getResourceRequest): Added way to convert an NSURLRequest
+ to a ResourceRequest.
+ (WebCore::nsURLRequest): Opposite of the above.
+ * platform/network/cf/ResourceRequestCFNet.h: Added.
+ * platform/network/cf/ResourceRequestCFNet.cpp: Added.
+ (WebCore::getResourceRequest): Added way to convert an CFURLRequest
+ to a ResourceRequest.
+ (WebCore::cfURLRequest): Opposite of the above.
+ * xml/xmlhttprequest.cpp:
+ (WebCore::XMLHttpRequest::willSendRequest): Renamed from receivedRedirect,
+ adjusted.
+ * xml/xmlhttprequest.h:
+
2006-11-04 Darin Adler <darin@apple.com>
Change suggested by Mitz.
51F11E150A48C2920034A24E /* SQLTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F11E140A48C2920034A24E /* SQLTransaction.cpp */; };
550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; };
550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 650E3F690AF6C168001FA3AD /* ResourceRequestMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 650E3F670AF6C168001FA3AD /* ResourceRequestMac.h */; };
+ 650E3F6A0AF6C168001FA3AD /* ResourceRequestMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 650E3F680AF6C168001FA3AD /* ResourceRequestMac.mm */; };
650F53DC09D15DDA00C9B0C8 /* CSSGrammar.h in Headers */ = {isa = PBXBuildFile; fileRef = 650F53DB09D15DDA00C9B0C8 /* CSSGrammar.h */; };
650F53DD09D15DDF00C9B0C8 /* CSSGrammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6565814409D13043000E61D7 /* CSSGrammar.cpp */; };
651B4D8509AC83370029F1EF /* DeprecatedStringList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651B4D8309AC83370029F1EF /* DeprecatedStringList.cpp */; };
6550B6A6099DF0270090D781 /* Text.h in Headers */ = {isa = PBXBuildFile; fileRef = 6550B69C099DF0270090D781 /* Text.h */; settings = {ATTRIBUTES = (Private, ); }; };
6552E7AA096AA11B0006F248 /* WebCoreFrameNamespaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 6552E7A8096AA11B0006F248 /* WebCoreFrameNamespaces.h */; settings = {ATTRIBUTES = (Private, ); }; };
6552E7AB096AA11B0006F248 /* WebCoreFrameNamespaces.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6552E7A9096AA11B0006F248 /* WebCoreFrameNamespaces.mm */; };
- 655A81BE0AEF67E6000975F0 /* HTTPHeaderMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 655A81BD0AEF67E6000975F0 /* HTTPHeaderMap.h */; };
+ 655A81BE0AEF67E6000975F0 /* HTTPHeaderMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 655A81BD0AEF67E6000975F0 /* HTTPHeaderMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
6563A9A70ADF4094000ED2CD /* LoaderNSURLRequestExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 6563A9A50ADF4094000ED2CD /* LoaderNSURLRequestExtras.h */; };
6563A9A80ADF4094000ED2CD /* LoaderNSURLRequestExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 6563A9A60ADF4094000ED2CD /* LoaderNSURLRequestExtras.m */; };
656580F409D12B20000E61D7 /* CSSPropertyNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 656580EF09D12B20000E61D7 /* CSSPropertyNames.h */; };
6582A16309999D6D00BEEB6D /* SystemTimeMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6582A15509999D6D00BEEB6D /* SystemTimeMac.cpp */; };
6582A17809999EA000BEEB6D /* DeprecatedStringMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6582A17709999EA000BEEB6D /* DeprecatedStringMac.mm */; };
658436860AE01B7400E53753 /* FrameLoadRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 658436850AE01B7400E53753 /* FrameLoadRequest.h */; };
- 658821660AF4CDF700F01D1F /* ResourceResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 658821650AF4CDF700F01D1F /* ResourceResponse.h */; };
+ 658821660AF4CDF700F01D1F /* ResourceResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 658821650AF4CDF700F01D1F /* ResourceResponse.h */; settings = {ATTRIBUTES = (Private, ); }; };
6588216B0AF4CE1200F01D1F /* ResourceResponseMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 658821680AF4CE1200F01D1F /* ResourceResponseMac.h */; };
6588216C0AF4CE1200F01D1F /* ResourceResponseMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 658821690AF4CE1200F01D1F /* ResourceResponseMac.mm */; };
65901A4409FC6039005BD752 /* WebCoreStringTruncator.h in Headers */ = {isa = PBXBuildFile; fileRef = 65901A4209FC6039005BD752 /* WebCoreStringTruncator.h */; settings = {ATTRIBUTES = (Private, ); }; };
55998A5B052B59CC0017A6C1 /* WebCoreAXObject.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreAXObject.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
55998A5C052B59CC0017A6C1 /* AXObjectCache.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = AXObjectCache.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
55998A5D052B59CC0017A6C1 /* AXObjectCacheMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AXObjectCacheMac.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 650E3F670AF6C168001FA3AD /* ResourceRequestMac.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ResourceRequestMac.h; sourceTree = "<group>"; };
+ 650E3F680AF6C168001FA3AD /* ResourceRequestMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceRequestMac.mm; sourceTree = "<group>"; };
650F53DB09D15DDA00C9B0C8 /* CSSGrammar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSGrammar.h; sourceTree = "<group>"; };
651B4D8309AC83370029F1EF /* DeprecatedStringList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DeprecatedStringList.cpp; sourceTree = "<group>"; };
651B4D8409AC83370029F1EF /* DeprecatedStringList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DeprecatedStringList.h; sourceTree = "<group>"; };
isa = PBXGroup;
children = (
656B84EA0AEA1DDA00A095B4 /* ResourceHandleMac.mm */,
+ 650E3F670AF6C168001FA3AD /* ResourceRequestMac.h */,
+ 650E3F680AF6C168001FA3AD /* ResourceRequestMac.mm */,
658821680AF4CE1200F01D1F /* ResourceResponseMac.h */,
658821690AF4CE1200F01D1F /* ResourceResponseMac.mm */,
);
93E22A730AF5E94C00D48324 /* PageState.h in Headers */,
658821660AF4CDF700F01D1F /* ResourceResponse.h in Headers */,
6588216B0AF4CE1200F01D1F /* ResourceResponseMac.h in Headers */,
+ 650E3F690AF6C168001FA3AD /* ResourceRequestMac.h in Headers */,
93CCF0270AF6C52900018E89 /* NavigationAction.h in Headers */,
B2A015A90AF6CD53006BCE0E /* GraphicsContext.h in Headers */,
B2A015AB0AF6CD53006BCE0E /* GraphicsTypes.h in Headers */,
93E227E30AF589AD00D48324 /* ResourceLoader.cpp in Sources */,
93E227E40AF589AD00D48324 /* SubresourceLoader.cpp in Sources */,
93E22A6F0AF5E94100D48324 /* PageState.cpp in Sources */,
+ 650E3F6A0AF6C168001FA3AD /* ResourceRequestMac.mm in Sources */,
93CCF0580AF6C9FE00018E89 /* NavigationActionMac.mm in Sources */,
93CCF0600AF6CA7600018E89 /* NavigationAction.cpp in Sources */,
B2A015A80AF6CD53006BCE0E /* GraphicsContext.cpp in Sources */,
return NO;
*data = resource->allData();
- *response = resource->response();
+ *response = resource->platformResponse();
return YES;
}
HashMap<String, CachedResource*>::const_iterator end = allResources.end();
for (HashMap<String, CachedResource*>::const_iterator it = allResources.begin(); it != end; ++it) {
[d addObject:it->second->allData()];
- [r addObject:it->second->response()];
+ [r addObject:it->second->platformResponse()];
}
*datas = [d autorelease];
return;
CachedResourceClientWalker w(m_clients);
- while (CachedResourceClient *c = w.next()) {
- if (m_response && !IsResponseURLEqualToURL(m_response, m_url))
- c->setCSSStyleSheet(ResponseURL(m_response), m_decoder->encoding().name(), m_sheet);
- else
- c->setCSSStyleSheet(m_url, m_decoder->encoding().name(), m_sheet);
- }
+ while (CachedResourceClient *c = w.next())
+ c->setCSSStyleSheet(m_response.url().url(), m_decoder->encoding().name(), m_sheet);
}
void CachedCSSStyleSheet::error()
{
// Create the image if it doesn't yet exist.
if (!m_image)
- m_image = new Image(this, ResponseMIMEType(m_response) == "application/pdf");
+ m_image = new Image(this, m_response.mimeType() == "application/pdf");
}
Vector<char>& CachedImage::bufferData(const char* bytes, int addedSize, Request* request)
namespace WebCore {
-CachedResource::CachedResource(const String& URL, Type type, CachePolicy cachePolicy, time_t expireDate, unsigned size)
+CachedResource::CachedResource(const String& URL, Type type, CachePolicy cachePolicy, unsigned size)
{
m_url = URL;
m_type = type;
m_inCache = false;
m_cachePolicy = cachePolicy;
m_request = 0;
- m_response = 0;
+ m_platformResponse = 0;
m_allData = 0;
- m_expireDate = expireDate;
m_expireDateChanged = false;
m_accessCount = 0;
m_nextInLRUList = 0;
#ifndef NDEBUG
m_deleted = true;
#endif
- setResponse(0);
+ setPlatformResponse(0);
setAllData(0);
}
m_expireDateChanged = false;
}
-void CachedResource::setExpireDate(time_t expireDate, bool changeHttpCache)
-{
- if (expireDate == m_expireDate)
- return;
-
- if (m_status == Cached)
- finish();
-
- m_expireDate = expireDate;
- if (changeHttpCache && m_expireDate)
- m_expireDateChanged = true;
-}
-
bool CachedResource::isExpired() const
{
- if (!m_expireDate)
+ if (!m_response.expirationDate())
return false;
time_t now = time(0);
- return (difftime(now, m_expireDate) >= 0);
+ return (difftime(now, m_response.expirationDate()) >= 0);
}
void CachedResource::setRequest(Request* request)
#include "CachePolicy.h"
#include "PlatformString.h"
#include "ResourceHandleClient.h" // defines PlatformResponse and PlatformData
+#include "ResourceResponse.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
#include <time.h>
Cached // regular case
};
- CachedResource(const String& URL, Type type, CachePolicy cachePolicy, time_t expireDate, unsigned size = 0);
+ CachedResource(const String& URL, Type type, CachePolicy cachePolicy, unsigned size = 0);
virtual ~CachedResource();
virtual void setEncoding(const String&) { }
void setRequest(Request*);
- PlatformResponse response() const { return m_response; }
- void setResponse(PlatformResponse);
+ PlatformResponse platformResponse() const { return m_platformResponse; }
+ void setPlatformResponse(PlatformResponse);
PlatformData allData() const { return m_allData; }
void setAllData(PlatformData);
- bool canDelete() const { return !referenced() && !m_request; }
+ void setResponse(const ResourceResponse& response) { m_response = response; }
- void setExpireDate(time_t expireDate, bool changeHttpCache);
+ bool canDelete() const { return !referenced() && !m_request; }
bool isExpired() const;
RetainPtr<NSURLRequest> m_nsURLRequest;
#endif
- PlatformResponse m_response;
+ ResourceResponse m_response;
+ PlatformResponse m_platformResponse;
PlatformData m_allData;
Type m_type;
unsigned m_accessCount;
protected:
- time_t m_expireDate;
CachePolicy m_cachePolicy;
bool m_inCache;
bool m_loading;
void CheckCacheObjectStatus(DocLoader*, CachedResource*);
bool CheckIfReloading(DocLoader*);
-bool IsResponseURLEqualToURL(PlatformResponse , const String& URL);
-DeprecatedString ResponseURL(PlatformResponse);
-DeprecatedString ResponseMIMEType(PlatformResponse);
-bool ResponseIsMultipart(PlatformResponse);
-NSString* HeaderStringFromDictionary(NSDictionary* headers, int statusCode);
}
// FIXME: the win32 platform does not have PlatformResponse yet.
ASSERT(response);
#endif
- req->cachedResource()->setResponse(response);
+ req->cachedResource()->setPlatformResponse(response);
}
-void Loader::didReceivedResponse(ResourceHandle* handle, const ResourceResponse& response)
+void Loader::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response)
{
Request* req = m_requestsLoading.get(handle);
ASSERT(req);
- req->cachedResource()->setExpireDate(response.expirationDate(), false);
+ req->cachedResource()->setResponse(response);
String encoding = response.textEncodingName();
if (!encoding.isNull())
private:
virtual void receivedResponse(ResourceHandle*, PlatformResponse);
- virtual void didReceivedResponse(ResourceHandle* handle, const ResourceResponse& response);
+ virtual void didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response);
virtual void didReceiveData(ResourceHandle*, const char*, int);
virtual void receivedAllData(ResourceHandle*, PlatformData);
namespace WebCore {
class FormData;
void setHTTPBody(NSMutableURLRequest *, const FormData&);
+ const FormData* httpBodyFromStream(NSInputStream* stream);
}
#import <sys/stat.h>
#import <sys/types.h>
#import <wtf/Assertions.h>
+#import <wtf/HashMap.h>
namespace WebCore {
+static HashMap<CFReadStreamRef, const FormData*>* streamFormDatas = 0;
+
+static HashMap<CFReadStreamRef, const FormData*>* getStreamFormDatas()
+{
+ if (!streamFormDatas)
+ streamFormDatas = new HashMap<CFReadStreamRef, const FormData*>();
+ return streamFormDatas;
+}
+
static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context);
struct FormStreamFields {
for (size_t i = 0; i < size; ++i)
newInfo->remainingElements.append(formData->elements()[size - i - 1]);
+ getStreamFormDatas()->set(stream, new FormData(*formData));
+
return newInfo;
}
{
FormStreamFields* form = static_cast<FormStreamFields*>(context);
+ delete getStreamFormDatas()->get(stream);
+ getStreamFormDatas()->remove(stream);
+
closeCurrentStream(form);
CFRelease(form->scheduledRunLoopPairs);
delete form;
CFRelease(stream);
}
+
+const FormData* httpBodyFromStream(NSInputStream* stream)
+{
+ return getStreamFormDatas()->get((CFReadStreamRef)stream);
+}
+
}
Frame* frame = document->frame();
NSURLResponse *response = frame->loader()->documentLoader()->response();
- image->setResponse(response);
+ image->setPlatformResponse(response);
IntSize size = image->imageSize();
if (size.width())
return;
}
- ASSERT(cachedResource->response());
+ ASSERT(cachedResource->platformResponse());
// Notify the caller that we "loaded".
FrameMac *frame = static_cast<FrameMac *>(loader->frame());
return;
NSURLRequest *request = cachedResource->getNSURLRequest();
- NSURLResponse *response = cachedResource->response();
+ NSURLResponse *response = cachedResource->platformResponse();
NSData *data = cachedResource->allData();
// FIXME: If the WebKit client changes or cancels the request, WebCore does not respect this and continues the load.
return false;
}
-void CachedResource::setResponse(PlatformResponse response)
+void CachedResource::setPlatformResponse(PlatformResponse response)
{
HardRetain(response);
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- HardRelease(m_response);
+ HardRelease(m_platformResponse);
END_BLOCK_OBJC_EXCEPTIONS;
- m_response = response;
+ m_platformResponse = response;
}
void CachedResource::setAllData(PlatformData allData)
NSURL *oldURL = [request() URL];
NSURLRequest *clientRequest = ResourceLoader::willSendRequest(newRequest, redirectResponse);
if (clientRequest && oldURL != [clientRequest URL] && ![oldURL isEqual:[clientRequest URL]])
- m_handle->redirectedToURL([clientRequest URL]);
+ clientRequest = m_handle->willSendRequest(clientRequest, redirectResponse);
return clientRequest;
}
#if PLATFORM(MAC)
#ifdef __OBJC__
@class WebCoreResourceLoaderImp;
+@class NSURLRequest;
+@class NSURLResponse;
#else
class WebCoreResourceLoaderImp;
+class NSURLRequest;
+class NSURLResponse;
#endif
#endif
void kill();
#if PLATFORM(MAC)
- void redirectedToURL(NSURL *url);
+ NSURLRequest *willSendRequest(NSURLRequest *, NSURLResponse *);
void addData(NSData *data);
void finishJobAndHandle(NSData *data);
void reportError();
class KURL;
class ResourceHandle;
+ class ResourceRequest;
class ResourceResponse;
class ResourceHandleClient {
virtual ~ResourceHandleClient() { }
// request may be modified
- // void willSendRequest(ResourceHandle*, Request&, const ResourceResonse& redirectResponse) { }
+ virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse& redirectResponse) { }
// void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) { }
// void didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) { }
// void willCacheResponse(ResourceHandle*, CachedResourceResponse&) { }
// old-style methods
- virtual void receivedRedirect(ResourceHandle*, const KURL&) { }
virtual void receivedResponse(ResourceHandle*, PlatformResponse) { }
virtual void receivedAllData(ResourceHandle*, PlatformData) { }
};
FormData& httpBody() { return m_httpBody; }
void setHTTPBody(const FormData& httpBody) { m_httpBody = httpBody; }
- bool allowHTTPCookies() const;
- void setAllowHTTPCookies(bool);
+ bool allowHTTPCookies() const { return m_allowHTTPCookies; }
+ void setAllowHTTPCookies(bool allowHTTPCookies) { m_allowHTTPCookies = allowHTTPCookies; }
private:
static const int defaultTimeoutInterval = 60;
class ResourceResponse {
public:
- ResourceResponse() : m_expectedContentLength(0), m_httpStatusCode(0) {}
+ ResourceResponse()
+ : m_expectedContentLength(0)
+ , m_httpStatusCode(0)
+ , m_expirationDate(0)
+ {
+ }
ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
: m_url(url)
, m_textEncodingName(textEncodingName)
, m_suggestedFilename(filename)
, m_httpStatusCode(0)
+ , m_expirationDate(0)
{
}
const HTTPHeaderMap& httpHeaderFields() const { return m_httpHeaderFields; }
HTTPHeaderMap& httpHeaderFields() { return m_httpHeaderFields; }
- // possibly add calculated expiration info
- // lastModifiedDate (date)
-
bool isMultipart() const { return m_mimeType == "multipart/x-mixed-replace"; }
void setExpirationDate(time_t expirationDate) { m_expirationDate = expirationDate; }
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.
+ */
+
+/* originally written by Becky Willrich, additional code by Darin Adler */
+
+#include "config.h"
+#include "FormDataStreamCFNet.h"
+
+#include "CString.h"
+#include "FormData.h"
+#include <CFNetwork/CFURLRequestPriv.h>
+#include <CoreFoundation/CFStreamAbstract.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+
+
+namespace WebCore {
+
+static HashMap<CFReadStreamRef, const FormData*>* streamFormDatas = 0;
+
+static HashMap<CFReadStreamRef, const FormData*>* getStreamFormDatas()
+{
+ if (!streamFormDatas)
+ streamFormDatas = new HashMap<CFReadStreamRef, const FormData*>();
+ return streamFormDatas;
+}
+
+static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context);
+
+struct FormStreamFields {
+ CFMutableSetRef scheduledRunLoopPairs;
+ Vector<FormDataElement> remainingElements; // in reverse order
+ CFReadStreamRef currentStream;
+ char* currentData;
+ CFReadStreamRef formStream;
+};
+
+struct SchedulePair {
+ CFRunLoopRef runLoop;
+ CFStringRef mode;
+};
+
+static const void* pairRetain(CFAllocatorRef alloc, const void* value)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+
+ SchedulePair* result = new SchedulePair;
+ CFRetain(pair->runLoop);
+ result->runLoop = pair->runLoop;
+ result->mode = CFStringCreateCopy(alloc, pair->mode);
+ return result;
+}
+
+static void pairRelease(CFAllocatorRef alloc, const void* value)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+
+ CFRelease(pair->runLoop);
+ CFRelease(pair->mode);
+ delete pair;
+}
+
+static Boolean pairEqual(const void* a, const void* b)
+{
+ const SchedulePair* pairA = static_cast<const SchedulePair*>(a);
+ const SchedulePair* pairB = static_cast<const SchedulePair*>(b);
+
+ return pairA->runLoop == pairB->runLoop && CFEqual(pairA->mode, pairB->mode);
+}
+
+static CFHashCode pairHash(const void* value)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+
+ return (CFHashCode)pair->runLoop ^ CFHash(pair->mode);
+}
+
+static void closeCurrentStream(FormStreamFields *form)
+{
+ if (form->currentStream) {
+ CFReadStreamClose(form->currentStream);
+ CFReadStreamSetClient(form->currentStream, kCFStreamEventNone, NULL, NULL);
+ CFRelease(form->currentStream);
+ form->currentStream = NULL;
+ }
+ if (form->currentData) {
+ fastFree(form->currentData);
+ form->currentData = 0;
+ }
+}
+
+static void scheduleWithPair(const void* value, void* context)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+ CFReadStreamRef stream = (CFReadStreamRef)context;
+
+ CFReadStreamScheduleWithRunLoop(stream, pair->runLoop, pair->mode);
+}
+
+static void advanceCurrentStream(FormStreamFields *form)
+{
+ closeCurrentStream(form);
+
+ if (form->remainingElements.isEmpty())
+ return;
+
+ // Create the new stream.
+ FormDataElement& nextInput = form->remainingElements.last();
+ if (nextInput.m_type == FormDataElement::data) {
+ size_t size = nextInput.m_data.size();
+ char* data = nextInput.m_data.releaseBuffer();
+ form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data), size, kCFAllocatorNull);
+ form->currentData = data;
+ } else {
+ CFStringRef filename = nextInput.m_filename.createCFString();
+ CFURLRef fileURL = CFURLCreateWithFileSystemPath(0, filename, kCFURLPOSIXPathStyle, FALSE);
+ CFRelease(filename);
+ form->currentStream = CFReadStreamCreateWithFile(0, fileURL);
+ CFRelease(fileURL);
+ }
+ form->remainingElements.removeLast();
+
+ // Set up the callback.
+ CFStreamClientContext context = { 0, form, NULL, NULL, NULL };
+ CFReadStreamSetClient(form->currentStream, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
+ formEventCallback, &context);
+
+ // Schedule with the current set of run loops.
+ CFSetApplyFunction(form->scheduledRunLoopPairs, scheduleWithPair, form->currentStream);
+}
+
+static void openNextStream(FormStreamFields* form)
+{
+ // Skip over any streams we can't open.
+ // For some purposes we might want to return an error, but the current CFURLConnection
+ // can't really do anything useful with an error at this point, so this is better.
+ advanceCurrentStream(form);
+ while (form->currentStream && !CFReadStreamOpen(form->currentStream))
+ advanceCurrentStream(form);
+}
+
+static void* formCreate(CFReadStreamRef stream, void* context)
+{
+ const FormData* formData = static_cast<const FormData*>(context);
+
+ CFSetCallBacks runLoopAndModeCallBacks = { 0, pairRetain, pairRelease, NULL, pairEqual, pairHash };
+
+ FormStreamFields* newInfo = new FormStreamFields;
+ newInfo->scheduledRunLoopPairs = CFSetCreateMutable(0, 0, &runLoopAndModeCallBacks);
+ newInfo->currentStream = NULL;
+ newInfo->currentData = 0;
+ newInfo->formStream = stream; // Don't retain. That would create a reference cycle.
+
+ // Append in reverse order since we remove elements from the end.
+ size_t size = formData->elements().size();
+ newInfo->remainingElements.reserveCapacity(size);
+ for (size_t i = 0; i < size; ++i)
+ newInfo->remainingElements.append(formData->elements()[size - i - 1]);
+
+ getStreamFormDatas()->set(stream, new FormData(*formData));
+
+ return newInfo;
+}
+
+static void formFinalize(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ delete getStreamFormDatas()->get(stream);
+ getStreamFormDatas()->remove(stream);
+
+ closeCurrentStream(form);
+ CFRelease(form->scheduledRunLoopPairs);
+ delete form;
+}
+
+static Boolean formOpen(CFReadStreamRef stream, CFStreamError* error, Boolean* openComplete, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ openNextStream(form);
+
+ *openComplete = TRUE;
+ error->error = 0;
+ return TRUE;
+}
+
+static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLength, CFStreamError* error, Boolean* atEOF, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ while (form->currentStream) {
+ CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bufferLength);
+ if (bytesRead < 0) {
+ *error = CFReadStreamGetError(form->currentStream);
+ return -1;
+ }
+ if (bytesRead > 0) {
+ error->error = 0;
+ *atEOF = FALSE;
+ return bytesRead;
+ }
+ openNextStream(form);
+ }
+
+ error->error = 0;
+ *atEOF = TRUE;
+ return 0;
+}
+
+static Boolean formCanRead(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ while (form->currentStream && CFReadStreamGetStatus(form->currentStream) == kCFStreamStatusAtEnd) {
+ openNextStream(form);
+ }
+ if (!form->currentStream) {
+ CFReadStreamSignalEvent(stream, kCFStreamEventEndEncountered, 0);
+ return FALSE;
+ }
+ return CFReadStreamHasBytesAvailable(form->currentStream);
+}
+
+static void formClose(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ closeCurrentStream(form);
+}
+
+static void formSchedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ if (form->currentStream)
+ CFReadStreamScheduleWithRunLoop(form->currentStream, runLoop, runLoopMode);
+ SchedulePair pair = { runLoop, runLoopMode };
+ CFSetAddValue(form->scheduledRunLoopPairs, &pair);
+}
+
+static void formUnschedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ if (form->currentStream)
+ CFReadStreamUnscheduleFromRunLoop(form->currentStream, runLoop, runLoopMode);
+ SchedulePair pair = { runLoop, runLoopMode };
+ CFSetRemoveValue(form->scheduledRunLoopPairs, &pair);
+}
+
+static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ switch (type) {
+ case kCFStreamEventHasBytesAvailable:
+ CFReadStreamSignalEvent(form->formStream, kCFStreamEventHasBytesAvailable, 0);
+ break;
+ case kCFStreamEventErrorOccurred: {
+ CFStreamError readStreamError = CFReadStreamGetError(stream);
+ CFReadStreamSignalEvent(form->formStream, kCFStreamEventErrorOccurred, &readStreamError);
+ break;
+ }
+ case kCFStreamEventEndEncountered:
+ openNextStream(form);
+ if (!form->currentStream)
+ CFReadStreamSignalEvent(form->formStream, kCFStreamEventEndEncountered, 0);
+ break;
+ case kCFStreamEventNone:
+ LOG_ERROR("unexpected kCFStreamEventNone");
+ break;
+ case kCFStreamEventOpenCompleted:
+ LOG_ERROR("unexpected kCFStreamEventOpenCompleted");
+ break;
+ case kCFStreamEventCanAcceptBytes:
+ LOG_ERROR("unexpected kCFStreamEventCanAcceptBytes");
+ break;
+ }
+}
+
+void setHTTPBody(CFMutableURLRequestRef request, const FormData& formData)
+{
+ size_t count = formData.elements().size();
+
+ if (!count == 0)
+ return;
+
+ // Handle the common special case of one piece of form data, with no files.
+ if (count == 1) {
+ const FormDataElement& element = formData.elements()[0];
+ if (element.m_type == FormDataElement::data) {
+ CFDataRef data = CFDataCreate(0, reinterpret_cast<const UInt8 *>(element.m_data.data()), element.m_data.size());
+ CFURLRequestSetHTTPRequestBody(request, data);
+ CFRelease(data);
+ return;
+ }
+ }
+
+ // Precompute the content length so CFURLConnection doesn't use chunked mode.
+ bool haveLength = true;
+ long long length = 0;
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData.elements()[i];
+ if (element.m_type == FormDataElement::data)
+ length += element.m_data.size();
+ else {
+ struct _stat64i32 sb;
+ int statResult = _stat(element.m_filename.utf8(), &sb);
+ if (statResult == 0 && (sb.st_mode & S_IFMT) == S_IFREG)
+ length += sb.st_size;
+ else
+ haveLength = false;
+ }
+ }
+
+ if (haveLength) {
+ CFStringRef lengthStr = CFStringCreateWithFormat(0, 0, CFSTR("%lld"), length);
+ CFURLRequestSetHTTPHeaderFieldValue(request, CFSTR("Content-Length"), lengthStr);
+ CFRelease(lengthStr);
+ }
+
+ static CFReadStreamCallBacks formDataStreamCallbacks =
+ { 1, formCreate, formFinalize, 0, formOpen, 0, formRead, 0, formCanRead, formClose, 0, 0, 0, formSchedule, formUnschedule};
+
+ CFReadStreamRef stream = CFReadStreamCreate(0, &formDataStreamCallbacks, const_cast<FormData*>(&formData));
+ CFURLRequestSetHTTPRequestBodyStream(request, stream);
+ CFRelease(stream);
+}
+
+
+const FormData* httpBodyFromStream(CFReadStreamRef stream)
+{
+ return getStreamFormDatas()->get(stream);
+}
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2005, 2006 Apple Computer, 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 FormDataStreamCFNet_h_
+#define FormDataStreamCFNet_h_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+typedef struct _CFURLRequest* CFMutableURLRequestRef;
+
+namespace WebCore {
+ class FormData;
+ void setHTTPBody(CFMutableURLRequestRef, const FormData&);
+ const FormData* httpBodyFromStream(CFReadStreamRef);
+}
+
+#endif FormDataStreamCFNet_h_
#include "Frame.h"
#include "ResourceHandle.h"
#include "ResourceHandleInternal.h"
+#include "ResourceRequestCFNet.h"
#include "ResourceResponse.h"
#include "ResourceResponseCFNet.h"
namespace WebCore {
-CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef request, CFURLResponseRef redirectionResponse, const void* clientInfo)
+CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfRequest, CFURLResponseRef cfRedirectResponse, const void* clientInfo)
{
- ResourceHandle* job = (ResourceHandle*)clientInfo;
- CFURLRef url = CFURLRequestGetURL(request);
- CFStringRef urlString = CFURLGetString(url);
- const char *bytes = CFStringGetCStringPtr(urlString, kCFStringEncodingUTF8);
- bool freeBytes = false;
-
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
#if defined(LOG_RESOURCELOADER_EVENTS)
- CFStringRef str = CFStringCreateWithFormat(0, 0, CFSTR("willSendRequest(conn=%p, job = %p)\n"), conn, job);
+ CFStringRef str = CFStringCreateWithFormat(0, 0, CFSTR("willSendRequest(conn=%p, job = %p)\n"), conn, handle);
CFShow(str);
CFRelease(str);
#endif
- if (!bytes) {
- CFIndex numBytes, urlLength = CFStringGetLength(urlString);
- UInt8* newBytes;
- CFStringGetBytes(urlString, CFRangeMake(0, urlLength), kCFStringEncodingUTF8, 0, FALSE, 0, 0, &numBytes);
- newBytes = (UInt8*)malloc(numBytes + 1);
- CFStringGetBytes(urlString, CFRangeMake(0, urlLength), kCFStringEncodingUTF8, 0, FALSE, newBytes, numBytes, &numBytes);
- newBytes[numBytes] = 0;
- freeBytes = true;
- bytes = (char*)newBytes;
+ if (ResourceHandleClient* c = handle->client()) {
+ ResourceRequest request;
+ getResourceRequest(request, cfRequest);
+ ResourceResponse redirectResponse;
+ getResourceResponse(redirectResponse, cfRedirectResponse);
+ return cfURLRequest(request);
}
- ASSERT(bytes);
- KURL newURL(bytes);
- if (freeBytes)
- free((void*)bytes);
- return request;
+
+ return cfRequest;
}
void didReceiveResponse(CFURLConnectionRef conn, CFURLResponseRef cfResponse, const void* clientInfo)
bool ResourceHandle::start(DocLoader* docLoader)
{
- CFURLRef url = d->m_request.url().createCFURL();
+ d->m_request.setHTTPUserAgent(docLoader->frame()->userAgent());
+ String referrer = docLoader->frame()->referrer();
+ if (!referrer.isEmpty() && referrer.find("file:", 0, false) != 0)
+ d->m_request.setHTTPReferrer(referrer);
- CFStringRef requestMethod = d->m_request.httpMethod().createCFString();
- CFMutableURLRequestRef request = CFURLRequestCreateMutable(0, url, kCFURLRequestCachePolicyProtocolDefault, 30.0, 0);
- Boolean isPost = CFStringCompare(requestMethod, CFSTR("POST"), kCFCompareCaseInsensitive);
- CFRelease(requestMethod);
-
- CFStringRef userAgentString = docLoader->frame()->userAgent().createCFString();
- CFURLRequestSetHTTPHeaderFieldValue(request, CFSTR("User-Agent"), userAgentString);
- CFRelease(userAgentString);
+ CFURLRequestRef request = cfURLRequest(d->m_request);
ref();
d->m_loading = true;
- addHeadersFromHashMap(request, d->m_request.httpHeaderFields());
-
- String referrer = docLoader->frame()->referrer();
- if (!referrer.isEmpty() && referrer.find("file:", 0, false) != 0) {
- CFStringRef str = referrer.createCFString();
- CFURLRequestSetHTTPHeaderFieldValue(request, CFSTR("Referer"),str);
- CFRelease(str);
- }
- CFReadStreamRef bodyStream = 0;
- if (postData().elements().size() > 0) {
- CFArrayRef formArray = arrayFromFormData(postData());
- bool done = false;
- CFIndex count = CFArrayGetCount(formArray);
-
- if (count == 1) {
- // Handle the common special case of one piece of form data, with no files.
- CFTypeRef d = CFArrayGetValueAtIndex(formArray, 0);
- if (CFGetTypeID(d) == CFDataGetTypeID()) {
- CFURLRequestSetHTTPRequestBody(request, (CFDataRef)d);
- done = true;
- }
- }
-
- if (!done) {
- // Precompute the content length so NSURLConnection doesn't use chunked mode.
- long long length = 0;
- unsigned i;
- bool success = true;
- for (i = 0; success && i < count; ++i) {
- CFTypeRef data = CFArrayGetValueAtIndex(formArray, i);
- CFIndex typeID = CFGetTypeID(data);
- if (typeID == CFDataGetTypeID()) {
- CFDataRef d = (CFDataRef)data;
- length += CFDataGetLength(d);
- } else {
- // data is a CFStringRef
- CFStringRef s = (CFStringRef)data;
- CFIndex bufLen = CFStringGetMaximumSizeOfFileSystemRepresentation(s);
- char* buf = (char*)malloc(bufLen);
- if (CFStringGetFileSystemRepresentation(s, buf, bufLen)) {
- struct _stat64i32 sb;
- int statResult = _stat(buf, &sb);
- if (statResult == 0 && (sb.st_mode & S_IFMT) == S_IFREG)
- length += sb.st_size;
- else
- success = false;
- } else {
- success = false;
- }
- free(buf);
- }
- }
- if (success) {
- CFStringRef lengthStr = CFStringCreateWithFormat(0, 0, CFSTR("%lld"), length);
- CFURLRequestSetHTTPHeaderFieldValue(request, CFSTR("Content-Length"), lengthStr);
- CFRelease(lengthStr);
- }
- bodyStream = CFReadStreamCreateWithFormArray(0, formArray);
- }
- CFRelease(formArray);
- }
-
- if (bodyStream)
- CFURLRequestSetHTTPRequestBodyStream(request, bodyStream);
CFURLConnectionClient client = {0, this, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge};
d->m_connection = CFURLConnectionCreate(0, request, &client);
CFRelease(request);
if (!loaderRL) {
_beginthread(runLoaderThread, 0, 0);
while (loaderRL == 0) {
+ // FIXME: sleep 10? that can't be right...
Sleep(10);
}
}
CFURLConnectionStart(d->m_connection);
#if defined(LOG_RESOURCELOADER_EVENTS)
+ CFURLRef url = d->m_request.url().createCFURL();
CFStringRef outStr = CFStringCreateWithFormat(0, 0, CFSTR("Starting URL %@ (job = %p, connection = %p)\n"), CFURLGetString(url), this, d->m_connection);
CFShow(outStr);
CFRelease(outStr);
-#endif
CFRelease(url);
+#endif
return true;
}
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "ResourceRequestCFNet.h"
+
+#include "FormDataStreamCFNet.h"
+#include "ResourceRequest.h"
+
+#include <CFNetwork/CFURLRequestPriv.h>
+
+namespace WebCore {
+
+ void getResourceRequest(ResourceRequest& request, CFURLRequestRef cfRequest)
+ {
+ request = ResourceRequest(CFURLRequestGetURL(cfRequest));
+
+ request.setCachePolicy((ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(cfRequest));
+ request.setTimeoutInterval(CFURLRequestGetTimeoutInterval(cfRequest));
+ request.setMainDocumentURL(KURL(CFURLRequestGetMainDocumentURL(cfRequest)));
+ if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(cfRequest)) {
+ request.setHTTPMethod(method);
+ CFRelease(method);
+ }
+ request.setAllowHTTPCookies(CFURLRequestShouldHandleHTTPCookies(cfRequest));
+
+ if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(cfRequest)) {
+ CFIndex headerCount = CFDictionaryGetCount(headers);
+ Vector<const void*, 128> keys(headerCount);
+ Vector<const void*, 128> values(headerCount);
+ CFDictionaryGetKeysAndValues(headers, keys.data(), values.data());
+ for (int i = 0; i < headerCount; ++i)
+ request.setHTTPHeaderField((CFStringRef)keys[i], (CFStringRef)values[i]);
+ CFRelease(headers);
+ }
+
+
+ if (CFDataRef bodyData = CFURLRequestCopyHTTPRequestBody(cfRequest)) {
+ request.setHTTPBody(FormData(CFDataGetBytePtr(bodyData), CFDataGetLength(bodyData)));
+ CFRelease(bodyData);
+ } else if (CFReadStreamRef bodyStream = CFURLRequestCopyHTTPRequestBodyStream(cfRequest)) {
+ if (const FormData* formData = httpBodyFromStream(bodyStream))
+ request.setHTTPBody(*formData);
+ CFRelease(bodyStream);
+ }
+ // FIXME: what to do about arbitrary body streams?
+ }
+
+ static void addHeadersFromHashMap(CFMutableURLRequestRef request, const HTTPHeaderMap& requestHeaders)
+ {
+ if (!requestHeaders.size())
+ return;
+
+ HTTPHeaderMap::const_iterator end = requestHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
+ CFStringRef key = it->first.createCFString();
+ CFStringRef value = it->second.createCFString();
+ CFURLRequestSetHTTPHeaderFieldValue(request, key, value);
+ CFRelease(key);
+ CFRelease(value);
+ }
+ }
+
+ CFURLRequestRef cfURLRequest(const ResourceRequest& request)
+ {
+ CFURLRef url = request.url().createCFURL();
+ CFURLRef mainDocumentURL = request.mainDocumentURL().createCFURL();
+
+ CFMutableURLRequestRef cfRequest = CFURLRequestCreateMutable(0, url, (CFURLRequestCachePolicy)request.cachePolicy(), request.timeoutInterval(), mainDocumentURL);
+
+ CFRelease(url);
+ CFRelease(mainDocumentURL);
+
+ CFStringRef requestMethod = request.httpMethod().createCFString();
+ CFURLRequestSetHTTPRequestMethod(cfRequest, requestMethod);
+ CFRelease(requestMethod);
+
+ addHeadersFromHashMap(cfRequest, request.httpHeaderFields());
+ setHTTPBody(cfRequest, request.httpBody());
+ CFURLRequestSetShouldHandleHTTPCookies(cfRequest, request.allowHTTPCookies());
+
+ return cfRequest;
+ }
+
+}
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 ResourceRequestCFNet_h_
+#define ResourceRequestCFNet_h_
+
+typedef const struct _CFURLRequest* CFURLRequestRef;
+
+namespace WebCore {
+
+ class ResourceRequest;
+
+ void getResourceRequest(ResourceRequest&, CFURLRequestRef);
+ CFURLRequestRef cfURLRequest(const ResourceRequest&);
+}
+
+#endif // ResourceRequestCFNet_h_
void getResourceResponse(ResourceResponse& response, CFURLResponseRef cfResponse)
{
+ if (!cfResponse)
+ return;
+
// FIXME: we may need to do MIME type sniffing here (unless that is done
// in CFURLResponseGetMIMEType
/*
- * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#import "KURL.h"
#import "LoaderFunctions.h"
#import "Logging.h"
+#import "ResourceRequestMac.h"
#import "ResourceResponse.h"
#import "ResourceResponseMac.h"
#import "WebCoreFrameBridge.h"
d->m_subresourceLoader->cancel();
}
-void ResourceHandle::redirectedToURL(NSURL *url)
+NSURLRequest *ResourceHandle::willSendRequest(NSURLRequest *nsRequest, NSURLResponse* nsRedirectResponse)
{
- ASSERT(url);
- if (ResourceHandleClient* c = client())
- c->receivedRedirect(this, KURL(url));
+ ASSERT(nsRequest);
+ if (ResourceHandleClient* c = client()) {
+ ResourceRequest request;
+ getResourceRequest(request, nsRequest);
+ ResourceResponse redirectResponse;
+ getResourceResponse(redirectResponse, nsRedirectResponse);
+ c->willSendRequest(this, request, redirectResponse);
+ return nsURLRequest(request);
+ }
+
+ return nsRequest;
}
void ResourceHandle::addData(NSData *data)
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 ResourceRequestMac_h_
+#define ResourceRequestMac_h_
+
+@class NSURLRequest;
+
+namespace WebCore {
+
+ class ResourceRequest;
+
+ void getResourceRequest(ResourceRequest&, NSURLRequest *);
+ NSURLRequest *nsURLRequest(const ResourceRequest&);
+
+}
+
+#endif // ResourceRequestMac_h_
--- /dev/null
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2006 Apple Computer, 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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.
+ */
+
+#import "config.h"
+#import "ResourceRequestMac.h"
+
+#import "FormDataStream.h"
+#import "ResourceRequest.h"
+
+#import <Foundation/Foundation.h>
+
+namespace WebCore {
+
+ void getResourceRequest(ResourceRequest& request, NSURLRequest* nsRequest)
+ {
+ request = ResourceRequest([nsRequest URL]);
+
+ request.setCachePolicy((ResourceRequestCachePolicy)[nsRequest cachePolicy]);
+ request.setTimeoutInterval([nsRequest timeoutInterval]);
+ request.setMainDocumentURL(KURL([nsRequest mainDocumentURL]));
+ if (NSString* method = [nsRequest HTTPMethod])
+ request.setHTTPMethod(method);
+ request.setAllowHTTPCookies([nsRequest HTTPShouldHandleCookies]);
+
+ NSDictionary *headers = [nsRequest allHTTPHeaderFields];
+ NSEnumerator *e = [headers keyEnumerator];
+ NSString *name;
+ while ((name = [e nextObject]))
+ request.setHTTPHeaderField(name, [headers objectForKey:name]);
+
+ if (NSData* bodyData = [nsRequest HTTPBody])
+ request.setHTTPBody(FormData([bodyData bytes], [bodyData length]));
+ else if (NSInputStream* bodyStream = [nsRequest HTTPBodyStream])
+ if (const FormData* formData = httpBodyFromStream(bodyStream))
+ request.setHTTPBody(*formData);
+ // FIXME: what to do about arbitrary body streams?
+ }
+
+ NSURLRequest* nsURLRequest(const ResourceRequest& request)
+ {
+ NSMutableURLRequest* nsRequest = [[NSMutableURLRequest alloc] initWithURL:request.url().getNSURL()];
+
+ [nsRequest setCachePolicy:(NSURLRequestCachePolicy)request.cachePolicy()];
+ [nsRequest setTimeoutInterval:request.timeoutInterval()];
+ [nsRequest setMainDocumentURL:request.mainDocumentURL().getNSURL()];
+ if (!request.httpMethod().isEmpty())
+ [nsRequest setHTTPMethod:request.httpMethod()];
+ [nsRequest setHTTPShouldHandleCookies:request.allowHTTPCookies()];
+
+ HTTPHeaderMap::const_iterator end = request.httpHeaderFields().end();
+ for (HTTPHeaderMap::const_iterator it = request.httpHeaderFields().begin(); it != end; ++it)
+ [nsRequest setValue:it->second forHTTPHeaderField:it->first];
+
+ if (!request.httpBody().isEmpty())
+ setHTTPBody(nsRequest, request.httpBody());
+
+ return [nsRequest autorelease];
+ }
+
+}
}
}
-void XMLHttpRequest::receivedRedirect(ResourceHandle*, const KURL& m_url)
+void XMLHttpRequest::willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
- if (!urlMatchesDocumentDomain(m_url))
+ if (!urlMatchesDocumentDomain(request.url()))
abort();
}
private:
bool urlMatchesDocumentDomain(const KURL&) const;
- virtual void receivedRedirect(ResourceHandle*, const KURL&);
+ virtual void willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse);
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
virtual void didReceiveData(ResourceHandle*, const char* data, int size);
virtual void didFinishLoading(ResourceHandle*);