diff options
author | Ben Murdoch <benm@google.com> | 2011-05-24 11:24:40 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-06-02 09:53:15 +0100 |
commit | 81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch) | |
tree | 7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/platform/network | |
parent | 94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff) | |
download | external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2 |
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/platform/network')
41 files changed, 768 insertions, 978 deletions
diff --git a/Source/WebCore/platform/network/CookieStorage.h b/Source/WebCore/platform/network/CookieStorage.h index 56ca5dc..67bb4d5 100644 --- a/Source/WebCore/platform/network/CookieStorage.h +++ b/Source/WebCore/platform/network/CookieStorage.h @@ -26,9 +26,20 @@ #ifndef CookieStorage_h #define CookieStorage_h +#include <wtf/RetainPtr.h> + +typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef; + namespace WebCore { + +#if USE(CFURLSTORAGESESSIONS) && PLATFORM(MAC) +RetainPtr<CFHTTPCookieStorageRef>& privateBrowsingCookieStorage(); +#endif + void setCookieStoragePrivateBrowsingEnabled(bool); +void startObservingCookieChanges(); +void stopObservingCookieChanges(); } diff --git a/Source/WebCore/platform/network/NetworkStateNotifier.cpp b/Source/WebCore/platform/network/NetworkStateNotifier.cpp index 7638478..d0e00f1 100644 --- a/Source/WebCore/platform/network/NetworkStateNotifier.cpp +++ b/Source/WebCore/platform/network/NetworkStateNotifier.cpp @@ -20,7 +20,7 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -35,15 +35,28 @@ namespace WebCore { NetworkStateNotifier& networkStateNotifier() { AtomicallyInitializedStatic(NetworkStateNotifier*, networkStateNotifier = new NetworkStateNotifier); - + return *networkStateNotifier; } void NetworkStateNotifier::setNetworkStateChangedFunction(void(*function)()) { ASSERT(!m_networkStateChangedFunction); - + m_networkStateChangedFunction = function; } - + +#if PLATFORM(ANDROID) || PLATFORM(CHROMIUM) +void NetworkStateNotifier::setOnLine(bool onLine) +{ + if (m_isOnLine == onLine) + return; + + m_isOnLine = onLine; + + if (m_networkStateChangedFunction) + m_networkStateChangedFunction(); +} +#endif // PLATFORM(ANDROID) || PLATFORM(CHROMIM) + } diff --git a/Source/WebCore/platform/network/NetworkStateNotifier.h b/Source/WebCore/platform/network/NetworkStateNotifier.h index 08ab0bd..116bbb4 100644 --- a/Source/WebCore/platform/network/NetworkStateNotifier.h +++ b/Source/WebCore/platform/network/NetworkStateNotifier.h @@ -41,10 +41,6 @@ typedef const struct __CFArray * CFArrayRef; typedef const struct __SCDynamicStore * SCDynamicStoreRef; -#elif PLATFORM(CHROMIUM) - -#include "NetworkStateNotifierPrivate.h" - #elif PLATFORM(WIN) #include <windows.h> @@ -71,19 +67,29 @@ class NetworkStateNotifier { public: NetworkStateNotifier(); void setNetworkStateChangedFunction(void (*)()); - + bool onLine() const { return m_isOnLine; } #if (PLATFORM(QT) && ENABLE(QT_BEARER)) void setNetworkAccessAllowed(bool); +#elif PLATFORM(ANDROID) || PLATFORM(CHROMIUM) + void setOnLine(bool); #endif #if PLATFORM(ANDROID) + void networkStateChange(bool online) { setOnLine(online); } +#endif + +<<<<<<< HEAD +#if PLATFORM(ANDROID) // TODO: Upstream to webkit.org Connection::ConnectionType type() const { return m_type; } #endif private: +======= +private: +>>>>>>> WebKit at r80534 bool m_isOnLine; #if PLATFORM(ANDROID) // TODO: Upstream to webkit.org @@ -105,11 +111,12 @@ private: static void CALLBACK addrChangeCallback(void*, BOOLEAN timedOut); static void callAddressChanged(void*); void addressChanged(); - + void registerForAddressChange(); HANDLE m_waitHandle; OVERLAPPED m_overlapped; +<<<<<<< HEAD #elif PLATFORM(CHROMIUM) NetworkStateNotifierPrivate p; @@ -119,13 +126,15 @@ public: // TODO: Upstream to webkit.org void networkTypeChange(Connection::ConnectionType type); +======= +>>>>>>> WebKit at r80534 #elif PLATFORM(QT) && ENABLE(QT_BEARER) friend class NetworkStateNotifierPrivate; NetworkStateNotifierPrivate* p; #endif }; -#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM) && !(PLATFORM(QT) && ENABLE(QT_BEARER)) +#if !PLATFORM(MAC) && !PLATFORM(WIN) && !(PLATFORM(QT) && ENABLE(QT_BEARER)) inline NetworkStateNotifier::NetworkStateNotifier() : m_isOnLine(true) @@ -134,7 +143,7 @@ inline NetworkStateNotifier::NetworkStateNotifier() , m_type(Connection::UNKNOWN) #endif , m_networkStateChangedFunction(0) -{ +{ } inline void NetworkStateNotifier::updateState() { } @@ -142,7 +151,7 @@ inline void NetworkStateNotifier::updateState() { } #endif NetworkStateNotifier& networkStateNotifier(); - + }; #endif // NetworkStateNotifier_h diff --git a/Source/WebCore/platform/network/ResourceHandle.cpp b/Source/WebCore/platform/network/ResourceHandle.cpp index 9910ac1..d901984 100644 --- a/Source/WebCore/platform/network/ResourceHandle.cpp +++ b/Source/WebCore/platform/network/ResourceHandle.cpp @@ -33,6 +33,7 @@ #include "ResourceHandleClient.h" #include "Timer.h" #include <algorithm> +#include <wtf/text/CString.h> namespace WebCore { @@ -185,4 +186,46 @@ void ResourceHandle::cacheMetadata(const ResourceResponse&, const Vector<char>&) // Optionally implemented by platform. } +#if USE(CFURLSTORAGESESSIONS) + +static RetainPtr<CFURLStorageSessionRef>& privateStorageSession() +{ + DEFINE_STATIC_LOCAL(RetainPtr<CFURLStorageSessionRef>, storageSession, ()); + return storageSession; +} + +static String& privateBrowsingStorageSessionIdentifierBase() +{ + DEFINE_STATIC_LOCAL(String, base, ()); + return base; +} + +void ResourceHandle::setPrivateBrowsingEnabled(bool enabled) +{ + if (!enabled) { + privateStorageSession() = nullptr; + return; + } + + if (privateStorageSession()) + return; + + String base = privateBrowsingStorageSessionIdentifierBase().isNull() ? privateBrowsingStorageSessionIdentifierDefaultBase() : privateBrowsingStorageSessionIdentifierBase(); + RetainPtr<CFStringRef> cfIdentifier(AdoptCF, String::format("%s.PrivateBrowsing", base.utf8().data()).createCFString()); + + privateStorageSession() = createPrivateBrowsingStorageSession(cfIdentifier.get()); +} + +CFURLStorageSessionRef ResourceHandle::privateBrowsingStorageSession() +{ + return privateStorageSession().get(); +} + +void ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(const String& identifier) +{ + privateBrowsingStorageSessionIdentifierBase() = identifier; +} + +#endif // USE(CFURLSTORAGESESSIONS) + } // namespace WebCore diff --git a/Source/WebCore/platform/network/ResourceHandle.h b/Source/WebCore/platform/network/ResourceHandle.h index c2a0b8e..f21f963 100644 --- a/Source/WebCore/platform/network/ResourceHandle.h +++ b/Source/WebCore/platform/network/ResourceHandle.h @@ -37,7 +37,7 @@ typedef struct _SoupSession SoupSession; #endif -#if PLATFORM(CF) +#if USE(CF) typedef const struct __CFData * CFDataRef; #endif @@ -71,6 +71,10 @@ typedef int CFHTTPCookieStorageAcceptPolicy; typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef; #endif +#if USE(CFURLSTORAGESESSIONS) +typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; +#endif + namespace WebCore { class AuthenticationChallenge; @@ -140,7 +144,7 @@ public: #if PLATFORM(WIN) && USE(CURL) static void setHostAllowsAnyHTTPSCertificate(const String&); #endif -#if PLATFORM(WIN) && USE(CURL) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CURL) && USE(CF) static void setClientCertificate(const String& host, CFDataRef); #endif @@ -190,6 +194,12 @@ public: void fireFailure(Timer<ResourceHandle>*); +#if USE(CFURLSTORAGESESSIONS) + static void setPrivateBrowsingEnabled(bool); + static CFURLStorageSessionRef privateBrowsingStorageSession(); + static void setPrivateBrowsingStorageSessionIdentifierBase(const String&); +#endif + using RefCounted<ResourceHandle>::ref; using RefCounted<ResourceHandle>::deref; @@ -214,10 +224,15 @@ private: #if PLATFORM(MAC) void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff); -#elif PLATFORM(CF) +#elif USE(CF) void createCFURLConnection(bool shouldUseCredentialStorage, bool shouldContentSniff); #endif +#if USE(CFURLSTORAGESESSIONS) + static RetainPtr<CFURLStorageSessionRef> createPrivateBrowsingStorageSession(CFStringRef identifier); + static String privateBrowsingStorageSessionIdentifierDefaultBase(); +#endif + friend class ResourceHandleInternal; OwnPtr<ResourceHandleInternal> d; }; diff --git a/Source/WebCore/platform/network/ResourceHandleInternal.h b/Source/WebCore/platform/network/ResourceHandleInternal.h index 5512062..b622801 100644 --- a/Source/WebCore/platform/network/ResourceHandleInternal.h +++ b/Source/WebCore/platform/network/ResourceHandleInternal.h @@ -114,7 +114,6 @@ namespace WebCore { #if USE(SOUP) , m_cancelled(false) , m_buffer(0) - , m_total(0) , m_bodySize(0) , m_bodyDataSent(0) , m_idleHandler(0) @@ -194,7 +193,6 @@ namespace WebCore { GRefPtr<GInputStream> m_inputStream; GRefPtr<GCancellable> m_cancellable; char* m_buffer; - gsize m_total; unsigned long m_bodySize; unsigned long m_bodyDataSent; guint m_idleHandler; diff --git a/Source/WebCore/platform/network/ResourceRequestBase.cpp b/Source/WebCore/platform/network/ResourceRequestBase.cpp index ba58461..6a554fe 100644 --- a/Source/WebCore/platform/network/ResourceRequestBase.cpp +++ b/Source/WebCore/platform/network/ResourceRequestBase.cpp @@ -32,6 +32,13 @@ using namespace std; namespace WebCore { +#if !PLATFORM(MAC) || USE(CFNETWORK) +double ResourceRequestBase::s_defaultTimeoutInterval = INT_MAX; +#else +// Will use NSURLRequest default timeout unless set to a non-zero value with setDefaultTimeoutInterval(). +double ResourceRequestBase::s_defaultTimeoutInterval = 0; +#endif + inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const { return *static_cast<const ResourceRequest*>(this); @@ -408,11 +415,22 @@ bool ResourceRequestBase::isConditional() const m_httpHeaderFields.contains("If-Unmodified-Since")); } +double ResourceRequestBase::defaultTimeoutInterval() +{ + return s_defaultTimeoutInterval; +} + +void ResourceRequestBase::setDefaultTimeoutInterval(double timeoutInterval) +{ + s_defaultTimeoutInterval = timeoutInterval; +} + void ResourceRequestBase::updatePlatformRequest() const { if (m_platformRequestUpdated) return; - + + ASSERT(m_resourceRequestUpdated); const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest(); m_platformRequestUpdated = true; } @@ -422,6 +440,7 @@ void ResourceRequestBase::updateResourceRequest() const if (m_resourceRequestUpdated) return; + ASSERT(m_platformRequestUpdated); const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest(); m_resourceRequestUpdated = true; } diff --git a/Source/WebCore/platform/network/ResourceRequestBase.h b/Source/WebCore/platform/network/ResourceRequestBase.h index 9cc9148..ec7e32a 100644 --- a/Source/WebCore/platform/network/ResourceRequestBase.h +++ b/Source/WebCore/platform/network/ResourceRequestBase.h @@ -44,8 +44,6 @@ namespace WebCore { ReturnCacheDataDontLoad, // results of a post - allow stale data and only use cache }; - const int unspecifiedTimeoutInterval = INT_MAX; - class ResourceRequest; struct CrossThreadResourceRequestData; @@ -85,7 +83,7 @@ namespace WebCore { ResourceRequestCachePolicy cachePolicy() const; void setCachePolicy(ResourceRequestCachePolicy cachePolicy); - double timeoutInterval() const; + double timeoutInterval() const; // May return 0 when using platform default. void setTimeoutInterval(double timeoutInterval); const KURL& firstPartyForCookies() const; @@ -148,9 +146,13 @@ namespace WebCore { void setReportRawHeaders(bool reportRawHeaders) { m_reportRawHeaders = reportRawHeaders; } // What this request is for. + // FIXME: This should be moved out of ResourceRequestBase, <https://bugs.webkit.org/show_bug.cgi?id=48483>. TargetType targetType() const { return m_targetType; } void setTargetType(TargetType type) { m_targetType = type; } + static double defaultTimeoutInterval(); // May return 0 when using platform default. + static void setDefaultTimeoutInterval(double); + static bool compare(const ResourceRequest&, const ResourceRequest&); protected: @@ -169,7 +171,7 @@ namespace WebCore { ResourceRequestBase(const KURL& url, ResourceRequestCachePolicy policy) : m_url(url) , m_cachePolicy(policy) - , m_timeoutInterval(unspecifiedTimeoutInterval) + , m_timeoutInterval(s_defaultTimeoutInterval) , m_httpMethod("GET") , m_allowCookies(true) , m_resourceRequestUpdated(true) @@ -191,7 +193,7 @@ namespace WebCore { KURL m_url; ResourceRequestCachePolicy m_cachePolicy; - double m_timeoutInterval; + double m_timeoutInterval; // 0 is a magic value for platform default on platforms that have one. KURL m_firstPartyForCookies; String m_httpMethod; HTTPHeaderMap m_httpHeaderFields; @@ -208,6 +210,8 @@ namespace WebCore { private: const ResourceRequest& asResourceRequest() const; + + static double s_defaultTimeoutInterval; }; bool equalIgnoringHeaderFields(const ResourceRequestBase&, const ResourceRequestBase&); @@ -236,7 +240,7 @@ namespace WebCore { unsigned initializeMaximumHTTPConnectionCountPerHost(); -#if PLATFORM(CF) +#if USE(CF) bool isHTTPPipeliningEnabled(); bool shouldForceHTTPPipeliningPriorityHigh(); #else diff --git a/Source/WebCore/platform/network/android/CookieJarAndroid.cpp b/Source/WebCore/platform/network/android/CookieJarAndroid.cpp index f3b343e..d0a4217 100644 --- a/Source/WebCore/platform/network/android/CookieJarAndroid.cpp +++ b/Source/WebCore/platform/network/android/CookieJarAndroid.cpp @@ -52,4 +52,19 @@ bool cookiesEnabled(const Document* document) return PlatformBridge::cookiesEnabled(document); } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/network/cf/AuthenticationCF.cpp b/Source/WebCore/platform/network/cf/AuthenticationCF.cpp index 5168a48..3932a2b 100644 --- a/Source/WebCore/platform/network/cf/AuthenticationCF.cpp +++ b/Source/WebCore/platform/network/cf/AuthenticationCF.cpp @@ -33,6 +33,10 @@ #include "Credential.h" #include "ProtectionSpace.h" +// This header must come before all other CFNetwork headers to work around a CFNetwork bug. It can +// be removed entirely once <rdar://problem/9042114> is fixed. +#include <CFNetwork/CFURLConnectionPriv.h> + #include <CFNetwork/CFURLAuthChallengePriv.h> #include <CFNetwork/CFURLCredentialPriv.h> #include <CFNetwork/CFURLProtectionSpacePriv.h> diff --git a/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp b/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp index c6d513a..71c5e25 100644 --- a/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp +++ b/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp @@ -233,6 +233,52 @@ void deleteCookie(const Document*, const KURL& url, const String& name) } } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + if (!cookieStorage) + return; + + RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookies(cookieStorage)); + if (!cookiesCF) + return; + + CFIndex count = CFArrayGetCount(cookiesCF.get()); + for (CFIndex i = 0; i < count; ++i) { + CFHTTPCookieRef cookie = static_cast<CFHTTPCookieRef>(const_cast<void *>(CFArrayGetValueAtIndex(cookiesCF.get(), i))); + RetainPtr<CFStringRef> domain = cookieDomain(cookie); + hostnames.add(domain.get()); + } +} + +void deleteCookiesForHostname(const String& hostname) +{ + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + if (!cookieStorage) + return; + + RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookies(cookieStorage)); + if (!cookiesCF) + return; + + CFIndex count = CFArrayGetCount(cookiesCF.get()); + for (CFIndex i = count - 1; i >=0; i--) { + CFHTTPCookieRef cookie = static_cast<CFHTTPCookieRef>(const_cast<void *>(CFArrayGetValueAtIndex(cookiesCF.get(), i))); + RetainPtr<CFStringRef> domain = cookieDomain(cookie); + if (String(domain.get()) == hostname) + CFHTTPCookieStorageDeleteCookie(cookieStorage, cookie); + } +} + +void deleteAllCookies() +{ + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + if (!cookieStorage) + return; + + CFHTTPCookieStorageDeleteAllCookies(cookieStorage); +} + } // namespace WebCore #endif // USE(CFNETWORK) diff --git a/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp b/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp index 3deb688..c2a5691 100644 --- a/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp +++ b/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp @@ -28,21 +28,32 @@ #if USE(CFNETWORK) +#include "LoaderRunLoopCF.h" +#include "ResourceHandle.h" #include <CFNetwork/CFHTTPCookiesPriv.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> #include <wtf/MainThread.h> #include <wtf/RetainPtr.h> +#if USE(PLATFORM_STRATEGIES) +#include "CookiesStrategy.h" +#include "PlatformStrategies.h" +#endif + namespace WebCore { -static RetainPtr<CFHTTPCookieStorageRef> s_cookieStorage; +static RetainPtr<CFHTTPCookieStorageRef>& privateBrowsingCookieStorage() +{ + DEFINE_STATIC_LOCAL(RetainPtr<CFHTTPCookieStorageRef>, cookieStorage, ()); + return cookieStorage; +} CFHTTPCookieStorageRef currentCookieStorage() { ASSERT(isMainThread()); - if (s_cookieStorage) - return s_cookieStorage.get(); + if (CFHTTPCookieStorageRef privateCookieStorage = privateBrowsingCookieStorage().get()) + return privateCookieStorage; return wkGetDefaultHTTPCookieStorage(); } @@ -50,17 +61,76 @@ void setCurrentCookieStorage(CFHTTPCookieStorageRef cookieStorage) { ASSERT(isMainThread()); - s_cookieStorage = cookieStorage; + privateBrowsingCookieStorage().adoptCF(cookieStorage); } void setCookieStoragePrivateBrowsingEnabled(bool enabled) { ASSERT(isMainThread()); - if (enabled) - s_cookieStorage.adoptCF(wkCreatePrivateHTTPCookieStorage()); - else - s_cookieStorage = 0; + if (!enabled) { + privateBrowsingCookieStorage() = nullptr; + return; + } + +#if USE(CFURLSTORAGESESSIONS) + privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(ResourceHandle::privateBrowsingStorageSession())); +#else + privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(0)); +#endif +} + +static void notifyCookiesChangedOnMainThread(void* context) +{ + ASSERT(isMainThread()); + +#if USE(PLATFORM_STRATEGIES) + platformStrategies()->cookiesStrategy()->notifyCookiesChanged(); +#endif +} + +static void notifyCookiesChanged(CFHTTPCookieStorageRef inStorage, void *context) +{ + callOnMainThread(notifyCookiesChangedOnMainThread, 0); +} + +static inline CFRunLoopRef cookieStorageObserverRunLoop() +{ + // We're using the loader run loop because we need a CFRunLoop to + // call the CFNetwork cookie storage APIs with. Re-using the loader + // run loop is less overhead than starting a new thread to just listen + // for changes in cookies. + + // FIXME: The loaderRunLoop function name should be a little more generic. + return loaderRunLoop(); +} + +void startObservingCookieChanges() +{ + ASSERT(isMainThread()); + + CFRunLoopRef runLoop = cookieStorageObserverRunLoop(); + ASSERT(runLoop); + + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + ASSERT(cookieStorage); + + CFHTTPCookieStorageScheduleWithRunLoop(cookieStorage, runLoop, kCFRunLoopCommonModes); + CFHTTPCookieStorageAddObserver(cookieStorage, runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0); +} + +void stopObservingCookieChanges() +{ + ASSERT(isMainThread()); + + CFRunLoopRef runLoop = cookieStorageObserverRunLoop(); + ASSERT(runLoop); + + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + ASSERT(cookieStorage); + + CFHTTPCookieStorageRemoveObserver(cookieStorage, runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0); + CFHTTPCookieStorageUnscheduleFromRunLoop(cookieStorage, runLoop, kCFRunLoopCommonModes); } } // namespace WebCore diff --git a/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp b/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp index 8bc8f08..b342fe3 100644 --- a/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp +++ b/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp @@ -53,260 +53,6 @@ typedef CFReadStreamCallBacks WCReadStreamCallBacks; namespace WebCore { -static HashMap<CFReadStreamRef, RefPtr<FormData> >& getStreamFormDatas() -{ - static HashMap<CFReadStreamRef, RefPtr<FormData> > streamFormDatas; - 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 - form->currentStream = CFReadStreamCreateWithFile(0, pathAsURL(nextInput.m_filename).get()); - 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) -{ - FormData* formData = static_cast<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, adoptRef(formData)); - - return newInfo; -} - -static void formFinalize(CFReadStreamRef stream, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - 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, PassRefPtr<FormData> formData) { if (!formData) { diff --git a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp index 52b100f..f840b04 100644 --- a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp +++ b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp @@ -334,6 +334,11 @@ CFArrayRef arrayFromFormData(const FormData& d) static CFURLRequestRef makeFinalRequest(const ResourceRequest& request, bool shouldContentSniff) { CFMutableURLRequestRef newRequest = CFURLRequestCreateMutableCopy(kCFAllocatorDefault, request.cfURLRequest()); + +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = ResourceHandle::privateBrowsingStorageSession()) + wkSetRequestStorageSession(storageSession, newRequest); +#endif if (!shouldContentSniff) wkSetCFURLRequestShouldContentSniff(newRequest, false); @@ -481,6 +486,11 @@ void ResourceHandle::willSendRequest(ResourceRequest& request, const ResourceRes if (!protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) request.clearHTTPAuthorization(); +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = privateBrowsingStorageSession()) + request.setStorageSession(storageSession); +#endif + client()->willSendRequest(this, request, redirectResponse); } @@ -716,6 +726,20 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame) return cached; } +#if USE(CFURLSTORAGESESSIONS) + +RetainPtr<CFURLStorageSessionRef> ResourceHandle::createPrivateBrowsingStorageSession(CFStringRef identifier) +{ + return RetainPtr<CFURLStorageSessionRef>(AdoptCF, wkCreatePrivateStorageSession(identifier)); +} + +String ResourceHandle::privateBrowsingStorageSessionIdentifierDefaultBase() +{ + return String(reinterpret_cast<CFStringRef>(CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleIdentifierKey))); +} + +#endif + void WebCoreSynchronousLoaderClient::willSendRequest(ResourceHandle* handle, ResourceRequest& request, const ResourceResponse& /*redirectResponse*/) { // FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests. diff --git a/Source/WebCore/platform/network/cf/ResourceRequest.h b/Source/WebCore/platform/network/cf/ResourceRequest.h index 172ebe1..2da5026 100644 --- a/Source/WebCore/platform/network/cf/ResourceRequest.h +++ b/Source/WebCore/platform/network/cf/ResourceRequest.h @@ -40,6 +40,10 @@ class NSURLRequest; #endif #endif +#if USE(CFURLSTORAGESESSIONS) +typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; +#endif + namespace WebCore { class ResourceRequest : public ResourceRequestBase { @@ -80,6 +84,10 @@ namespace WebCore { NSURLRequest* nsURLRequest() const; #endif +#if USE(CFURLSTORAGESESSIONS) + void setStorageSession(CFURLStorageSessionRef); +#endif + private: friend class ResourceRequestBase; diff --git a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp index 7a1dfd5..fdccc11 100644 --- a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp +++ b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp @@ -195,6 +195,17 @@ void ResourceRequest::doUpdateResourceRequest() m_httpBody = httpBodyFromRequest(m_cfRequest.get()); } +#if USE(CFURLSTORAGESESSIONS) + +void ResourceRequest::setStorageSession(CFURLStorageSessionRef storageSession) +{ + CFMutableURLRequestRef cfRequest = CFURLRequestCreateMutableCopy(0, m_cfRequest.get()); + wkSetRequestStorageSession(storageSession, cfRequest); + m_cfRequest.adoptCF(cfRequest); +} + +#endif + #endif // USE(CFNETWORK) unsigned initializeMaximumHTTPConnectionCountPerHost() diff --git a/Source/WebCore/platform/network/cf/SocketStreamHandle.h b/Source/WebCore/platform/network/cf/SocketStreamHandle.h index fbda3bc..5c1c6ff 100644 --- a/Source/WebCore/platform/network/cf/SocketStreamHandle.h +++ b/Source/WebCore/platform/network/cf/SocketStreamHandle.h @@ -72,6 +72,7 @@ private: #endif bool shouldUseSSL() const { return m_url.protocolIs("wss"); } + unsigned short port() const; void addCONNECTCredentials(CFHTTPMessageRef response); diff --git a/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp b/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp index 06454a7..d5b1743 100644 --- a/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp +++ b/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp @@ -69,9 +69,6 @@ SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient ASSERT(url.protocolIs("ws") || url.protocolIs("wss")); - if (!m_url.port()) - m_url.setPort(shouldUseSSL() ? 443 : 80); - KURL httpsURL(KURL(), "https://" + m_url.host()); m_httpsURL.adoptCF(httpsURL.createCFURL()); @@ -318,7 +315,7 @@ void SocketStreamHandle::createStreams() // Creating streams to final destination, not to proxy. CFReadStreamRef readStream = 0; CFWriteStreamRef writeStream = 0; - CFStreamCreatePairWithSocketToHost(0, host.get(), m_url.port(), &readStream, &writeStream); + CFStreamCreatePairWithSocketToHost(0, host.get(), port(), &readStream, &writeStream); m_readStream.adoptCF(readStream); m_writeStream.adoptCF(writeStream); @@ -673,4 +670,13 @@ void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&) { } +unsigned short SocketStreamHandle::port() const +{ + if (unsigned short urlPort = m_url.port()) + return urlPort; + if (shouldUseSSL()) + return 443; + return 80; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp b/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp index 2f2489b..779fe45 100644 --- a/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp +++ b/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp @@ -67,4 +67,19 @@ void deleteCookie(const Document* document, const KURL& url, const String& cooki return PlatformBridge::deleteCookie(document, url, cookieName); } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } // namespace WebCore diff --git a/Source/WebCore/platform/network/chromium/NetworkStateNotifierChromium.cpp b/Source/WebCore/platform/network/chromium/NetworkStateNotifierChromium.cpp deleted file mode 100644 index 3b28fbd..0000000 --- a/Source/WebCore/platform/network/chromium/NetworkStateNotifierChromium.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2008, 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 "NetworkStateNotifier.h" - -namespace WebCore { - -// Chromium doesn't currently support network state notifications. This causes -// an extra DLL to get loaded into the renderer which can slow things down a -// bit. We may want an alternate design. - -void NetworkStateNotifier::updateState() -{ -} - -NetworkStateNotifier::NetworkStateNotifier() - : m_isOnLine(true) - , m_networkStateChangedFunction(0) -{ -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/network/chromium/NetworkStateNotifierPrivate.h b/Source/WebCore/platform/network/chromium/NetworkStateNotifierPrivate.h deleted file mode 100644 index 7628d59..0000000 --- a/Source/WebCore/platform/network/chromium/NetworkStateNotifierPrivate.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2008, 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 NetworkStateNotifierPrivate_h -#define NetworkStateNotifierPrivate_h - -namespace WebCore { - - struct NetworkStateNotifierPrivate {}; - -} // namespace WebCore - -#endif diff --git a/Source/WebCore/platform/network/chromium/ResourceResponse.cpp b/Source/WebCore/platform/network/chromium/ResourceResponse.cpp index fc8ac62..58c8dd0 100644 --- a/Source/WebCore/platform/network/chromium/ResourceResponse.cpp +++ b/Source/WebCore/platform/network/chromium/ResourceResponse.cpp @@ -32,14 +32,14 @@ PassOwnPtr<CrossThreadResourceResponseData> ResourceResponse::doPlatformCopyData { data->m_appCacheID = m_appCacheID; data->m_appCacheManifestURL = m_appCacheManifestURL.copy(); - data->m_isContentFiltered = m_isContentFiltered; data->m_isMultipartPayload = m_isMultipartPayload; data->m_wasFetchedViaSPDY = m_wasFetchedViaSPDY; data->m_wasNpnNegotiated = m_wasNpnNegotiated; data->m_wasAlternateProtocolAvailable = m_wasAlternateProtocolAvailable; data->m_wasFetchedViaProxy = m_wasFetchedViaProxy; data->m_responseTime = m_responseTime; - data->m_socketAddress = m_socketAddress; + data->m_remoteIPAddress = m_remoteIPAddress; + data->m_remotePort = m_remotePort; data->m_downloadFilePath = m_downloadFilePath; return data; } @@ -48,14 +48,14 @@ void ResourceResponse::doPlatformAdopt(PassOwnPtr<CrossThreadResourceResponseDat { m_appCacheID = data->m_appCacheID; m_appCacheManifestURL = data->m_appCacheManifestURL.copy(); - m_isContentFiltered = data->m_isContentFiltered; m_isMultipartPayload = data->m_isMultipartPayload; m_wasFetchedViaSPDY = data->m_wasFetchedViaSPDY; m_wasNpnNegotiated = data->m_wasNpnNegotiated; m_wasAlternateProtocolAvailable = data->m_wasAlternateProtocolAvailable; m_wasFetchedViaProxy = data->m_wasFetchedViaProxy; m_responseTime = data->m_responseTime; - m_socketAddress = data->m_socketAddress; + m_remoteIPAddress = data->m_remoteIPAddress; + m_remotePort = data->m_remotePort; m_downloadFilePath = data->m_downloadFilePath; } diff --git a/Source/WebCore/platform/network/chromium/ResourceResponse.h b/Source/WebCore/platform/network/chromium/ResourceResponse.h index 35f13d1..777e1dd 100644 --- a/Source/WebCore/platform/network/chromium/ResourceResponse.h +++ b/Source/WebCore/platform/network/chromium/ResourceResponse.h @@ -37,26 +37,26 @@ namespace WebCore { public: ResourceResponse() : m_appCacheID(0) - , m_isContentFiltered(false) , m_isMultipartPayload(false) , m_wasFetchedViaSPDY(false) , m_wasNpnNegotiated(false) , m_wasAlternateProtocolAvailable(false) , m_wasFetchedViaProxy(false) , m_responseTime(0) + , m_remotePort(0) { } ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename) : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename) , m_appCacheID(0) - , m_isContentFiltered(false) , m_isMultipartPayload(false) , m_wasFetchedViaSPDY(false) , m_wasNpnNegotiated(false) , m_wasAlternateProtocolAvailable(false) , m_wasFetchedViaProxy(false) , m_responseTime(0) + , m_remotePort(0) { } @@ -69,9 +69,6 @@ namespace WebCore { const KURL& appCacheManifestURL() const { return m_appCacheManifestURL; } void setAppCacheManifestURL(const KURL& url) { m_appCacheManifestURL = url; } - bool isContentFiltered() const { return m_isContentFiltered; } - void setIsContentFiltered(bool value) { m_isContentFiltered = value; } - bool wasFetchedViaSPDY() const { return m_wasFetchedViaSPDY; } void setWasFetchedViaSPDY(bool value) { m_wasFetchedViaSPDY = value; } @@ -96,8 +93,11 @@ namespace WebCore { double responseTime() const { return m_responseTime; } void setResponseTime(double responseTime) { m_responseTime = responseTime; } - const String& socketAddress() const { return m_socketAddress; } - void setSocketAddress(const String& value) { m_socketAddress = value; } + const String& remoteIPAddress() const { return m_remoteIPAddress; } + void setRemoteIPAddress(const String& value) { m_remoteIPAddress = value; } + + unsigned short remotePort() const { return m_remotePort; } + void setRemotePort(unsigned short value) { m_remotePort = value; } const String& downloadFilePath() const { return m_downloadFilePath; } void setDownloadFilePath(const String& downloadFilePath) { m_downloadFilePath = downloadFilePath; } @@ -126,10 +126,6 @@ namespace WebCore { // Note: only valid for main resource responses. KURL m_appCacheManifestURL; - // Whether the contents for this response has been altered/blocked (usually - // for security reasons. - bool m_isContentFiltered; - // Set to true if this is part of a multipart response. bool m_isMultipartPayload; @@ -150,9 +146,11 @@ namespace WebCore { // responses, this time could be "far" in the past. double m_responseTime; - // Remote address of the socket which fetched this resource, for presenting - // to inquisitive users. Can be "ipv4:port", "[ipv6]:port", or empty. - String m_socketAddress; + // Remote IP address of the socket which fetched this resource. + String m_remoteIPAddress; + + // Remote port number of the socket which fetched this resource. + unsigned short m_remotePort; // The path to the downloaded file. String m_downloadFilePath; @@ -161,14 +159,14 @@ namespace WebCore { struct CrossThreadResourceResponseData : public CrossThreadResourceResponseDataBase { long long m_appCacheID; KURL m_appCacheManifestURL; - bool m_isContentFiltered; bool m_isMultipartPayload; bool m_wasFetchedViaSPDY; bool m_wasNpnNegotiated; bool m_wasAlternateProtocolAvailable; bool m_wasFetchedViaProxy; double m_responseTime; - String m_socketAddress; + String m_remoteIPAddress; + unsigned short m_remotePort; String m_downloadFilePath; }; diff --git a/Source/WebCore/platform/network/curl/CookieJarCurl.cpp b/Source/WebCore/platform/network/curl/CookieJarCurl.cpp index 36495d0..57102a7 100644 --- a/Source/WebCore/platform/network/curl/CookieJarCurl.cpp +++ b/Source/WebCore/platform/network/curl/CookieJarCurl.cpp @@ -68,4 +68,19 @@ void setCookieStoragePrivateBrowsingEnabled(bool enabled) } #endif +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp b/Source/WebCore/platform/network/curl/DownloadBundle.h index 7cc6ceb..cf90908 100644 --- a/Source/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp +++ b/Source/WebCore/platform/network/curl/DownloadBundle.h @@ -1,54 +1,43 @@ /* - * Copyright 2009, The Android Open Source Project + * Copyright (C) 2011 Apple 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 + * 1. 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 + * 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 THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * 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 THE COPYRIGHT OWNER OR + * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#include "NetworkStateNotifier.h" +#ifndef DownloadBundle_h +#define DownloadBundle_h -namespace WebCore { - -void NetworkStateNotifier::networkStateChange(bool online) -{ - if (m_isOnLine == online) - return; - - m_isOnLine = online; +#include <wtf/Forward.h> - if (m_networkStateChangedFunction) - m_networkStateChangedFunction(); -} +typedef const struct __CFData* CFDataRef; -// TODO: Upstream to webkit.org -void NetworkStateNotifier::networkTypeChange(Connection::ConnectionType type) -{ - if (m_type == type) - return; +namespace WebCore { +namespace DownloadBundle { - m_type = type; +bool appendResumeData(CFDataRef resumeData, const String& bundlePath); +CFDataRef extractResumeData(const String& bundlePath); +const String& fileExtension(); - if (m_networkStateChangedFunction) - m_networkStateChangedFunction(); -} +} // namespace DownloadBundle +} // namespace WebCore -} +#endif // DownloadBundle_h diff --git a/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp index f360f86..1d276aa 100644 --- a/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp +++ b/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp @@ -34,7 +34,7 @@ #include "ResourceHandleManager.h" #include "SharedBuffer.h" -#if PLATFORM(WIN) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CF) #include <wtf/PassRefPtr.h> #include <wtf/RetainPtr.h> #endif @@ -124,7 +124,7 @@ bool ResourceHandle::supportsBufferedData() return false; } -#if PLATFORM(WIN) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CF) static HashSet<String>& allowsAnyHTTPSCertificateHosts() { static HashSet<String> hosts; @@ -138,7 +138,7 @@ void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host) } #endif -#if PLATFORM(WIN) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CF) // FIXME: The CFDataRef will need to be something else when // building without static HashMap<String, RetainPtr<CFDataRef> >& clientCerts() diff --git a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp index 2e4259c..f0fd403 100644 --- a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp +++ b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp @@ -44,7 +44,7 @@ #include <errno.h> #include <stdio.h> -#if PLATFORM(CF) +#if USE(CF) #include <wtf/RetainPtr.h> #endif #include <wtf/Threading.h> @@ -66,7 +66,7 @@ static const bool ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS"); static CString certificatePath() { -#if PLATFORM(CF) +#if USE(CF) CFBundleRef webKitBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit")); if (webKitBundle) { RetainPtr<CFURLRef> certURLRef(AdoptCF, CFBundleCopyResourceURL(webKitBundle, CFSTR("cacert"), CFSTR("pem"), CFSTR("certificates"))); diff --git a/Source/WebCore/platform/network/mac/AuthenticationMac.mm b/Source/WebCore/platform/network/mac/AuthenticationMac.mm index a187187..efa42d9 100644 --- a/Source/WebCore/platform/network/mac/AuthenticationMac.mm +++ b/Source/WebCore/platform/network/mac/AuthenticationMac.mm @@ -31,7 +31,6 @@ #import "AuthenticationClient.h" #import "Credential.h" #import "ProtectionSpace.h" -#import <wtf/UnusedParam.h> #import <Foundation/NSURLAuthenticationChallenge.h> #import <Foundation/NSURLCredential.h> @@ -87,20 +86,6 @@ using namespace WebCore; m_client->receivedCancellation(core(challenge)); } -- (void)performDefaultHandlingForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge -{ - // FIXME: <rdar://problem/8995483> Determine what, if anything, we should do here. - ASSERT_NOT_REACHED(); - UNUSED_PARAM(challenge); -} - -- (void)rejectProtectionSpaceAndContinueWithChallenge:(NSURLAuthenticationChallenge *)challenge -{ - // FIXME: <rdar://problem/8995483> Determine what, if anything, we should do here. - ASSERT_NOT_REACHED(); - UNUSED_PARAM(challenge); -} - @end namespace WebCore { diff --git a/Source/WebCore/platform/network/mac/CookieStorageMac.mm b/Source/WebCore/platform/network/mac/CookieStorageMac.mm index ab26f7b..db64aae 100644 --- a/Source/WebCore/platform/network/mac/CookieStorageMac.mm +++ b/Source/WebCore/platform/network/mac/CookieStorageMac.mm @@ -26,13 +26,98 @@ #include "config.h" #include "CookieStorage.h" +#import "ResourceHandle.h" #import "WebCoreSystemInterface.h" +#import <wtf/RetainPtr.h> +#import <wtf/UnusedParam.h> + +#if USE(PLATFORM_STRATEGIES) +#include "CookiesStrategy.h" +#include "PlatformStrategies.h" +#endif + +using namespace WebCore; + +@interface CookieStorageObjCAdapter : NSObject +-(void)notifyCookiesChangedOnMainThread; +-(void)cookiesChangedNotificationHandler:(NSNotification *)notification; +-(void)startListeningForCookieChangeNotifications; +-(void)stopListeningForCookieChangeNotifications; +@end + +@implementation CookieStorageObjCAdapter + +-(void)notifyCookiesChangedOnMainThread +{ +#if USE(PLATFORM_STRATEGIES) + platformStrategies()->cookiesStrategy()->notifyCookiesChanged(); +#endif +} + +-(void)cookiesChangedNotificationHandler:(NSNotification *)notification +{ + UNUSED_PARAM(notification); + + [self performSelectorOnMainThread:@selector(notifyCookiesChangedOnMainThread) withObject:nil waitUntilDone:FALSE]; +} + +-(void)startListeningForCookieChangeNotifications +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cookiesChangedNotificationHandler:) name:NSHTTPCookieManagerCookiesChangedNotification object:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; +} + +-(void)stopListeningForCookieChangeNotifications +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSHTTPCookieManagerCookiesChangedNotification object:nil]; +} + +@end namespace WebCore { +#if USE(CFURLSTORAGESESSIONS) + +RetainPtr<CFHTTPCookieStorageRef>& privateBrowsingCookieStorage() +{ + DEFINE_STATIC_LOCAL(RetainPtr<CFHTTPCookieStorageRef>, cookieStorage, ()); + return cookieStorage; +} + +#endif + void setCookieStoragePrivateBrowsingEnabled(bool enabled) { +#if USE(CFURLSTORAGESESSIONS) + if (enabled && privateBrowsingCookieStorage()) + return; + + if (enabled && ResourceHandle::privateBrowsingStorageSession()) { + privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(ResourceHandle::privateBrowsingStorageSession())); + + // FIXME: When Private Browsing is enabled, the Private Browsing Cookie Storage should be + // observed for changes, not the default Cookie Storage. + + return; + } + + privateBrowsingCookieStorage() = nullptr; +#endif wkSetCookieStoragePrivateBrowsingEnabled(enabled); } +static CookieStorageObjCAdapter *cookieStorageAdapter; + +void startObservingCookieChanges() +{ + if (!cookieStorageAdapter) + cookieStorageAdapter = [[CookieStorageObjCAdapter alloc] init]; + [cookieStorageAdapter startListeningForCookieChangeNotifications]; +} + +void stopObservingCookieChanges() +{ + ASSERT(cookieStorageAdapter); + [cookieStorageAdapter stopListeningForCookieChangeNotifications]; +} + } diff --git a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm index 2d687c0..96d561d 100644 --- a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm +++ b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm @@ -33,6 +33,7 @@ #import "Base64.h" #import "BlobRegistry.h" #import "BlockExceptions.h" +#import "CookieStorage.h" #import "CredentialStorage.h" #import "CachedResourceLoader.h" #import "EmptyProtocolDefinitions.h" @@ -186,6 +187,35 @@ bool ResourceHandle::didSendBodyDataDelegateExists() return NSFoundationVersionNumber > MaxFoundationVersionWithoutdidSendBodyDataDelegate; } +static bool shouldRelaxThirdPartyCookiePolicy(const KURL& url) +{ + // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies. + + NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + + NSHTTPCookieAcceptPolicy cookieAcceptPolicy; +#if USE(CFURLSTORAGESESSIONS) + CFHTTPCookieStorageRef cfPrivateBrowsingStorage = privateBrowsingCookieStorage().get(); + if (cfPrivateBrowsingStorage) + cookieAcceptPolicy = wkGetHTTPCookieAcceptPolicy(cfPrivateBrowsingStorage); + else +#endif + cookieAcceptPolicy = [sharedStorage cookieAcceptPolicy]; + + if (cookieAcceptPolicy != NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain) + return false; + + NSArray *cookies; +#if USE(CFURLSTORAGESESSIONS) + if (cfPrivateBrowsingStorage) + cookies = wkHTTPCookiesForURL(cfPrivateBrowsingStorage, url); + else +#endif + cookies = [sharedStorage cookiesForURL:url]; + + return [cookies count]; +} + void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff) { // Credentials for ftp can only be passed in URL, the connection:didReceiveAuthenticationChallenge: delegate call won't be made. @@ -200,9 +230,7 @@ void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredential firstRequest().setURL(urlWithCredentials); } - // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies. - NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain && [[sharedStorage cookiesForURL:firstRequest().url()] count]) + if (shouldRelaxThirdPartyCookiePolicy(firstRequest().url())) firstRequest().setFirstPartyForCookies(firstRequest().url()); #if !defined(BUILDING_ON_TIGER) @@ -239,6 +267,11 @@ void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredential static bool supportsSettingConnectionProperties = [NSURLConnection instancesRespondToSelector:@selector(_initWithRequest:delegate:usesCache:maxContentLength:startImmediately:connectionProperties:)]; #endif +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = privateBrowsingStorageSession()) + nsRequest = [wkCopyRequestWithStorageSession(storageSession, nsRequest) autorelease]; +#endif + if (supportsSettingConnectionProperties) { NSDictionary *sessionID = shouldUseCredentialStorage ? [NSDictionary dictionary] : [NSDictionary dictionaryWithObject:@"WebKitPrivateSession" forKey:@"_kCFURLConnectionSessionID"]; NSDictionary *propertyDictionary = [NSDictionary dictionaryWithObject:sessionID forKey:@"kCFURLConnectionSocketStreamProperties"]; @@ -506,9 +539,7 @@ void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const UNUSED_PARAM(context); NSURLRequest *firstRequest = request.nsURLRequest(); - // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies. - NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain && [[sharedStorage cookiesForURL:[firstRequest URL]] count]) { + if (shouldRelaxThirdPartyCookiePolicy([firstRequest URL])) { NSMutableURLRequest *mutableRequest = [[firstRequest mutableCopy] autorelease]; [mutableRequest setMainDocumentURL:[mutableRequest URL]]; firstRequest = mutableRequest; @@ -552,6 +583,11 @@ void ResourceHandle::willSendRequest(ResourceRequest& request, const ResourceRes if (!protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) request.clearHTTPAuthorization(); +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = privateBrowsingStorageSession()) + request.setStorageSession(storageSession); +#endif + client()->willSendRequest(this, request, redirectResponse); } @@ -693,6 +729,20 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen client()->receivedCancellation(this, challenge); } +#if USE(CFURLSTORAGESESSIONS) + +RetainPtr<CFURLStorageSessionRef> ResourceHandle::createPrivateBrowsingStorageSession(CFStringRef identifier) +{ + return RetainPtr<CFURLStorageSessionRef>(AdoptCF, wkCreatePrivateStorageSession(identifier)); +} + +String ResourceHandle::privateBrowsingStorageSessionIdentifierDefaultBase() +{ + return String([[NSBundle mainBundle] bundleIdentifier]); +} + +#endif + } // namespace WebCore @implementation WebCoreResourceHandleAsDelegate diff --git a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm index 640d237..8446782 100644 --- a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm +++ b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm @@ -40,11 +40,12 @@ typedef unsigned NSUInteger; #endif -@interface NSURLRequest (WebCoreContentDispositionEncoding) +@interface NSURLRequest (WebNSURLRequestDetails) - (NSArray *)contentDispositionEncodingFallbackArray; ++ (void)setDefaultTimeoutInterval:(NSTimeInterval)seconds; @end -@interface NSMutableURLRequest (WebCoreContentDispositionEncoding) +@interface NSMutableURLRequest (WebMutableNSURLRequestDetails) - (void)setContentDispositionEncodingFallbackArray:(NSArray *)theEncodingFallbackArray; @end @@ -126,8 +127,12 @@ void ResourceRequest::doUpdatePlatformRequest() #endif [nsRequest setCachePolicy:(NSURLRequestCachePolicy)cachePolicy()]; - if (timeoutInterval() != unspecifiedTimeoutInterval) - [nsRequest setTimeoutInterval:timeoutInterval()]; + + double timeoutInterval = ResourceRequestBase::timeoutInterval(); + if (timeoutInterval) + [nsRequest setTimeoutInterval:timeoutInterval]; + // Otherwise, respect NSURLRequest default timeout. + [nsRequest setMainDocumentURL:firstPartyForCookies()]; if (!httpMethod().isEmpty()) [nsRequest setHTTPMethod:httpMethod()]; @@ -169,6 +174,15 @@ void ResourceRequest::applyWebArchiveHackForMail() [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)nsURLRequest()]; } +#if USE(CFURLSTORAGESESSIONS) + +void ResourceRequest::setStorageSession(CFURLStorageSessionRef storageSession) +{ + m_nsRequest = wkCopyRequestWithStorageSession(storageSession, m_nsRequest.get()); +} + +#endif + } // namespace WebCore #endif // !USE(CFNETWORK) diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 98fd68d..61fe96c 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -23,7 +23,6 @@ #include "HTTPParsers.h" #include "MIMETypeRegistry.h" -#include "QtNAMThreadSafeProxy.h" #include "ResourceHandle.h" #include "ResourceHandleClient.h" #include "ResourceHandleInternal.h" @@ -47,19 +46,22 @@ // It is fixed in Qt 4.6.3. See https://bugs.webkit.org/show_bug.cgi?id=32113 // and https://bugs.webkit.org/show_bug.cgi?id=36755 #if QT_VERSION > QT_VERSION_CHECK(4, 6, 2) -#define SIGNAL_CONN Qt::AutoConnection +#define SIGNAL_CONN Qt::DirectConnection #else #define SIGNAL_CONN Qt::QueuedConnection #endif +// In Qt 4.8, the attribute for sending a request synchronously will be made public, +// for now, use this hackish solution for setting the internal attribute. +const QNetworkRequest::Attribute gSynchronousNetworkRequestAttribute = static_cast<QNetworkRequest::Attribute>(QNetworkRequest::HttpPipeliningWasUsedAttribute + 7); + static const int gMaxRecursionLimit = 10; namespace WebCore { // Take a deep copy of the FormDataElement -FormDataIODevice::FormDataIODevice(FormData* data, QObject* parent) - : QIODevice(parent) - , m_formElements(data ? data->elements() : Vector<FormDataElement>()) +FormDataIODevice::FormDataIODevice(FormData* data) + : m_formElements(data ? data->elements() : Vector<FormDataElement>()) , m_currentFile(0) , m_currentDelta(0) , m_fileSize(0) @@ -194,9 +196,6 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode load , m_shouldForwardData(false) , m_redirectionTries(gMaxRecursionLimit) { - // Make this a direct function call once we require 4.6.1+. - connect(this, SIGNAL(processQueuedItems()), this, SLOT(sendQueuedItems()), SIGNAL_CONN); - const ResourceRequest &r = m_resourceHandle->firstRequest(); if (r.httpMethod() == "GET") @@ -223,14 +222,14 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode load m_request = r.toNetworkRequest(originatingObject); - if (m_loadMode == LoadNormal) + if (m_loadMode == LoadSynchronously) + m_request.setAttribute(gSynchronousNetworkRequestAttribute, true); + + if (m_loadMode == LoadNormal || m_loadMode == LoadSynchronously) start(); -} -QNetworkReplyHandler::~QNetworkReplyHandler() -{ - if (m_reply) - m_reply->deleteLater(); + if (m_loadMode == LoadSynchronously) + m_loadMode = LoadNormal; } void QNetworkReplyHandler::setLoadMode(LoadMode mode) @@ -242,20 +241,9 @@ void QNetworkReplyHandler::setLoadMode(LoadMode mode) case LoadNormal: m_loadMode = LoadResuming; emit processQueuedItems(); - - // sendQueuedItems() may cause m_reply to be set to 0 due to the finish() call causing - // the ResourceHandle instance that owns this QNetworkReplyHandler to be destroyed. - if (m_reply) { - // Restart forwarding only after processQueuedItems to make sure - // our buffered data was handled before any incoming data. - m_reply->setForwardingDefered(false); - } break; case LoadDeferred: - if (m_reply) { - m_loadMode = LoadDeferred; - m_reply->setForwardingDefered(true); - } + m_loadMode = LoadDeferred; break; case LoadResuming: Q_ASSERT(0); // should never happen @@ -267,30 +255,31 @@ void QNetworkReplyHandler::abort() { m_resourceHandle = 0; if (m_reply) { - QtNetworkReplyThreadSafeProxy* reply = release(); + QNetworkReply* reply = release(); reply->abort(); reply->deleteLater(); } deleteLater(); } -QtNetworkReplyThreadSafeProxy* QNetworkReplyHandler::release() +QNetworkReply* QNetworkReplyHandler::release() { - QtNetworkReplyThreadSafeProxy* reply = m_reply; + QNetworkReply* reply = m_reply; if (m_reply) { disconnect(m_reply, 0, this, 0); // We have queued connections to the QNetworkReply. Make sure any // posted meta call events that were the result of a signal emission // don't reach the slots in our instance. QCoreApplication::removePostedEvents(this, QEvent::MetaCall); + m_reply->setParent(0); m_reply = 0; } return reply; } -static bool ignoreHttpError(QtNetworkReplyThreadSafeProxy* reply, bool receivedData) +static bool ignoreHttpError(QNetworkReply* reply, bool receivedData) { - int httpStatusCode = reply->httpStatusCode(); + int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (httpStatusCode == 401 || httpStatusCode == 407) return true; @@ -326,10 +315,10 @@ void QNetworkReplyHandler::finish() client->didFinishLoading(m_resourceHandle, 0); else { QUrl url = m_reply->url(); - int httpStatusCode = m_reply->httpStatusCode(); + int httpStatusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (httpStatusCode) { - ResourceError error("HTTP", httpStatusCode, url.toString(), QString::fromAscii(m_reply->httpReasonPhrase())); + ResourceError error("HTTP", httpStatusCode, url.toString(), m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()); client->didFail(m_resourceHandle, error); } else { ResourceError error("QtNetwork", m_reply->error(), url.toString(), m_reply->errorString()); @@ -370,7 +359,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded() if (!client) return; - WTF::String contentType = m_reply->contentTypeHeader(); + WTF::String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); WTF::String encoding = extractCharsetFromMediaType(contentType); WTF::String mimeType = extractMIMETypeFromMediaType(contentType); @@ -381,7 +370,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded() KURL url(m_reply->url()); ResourceResponse response(url, mimeType.lower(), - m_reply->contentLengthHeader(), + m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), encoding, String()); if (url.isLocalFile()) { @@ -390,10 +379,10 @@ void QNetworkReplyHandler::sendResponseIfNeeded() } // The status code is equal to 0 for protocols not in the HTTP family. - int statusCode = m_reply->httpStatusCode(); + int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (url.protocolInHTTPFamily()) { - String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->contentDispositionHeader())); + String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->rawHeader("Content-Disposition"))); if (!suggestedFilename.isEmpty()) response.setSuggestedFilename(suggestedFilename); @@ -401,15 +390,19 @@ void QNetworkReplyHandler::sendResponseIfNeeded() response.setSuggestedFilename(url.lastPathComponent()); response.setHTTPStatusCode(statusCode); - response.setHTTPStatusText(m_reply->httpReasonPhrase().constData()); + response.setHTTPStatusText(m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray().constData()); // Add remaining headers. - foreach (const QtNetworkReplyThreadSafeProxy::RawHeaderPair& pair, m_reply->rawHeaderPairs()) { +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + foreach (const QNetworkReply::RawHeaderPair& pair, m_reply->rawHeaderPairs()) response.setHTTPHeaderField(QString::fromAscii(pair.first), QString::fromAscii(pair.second)); - } +#else + foreach (const QByteArray& headerName, m_reply->rawHeaderList()) + response.setHTTPHeaderField(QString::fromAscii(headerName), QString::fromAscii(m_reply->rawHeader(headerName))); +#endif } - QUrl redirection = m_reply->redirectionTarget(); + QUrl redirection = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); if (redirection.isValid()) { QUrl newUrl = m_reply->url().resolved(redirection); @@ -454,15 +447,13 @@ void QNetworkReplyHandler::sendResponseIfNeeded() client->didReceiveResponse(m_resourceHandle, response); } -void QNetworkReplyHandler::forwardData(const QByteArray &data) +void QNetworkReplyHandler::forwardData() { m_shouldForwardData = (m_loadMode != LoadNormal); - if (m_shouldForwardData) { - m_bufferedData += data; + if (m_shouldForwardData) return; - } - if (!data.isEmpty()) + if (m_reply->bytesAvailable()) m_responseContainsData = true; sendResponseIfNeeded(); @@ -474,6 +465,8 @@ void QNetworkReplyHandler::forwardData(const QByteArray &data) if (!m_resourceHandle) return; + QByteArray data = m_reply->read(m_reply->bytesAvailable()); + ResourceHandleClient* client = m_resourceHandle->client(); if (!client) return; @@ -516,53 +509,41 @@ void QNetworkReplyHandler::start() && (!url.toLocalFile().isEmpty() || url.scheme() == QLatin1String("data"))) m_method = QNetworkAccessManager::GetOperation; - m_reply = new QtNetworkReplyThreadSafeProxy(manager); - connect(m_reply, SIGNAL(finished()), this, SLOT(finish()), SIGNAL_CONN); - - // For http(s) we know that the headers are complete upon metaDataChanged() emission, so we - // can send the response as early as possible - if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) - connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(sendResponseIfNeeded()), SIGNAL_CONN); - - connect(m_reply, SIGNAL(dataReceived(const QByteArray&)), this, SLOT(forwardData(const QByteArray&)), SIGNAL_CONN); - - if (m_resourceHandle->firstRequest().reportUploadProgress()) - connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)), SIGNAL_CONN); - switch (m_method) { case QNetworkAccessManager::GetOperation: - m_reply->get(m_request); + m_reply = manager->get(m_request); break; case QNetworkAccessManager::PostOperation: { - FormDataIODevice* postDevice = new FormDataIODevice(d->m_firstRequest.httpBody(), this); + FormDataIODevice* postDevice = new FormDataIODevice(d->m_firstRequest.httpBody()); // We may be uploading files so prevent QNR from buffering data m_request.setHeader(QNetworkRequest::ContentLengthHeader, postDevice->getFormDataSize()); m_request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, QVariant(true)); - m_reply->post(m_request, postDevice); + m_reply = manager->post(m_request, postDevice); + postDevice->setParent(m_reply); break; } case QNetworkAccessManager::HeadOperation: - m_reply->head(m_request); + m_reply = manager->head(m_request); break; case QNetworkAccessManager::PutOperation: { - FormDataIODevice* putDevice = new FormDataIODevice(d->m_firstRequest.httpBody(), this); + FormDataIODevice* putDevice = new FormDataIODevice(d->m_firstRequest.httpBody()); // We may be uploading files so prevent QNR from buffering data m_request.setHeader(QNetworkRequest::ContentLengthHeader, putDevice->getFormDataSize()); m_request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, QVariant(true)); - m_reply->put(m_request, putDevice); + m_reply = manager->put(m_request, putDevice); + putDevice->setParent(m_reply); break; } case QNetworkAccessManager::DeleteOperation: { - m_reply->deleteResource(m_request); + m_reply = manager->deleteResource(m_request); break; } #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) case QNetworkAccessManager::CustomOperation: - m_reply->sendCustomRequest(m_request, m_resourceHandle->firstRequest().httpMethod().latin1().data()); + m_reply = manager->sendCustomRequest(m_request, m_resourceHandle->firstRequest().httpMethod().latin1().data()); break; #endif case QNetworkAccessManager::UnknownOperation: { - m_reply->deleteLater(); m_reply = 0; ResourceHandleClient* client = m_resourceHandle->client(); if (client) { @@ -574,6 +555,34 @@ void QNetworkReplyHandler::start() return; } } + + m_reply->setParent(this); + + if (m_loadMode == LoadSynchronously && m_reply->isFinished()) { + // If supported, a synchronous request will be finished at this point, no need to hook up the signals. + return; + } + + connect(m_reply, SIGNAL(finished()), + this, SLOT(finish()), SIGNAL_CONN); + + // For http(s) we know that the headers are complete upon metaDataChanged() emission, so we + // can send the response as early as possible + if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) + connect(m_reply, SIGNAL(metaDataChanged()), + this, SLOT(sendResponseIfNeeded()), SIGNAL_CONN); + + connect(m_reply, SIGNAL(readyRead()), + this, SLOT(forwardData()), SIGNAL_CONN); + + if (m_resourceHandle->firstRequest().reportUploadProgress()) { + connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)), + this, SLOT(uploadProgress(qint64, qint64)), SIGNAL_CONN); + } + + // Make this a direct function call once we require 4.6.1+. + connect(this, SIGNAL(processQueuedItems()), + this, SLOT(sendQueuedItems()), SIGNAL_CONN); } void QNetworkReplyHandler::resetState() @@ -599,10 +608,8 @@ void QNetworkReplyHandler::sendQueuedItems() if (m_shouldSendResponse) sendResponseIfNeeded(); - if (m_shouldForwardData) { - forwardData(m_bufferedData); - m_bufferedData.clear(); - } + if (m_shouldForwardData) + forwardData(); if (m_shouldFinish) finish(); diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h index 11638b3..8c9bd08 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h @@ -23,7 +23,6 @@ #include <QNetworkRequest> #include <QNetworkAccessManager> -#include <QNetworkReply> #include "FormData.h" @@ -35,7 +34,6 @@ QT_END_NAMESPACE namespace WebCore { class ResourceHandle; -class QtNetworkReplyThreadSafeProxy; class QNetworkReplyHandler : public QObject { @@ -44,24 +42,26 @@ public: enum LoadMode { LoadNormal, LoadDeferred, - LoadResuming + LoadResuming, + LoadSynchronously }; QNetworkReplyHandler(ResourceHandle *handle, LoadMode); - ~QNetworkReplyHandler(); void setLoadMode(LoadMode); + QNetworkReply* reply() const { return m_reply; } + void abort(); - QtNetworkReplyThreadSafeProxy* release(); + QNetworkReply* release(); signals: void processQueuedItems(); -private slots: +public slots: void finish(); void sendResponseIfNeeded(); - void forwardData(const QByteArray &data); + void forwardData(); void sendQueuedItems(); void uploadProgress(qint64 bytesSent, qint64 bytesTotal); @@ -70,7 +70,7 @@ private: void resetState(); String httpMethod() const; - QtNetworkReplyThreadSafeProxy* m_reply; + QNetworkReply* m_reply; ResourceHandle* m_resourceHandle; bool m_redirected; bool m_responseSent; @@ -85,7 +85,6 @@ private: bool m_shouldSendResponse; bool m_shouldForwardData; int m_redirectionTries; - QByteArray m_bufferedData; }; // Self destructing QIODevice for FormData @@ -96,7 +95,7 @@ private: class FormDataIODevice : public QIODevice { Q_OBJECT public: - FormDataIODevice(FormData*, QObject* parent = 0); + FormDataIODevice(FormData*); ~FormDataIODevice(); bool isSequential() const; diff --git a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp deleted file mode 100644 index a98b4f4..0000000 --- a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#include "config.h" -#include "QtNAMThreadSafeProxy.h" - -#include "Assertions.h" -#include <QAbstractNetworkCache> -#include <QNetworkAccessManager> -#include <QNetworkCookieJar> -#include <QStringList> - -namespace WebCore { - -QtNAMThreadSafeProxy::QtNAMThreadSafeProxy(QNetworkAccessManager *manager) - : m_manager(manager) -{ - moveToThread(manager->thread()); - - connect(this, SIGNAL(localSetCookiesRequested(const QUrl&, const QString&)), SLOT(localSetCookies(const QUrl&, const QString&))); - connect(this, SIGNAL(localCookiesForUrlRequested(const QUrl&, bool*, QList<QNetworkCookie>*)), SLOT(localCookiesForUrl(const QUrl&, bool*, QList<QNetworkCookie>*))); - connect(this, SIGNAL(localWillLoadFromCacheRequested(const QUrl&, bool*, bool*)), SLOT(localWillLoadFromCache(const QUrl&, bool*, bool*))); - connect(this, SIGNAL(hasCookieJarRequested(bool*, bool*)), SLOT(hasCookieJar(bool*, bool*))); -} - -bool QtNAMThreadSafeProxy::hasCookieJar() -{ - bool result; - bool done = false; - emit hasCookieJarRequested(&done, &result); - QMutexLocker lock(&m_resultMutex); - while (!done) - m_resultWaitCondition.wait(&m_resultMutex); - return result; -} - -void QtNAMThreadSafeProxy::localSetCookies(const QUrl& url, const QString& cookies) -{ - QList<QNetworkCookie> cookieList = QNetworkCookie::parseCookies(cookies.toAscii()); - QList<QNetworkCookie>::Iterator it = cookieList.begin(); - while (it != cookieList.end()) { - if (it->isHttpOnly()) - it = cookieList.erase(it); - else - ++it; - } - m_manager->cookieJar()->setCookiesFromUrl(cookieList, url); -} - -void QtNAMThreadSafeProxy::localCookiesForUrl(const QUrl& url, bool* done, QList<QNetworkCookie>* result) -{ - QMutexLocker lock(&m_resultMutex); - *result = m_manager->cookieJar()->cookiesForUrl(url); - *done = true; - m_resultWaitCondition.wakeAll(); -} - -void QtNAMThreadSafeProxy::localWillLoadFromCache(const QUrl& url, bool* done, bool* result) -{ - QMutexLocker lock(&m_resultMutex); - if (m_manager->cache()) - *result = m_manager->cache()->metaData(url).isValid(); - else - *result = false; - *done = true; - m_resultWaitCondition.wakeAll(); -} - -void QtNAMThreadSafeProxy::hasCookieJar(bool* done, bool* result) -{ - QMutexLocker lock(&m_resultMutex); - *result = !!m_manager->cookieJar(); - *done = true; - m_resultWaitCondition.wakeAll(); -} - -QtNetworkReplyThreadSafeProxy::QtNetworkReplyThreadSafeProxy(QNetworkAccessManager *manager) - : m_manager(manager) - , m_reply(0) - , m_forwardingDefered(false) - , m_contentLengthHeader(0) - , m_error(QNetworkReply::NoError) - , m_httpStatusCode(0) -{ - moveToThread(manager->thread()); - - // This might be unnecessarily heavy to do for each request while we could have the same wrapper for the manager instead - connect(this, SIGNAL(localGetRequested(const QNetworkRequest&)), SLOT(localGet(const QNetworkRequest&))); - connect(this, SIGNAL(localPostRequested(const QNetworkRequest&, QIODevice*)), SLOT(localPost(const QNetworkRequest&, QIODevice*))); - connect(this, SIGNAL(localHeadRequested(const QNetworkRequest&)), SLOT(localHead(const QNetworkRequest&))); - connect(this, SIGNAL(localPutRequested(const QNetworkRequest&, QIODevice*)), SLOT(localPut(const QNetworkRequest&, QIODevice*))); - connect(this, SIGNAL(localDeleteResourceRequested(const QNetworkRequest&)), SLOT(localDeleteResource(const QNetworkRequest&))); - connect(this, SIGNAL(localCustomRequestRequested(const QNetworkRequest&, const QByteArray&)), SLOT(localCustomRequest(const QNetworkRequest&, const QByteArray&))); - connect(this, SIGNAL(localAbortRequested()), SLOT(localAbort())); - connect(this, SIGNAL(localSetForwardingDeferedRequested(bool)), SLOT(localSetForwardingDefered(bool))); -} - -QtNetworkReplyThreadSafeProxy::~QtNetworkReplyThreadSafeProxy() -{ - delete m_reply; -} - -void QtNetworkReplyThreadSafeProxy::localGet(const QNetworkRequest& request) -{ - localSetReply(m_manager->get(request)); -} - -void QtNetworkReplyThreadSafeProxy::localPost(const QNetworkRequest& request, QIODevice* data) -{ - localSetReply(m_manager->post(request, data)); -} - -void QtNetworkReplyThreadSafeProxy::localHead(const QNetworkRequest& request) -{ - localSetReply(m_manager->head(request)); -} - -void QtNetworkReplyThreadSafeProxy::localPut(const QNetworkRequest& request, QIODevice* data) -{ - localSetReply(m_manager->put(request, data)); -} - -void QtNetworkReplyThreadSafeProxy::localDeleteResource(const QNetworkRequest& request) -{ - localSetReply(m_manager->deleteResource(request)); -} - -void QtNetworkReplyThreadSafeProxy::localCustomRequest(const QNetworkRequest& request, const QByteArray& verb) -{ -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - localSetReply(m_manager->sendCustomRequest(request, verb)); -#endif -} - -void QtNetworkReplyThreadSafeProxy::localAbort() -{ - if (m_reply) - m_reply->abort(); -} - -void QtNetworkReplyThreadSafeProxy::localForwardData() -{ - if (m_reply->bytesAvailable()) { - QByteArray data = m_reply->read(m_reply->bytesAvailable()); - emit dataReceived(data); - } -} - -void QtNetworkReplyThreadSafeProxy::localSetForwardingDefered(bool forwardingDefered) -{ - if (m_forwardingDefered && !forwardingDefered) - localForwardData(); - m_forwardingDefered = forwardingDefered; -} - -void QtNetworkReplyThreadSafeProxy::localMirrorMembers() -{ - ASSERT(m_reply); - QMutexLocker lock(&m_mirroredMembersMutex); - - m_contentDispositionHeader = m_reply->rawHeader("Content-Disposition"); - m_contentLengthHeader = m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(); - m_contentTypeHeader = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); - m_error = m_reply->error(); - m_errorString = m_reply->errorString(); - m_httpReasonPhrase = m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray(); - m_httpStatusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - m_url = m_reply->url(); - m_redirectionTarget = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - m_rawHeaderPairs = m_reply->rawHeaderPairs(); -#else - m_rawHeaderPairs.clear(); - foreach (const QByteArray& headerName, m_reply->rawHeaderList()) - m_rawHeaderPairs.append(RawHeaderPair(headerName, m_reply->rawHeader(headerName))); -#endif -} - -void QtNetworkReplyThreadSafeProxy::localSetReply(QNetworkReply *reply) -{ - ASSERT(!m_reply); - m_reply = reply; - m_reply->setParent(0); - connect(m_reply, SIGNAL(readyRead()), this, SLOT(localForwardData())); - // Make sure localMirrorMembers() is called before the outward signal - connect(m_reply, SIGNAL(finished()), this, SLOT(localMirrorMembers()), Qt::DirectConnection); - connect(m_reply, SIGNAL(finished()), this, SIGNAL(finished())); - // Make sure localMirrorMembers() is called before the outward signal - connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(localMirrorMembers()), Qt::DirectConnection); - connect(m_reply, SIGNAL(metaDataChanged()), this, SIGNAL(metaDataChanged())); - connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SIGNAL(uploadProgress(qint64, qint64))); -} - - -} diff --git a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h deleted file mode 100644 index 4906fe2..0000000 --- a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef QtNAMThreadSafeProxy_h -#define QtNAMThreadSafeProxy_h - -#include <QMutex> -#include <QNetworkCookie> -#include <QNetworkReply> -#include <QObject> -#include <QWaitCondition> - -QT_BEGIN_NAMESPACE -class QNetworkAccessManager; -class QNetworkRequest; -class QUrl; -QT_END_NAMESPACE - -namespace WebCore { - -class QtNAMThreadSafeProxy : public QObject { - Q_OBJECT -public: - QtNAMThreadSafeProxy(QNetworkAccessManager *manager); - - void setCookies(const QUrl& url, const QString& cookies) - { - emit localSetCookiesRequested(url, cookies); - } - - QList<QNetworkCookie> cookiesForUrl(const QUrl& url) - { - bool done = false; - QList<QNetworkCookie> result; - emit localCookiesForUrlRequested(url, &done, &result); - - QMutexLocker lock(&m_resultMutex); - while (!done) - m_resultWaitCondition.wait(&m_resultMutex); - return result; - } - - bool willLoadFromCache(const QUrl& url) - { - bool done = false; - bool result; - emit localWillLoadFromCacheRequested(url, &done, &result); - - QMutexLocker lock(&m_resultMutex); - while (!done) - m_resultWaitCondition.wait(&m_resultMutex); - return result; - } - - bool hasCookieJar(); - -signals: - void localSetCookiesRequested(const QUrl&, const QString& cookies); - void localCookiesForUrlRequested(const QUrl&, bool* done, QList<QNetworkCookie>* result); - void localWillLoadFromCacheRequested(const QUrl&, bool* done, bool* result); - void hasCookieJarRequested(bool* done, bool* result); - -private slots: - void localSetCookies(const QUrl&, const QString& cookies); - void localCookiesForUrl(const QUrl&, bool* done, QList<QNetworkCookie>* result); - void localWillLoadFromCache(const QUrl&, bool* done, bool* result); - void hasCookieJar(bool* done, bool* result); - -private: - QNetworkAccessManager* m_manager; - QMutex m_resultMutex; - QWaitCondition m_resultWaitCondition; -}; - - -class QtNetworkReplyThreadSafeProxy : public QObject { - Q_OBJECT -public: - typedef QPair<QByteArray, QByteArray> RawHeaderPair; - QtNetworkReplyThreadSafeProxy(QNetworkAccessManager *manager); - ~QtNetworkReplyThreadSafeProxy(); - void abort() - { - emit localAbortRequested(); - } - void setForwardingDefered(bool forwardingDefered) - { - emit localSetForwardingDeferedRequested(forwardingDefered); - } - - QByteArray contentDispositionHeader() { QMutexLocker lock(&m_mirroredMembersMutex); return m_contentDispositionHeader; } - qlonglong contentLengthHeader() { QMutexLocker lock(&m_mirroredMembersMutex); return m_contentLengthHeader; } - QString contentTypeHeader() { QMutexLocker lock(&m_mirroredMembersMutex); return m_contentTypeHeader; } - QNetworkReply::NetworkError error() { QMutexLocker lock(&m_mirroredMembersMutex); return m_error; } - QString errorString() { QMutexLocker lock(&m_mirroredMembersMutex); return m_errorString; } - QByteArray httpReasonPhrase() { QMutexLocker lock(&m_mirroredMembersMutex); return m_httpReasonPhrase; } - int httpStatusCode() { QMutexLocker lock(&m_mirroredMembersMutex); return m_httpStatusCode; } - QUrl url() { QMutexLocker lock(&m_mirroredMembersMutex); return m_url; } - QUrl redirectionTarget() { QMutexLocker lock(&m_mirroredMembersMutex); return m_redirectionTarget; } - QList<RawHeaderPair> rawHeaderPairs() { QMutexLocker lock(&m_mirroredMembersMutex); return m_rawHeaderPairs; } - - QNetworkReply* reply() - { - // Careful, acccessing the reply accross threads might be hazardous to your health - return m_reply; - } -public: - void get(const QNetworkRequest &request) - { - emit localGetRequested(request); - } - void post(const QNetworkRequest &request, QIODevice* data) - { - emit localPostRequested(request, data); - } - void head(const QNetworkRequest &request) - { - emit localHeadRequested(request); - } - void put(const QNetworkRequest &request, QIODevice* data) - { - emit localPutRequested(request, data); - } - void deleteResource(const QNetworkRequest &request) - { - emit localDeleteResourceRequested(request); - } -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - void sendCustomRequest(const QNetworkRequest &request, const QByteArray& verb) - { - emit localCustomRequestRequested(request, verb); - } -#endif - -signals: - void localGetRequested(const QNetworkRequest& request); - void localPostRequested(const QNetworkRequest& request, QIODevice* data); - void localHeadRequested(const QNetworkRequest& request); - void localPutRequested(const QNetworkRequest& request, QIODevice* data); - void localDeleteResourceRequested(const QNetworkRequest& request); - void localCustomRequestRequested(const QNetworkRequest& request, const QByteArray& verb); - void localAbortRequested(); - void localSetForwardingDeferedRequested(bool forwardingDefered); - - void finished(); - void readyRead(); - void metaDataChanged(); - void uploadProgress(qint64 bytesSent, qint64 bytesTotal); - void dataReceived(const QByteArray &data); - -private slots: - void localGet(const QNetworkRequest& request); - void localPost(const QNetworkRequest& request, QIODevice* data); - void localHead(const QNetworkRequest& request); - void localPut(const QNetworkRequest& request, QIODevice* data); - void localDeleteResource(const QNetworkRequest& request); - void localCustomRequest(const QNetworkRequest& request, const QByteArray& verb); - void localAbort(); - void localForwardData(); - void localSetForwardingDefered(bool forwardingDefered); - void localMirrorMembers(); - -private: - void localSetReply(QNetworkReply *reply); - - QNetworkAccessManager *m_manager; - QNetworkReply *m_reply; - bool m_forwardingDefered; - - // Mirrored members - QMutex m_mirroredMembersMutex; - QByteArray m_contentDispositionHeader; - qlonglong m_contentLengthHeader; - QString m_contentTypeHeader; - QNetworkReply::NetworkError m_error; - QString m_errorString; - QByteArray m_httpReasonPhrase; - int m_httpStatusCode; - QUrl m_url; - QUrl m_redirectionTarget; - QList<RawHeaderPair> m_rawHeaderPairs; -}; - -} - - -#endif // QtNAMThreadSafeProxy_h diff --git a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp index 56125b7..cd17660 100644 --- a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp +++ b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp @@ -35,7 +35,6 @@ #include "Frame.h" #include "FrameNetworkingContext.h" #include "FrameLoaderClientQt.h" -#include "QtNAMThreadSafeProxy.h" #include "NotImplemented.h" #include "Page.h" #include "QNetworkReplyHandler.h" @@ -70,14 +69,18 @@ public: ResourceError resourceError() const { return m_error; } Vector<char> data() const { return m_data; } + void setReplyFinished(bool finished) { m_replyFinished = finished; } + private: ResourceResponse m_response; ResourceError m_error; Vector<char> m_data; QEventLoop m_eventLoop; + bool m_replyFinished; }; WebCoreSynchronousLoader::WebCoreSynchronousLoader() + : m_replyFinished(false) { } @@ -93,13 +96,15 @@ void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) { - m_eventLoop.exit(); + if (!m_replyFinished) + m_eventLoop.exit(); } void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error) { m_error = error; - m_eventLoop.exit(); + if (!m_replyFinished) + m_eventLoop.exit(); } void WebCoreSynchronousLoader::waitForCompletion() @@ -157,13 +162,20 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame) if (!frame) return false; + QNetworkAccessManager* manager = 0; + QAbstractNetworkCache* cache = 0; if (frame->loader()->networkingContext()) { - QNetworkAccessManager* manager = frame->loader()->networkingContext()->networkAccessManager(); - QtNAMThreadSafeProxy managerProxy(manager); - if (managerProxy.willLoadFromCache(request.url())) { - request.setCachePolicy(ReturnCacheDataDontLoad); - return true; - } + manager = frame->loader()->networkingContext()->networkAccessManager(); + cache = manager->cache(); + } + + if (!cache) + return false; + + QNetworkCacheMetaData data = cache->metaData(request.url()); + if (data.isValid()) { + request.setCachePolicy(ReturnCacheDataDontLoad); + return true; } return false; @@ -195,9 +207,17 @@ void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const d->m_firstRequest.setURL(urlWithCredentials); } d->m_context = context; - d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::LoadNormal); + d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::LoadSynchronously); + + QNetworkReply* reply = d->m_job->reply(); + // When using synchronous calls, we are finished when reaching this point. + if (reply->isFinished()) { + syncLoader.setReplyFinished(true); + d->m_job->forwardData(); + d->m_job->finish(); + } else + syncLoader.waitForCompletion(); - syncLoader.waitForCompletion(); error = syncLoader.resourceError(); data = syncLoader.data(); response = syncLoader.resourceResponse(); diff --git a/Source/WebCore/platform/network/soup/CookieJarSoup.cpp b/Source/WebCore/platform/network/soup/CookieJarSoup.cpp index e2c2f05..f73a616 100644 --- a/Source/WebCore/platform/network/soup/CookieJarSoup.cpp +++ b/Source/WebCore/platform/network/soup/CookieJarSoup.cpp @@ -122,4 +122,19 @@ void deleteCookie(const Document*, const KURL&, const String&) // FIXME: Not yet implemented } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp index 3b1f157..d410fa3 100644 --- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp +++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp @@ -171,9 +171,11 @@ static void ensureSessionIsInitialized(SoupSession* session) g_object_unref(logger); } - SoupRequester* requester = soup_requester_new(); - soup_session_add_feature(session, SOUP_SESSION_FEATURE(requester)); - g_object_unref(requester); + if (!soup_session_get_feature(session, SOUP_TYPE_REQUESTER)) { + SoupRequester* requester = soup_requester_new(); + soup_session_add_feature(session, SOUP_SESSION_FEATURE(requester)); + g_object_unref(requester); + } g_object_set(session, SOUP_SESSION_MAX_CONNS, maxConnections, @@ -362,7 +364,7 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data) ASSERT(!d->m_response.isNull()); - client->didReceiveData(handle.get(), chunk->data, chunk->length, false); + client->didReceiveData(handle.get(), chunk->data, chunk->length, chunk->length); } static SoupSession* createSoupSession() @@ -453,7 +455,7 @@ static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer use // response_body->data as libsoup always creates the // SoupBuffer for the body even if the length is 0 if (!d->m_cancelled && soupMsg->response_body->length) - client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, true); + client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, soupMsg->response_body->length); } // didReceiveData above might have cancelled it @@ -473,7 +475,6 @@ static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer use d->m_inputStream = adoptGRef(in); d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE)); - d->m_total = 0; // readCallback needs it g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle.get()); @@ -698,10 +699,14 @@ void ResourceHandle::platformSetDefersLoading(bool defersLoading) if (!d->m_soupMessage) return; + SoupMessage* soupMessage = d->m_soupMessage.get(); + if (soupMessage->status_code != SOUP_STATUS_NONE) + return; + if (defersLoading) - soup_session_pause_message(defaultSession(), d->m_soupMessage.get()); + soup_session_pause_message(defaultSession(), soupMessage); else - soup_session_unpause_message(defaultSession(), d->m_soupMessage.get()); + soup_session_unpause_message(defaultSession(), soupMessage); } bool ResourceHandle::loadsBlocked() @@ -783,13 +788,12 @@ static void readCallback(GObject* source, GAsyncResult* asyncResult, gpointer da // It's mandatory to have sent a response before sending data ASSERT(!d->m_response.isNull()); - d->m_total += bytesRead; if (G_LIKELY(!convertToUTF16)) - client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total); + client->didReceiveData(handle.get(), d->m_buffer, bytesRead, bytesRead); else { // We have to convert it to UTF-16 due to limitations in KURL String data = String::fromUTF8(d->m_buffer, bytesRead); - client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0); + client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), bytesRead); } // didReceiveData may cancel the load, which may release the last reference. diff --git a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp index 5016bf1..a684790 100644 --- a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp +++ b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp @@ -89,13 +89,14 @@ void ResourceRequest::updateFromSoupMessage(SoupMessage* soupMessage) m_httpMethod = String::fromUTF8(soupMessage->method); + m_httpHeaderFields.clear(); SoupMessageHeadersIter headersIter; const char* headerName; const char* headerValue; - soup_message_headers_iter_init(&headersIter, soupMessage->request_headers); - while (soup_message_headers_iter_next(&headersIter, &headerName, &headerValue)) + while (soup_message_headers_iter_next(&headersIter, &headerName, &headerValue)) { m_httpHeaderFields.set(String::fromUTF8(headerName), String::fromUTF8(headerValue)); + } if (soupMessage->request_body->data) m_httpBody = FormData::create(soupMessage->request_body->data, soupMessage->request_body->length); diff --git a/Source/WebCore/platform/network/win/CookieJarWin.cpp b/Source/WebCore/platform/network/win/CookieJarWin.cpp index a2afbc6..2820010 100644 --- a/Source/WebCore/platform/network/win/CookieJarWin.cpp +++ b/Source/WebCore/platform/network/win/CookieJarWin.cpp @@ -86,4 +86,19 @@ void deleteCookie(const Document*, const KURL&, const String&) // FIXME: Not yet implemented } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/network/win/CookieStorageWin.cpp b/Source/WebCore/platform/network/win/CookieStorageWin.cpp new file mode 100644 index 0000000..c1ec33d --- /dev/null +++ b/Source/WebCore/platform/network/win/CookieStorageWin.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> + * + * 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 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. + */ + +#include "config.h" +#include "CookieStorage.h" + +#include "NotImplemented.h" + +namespace WebCore { + +void setCookieStoragePrivateBrowsingEnabled(bool) +{ + notImplemented(); +} + +} // namespace WebCore |