Reviewed by Adam Roben.
authorap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Feb 2011 22:47:03 +0000 (22:47 +0000)
committerap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Feb 2011 22:47:03 +0000 (22:47 +0000)
        REGRESSION (WebKit2): HTTP requests time out after 60 seconds
        https://bugs.webkit.org/show_bug.cgi?id=54755
        <rdar://problem/9006592>

WebCore:
        It's now possible to set a default timeout to be used at ResourceRequest creation. If one
        hasn't been set, ResourceRequest will behave as before (use NSURLRequest default on Mac,
        or use INT_MAX on other platforms).

        * WebCore.exp.in:
        * platform/network/ResourceRequestBase.cpp:
        (WebCore::ResourceRequestBase::defaultTimeoutInterval): Get the ResourceRequest notion of
        default timeout interval (may be 0 if using NSURLRequest default).
        (WebCore::ResourceRequestBase::setDefaultTimeoutInterval): Set the static member variable.
        (WebCore::ResourceRequestBase::updatePlatformRequest): Added an assertion that resource
        request is updated. Plaform code often calls updateResourceRequest() indirectly from this
        function, and that must obviously be a no-op.
        (WebCore::ResourceRequestBase::updateResourceRequest): Added an assertion in the opposite
        direction.
        * platform/network/ResourceRequestBase.h: Changed "unspecifiedTimeoutInterval" to
        "defaultTimeoutInterval". It has been used as default by most platforms anyway.
        (WebCore::ResourceRequestBase::ResourceRequestBase):

        * platform/network/mac/ResourceRequestMac.mm: (WebCore::ResourceRequest::doUpdatePlatformRequest):
        Now zero is the magic value, not INT_MAX. We'll use NSURLRequest default if neither
        setTimeoutInterval() nor setDefaultTimeoutInterval() has been called.

WebKit2:
        * Shared/API/c/WKURLRequest.cpp:
        (WKURLRequestSetDefaultTimeoutInterval):
        * Shared/API/c/WKURLRequest.h:
        Added an API to set a default timeout interval for requests created from URLs. The API
        affects both the UI process and requests created internally by the Web process. Requests
        created from NSURLRequest or CFURLRequest take timeout from those.

        * Shared/WebURLRequest.cpp: (WebKit::WebURLRequest::setDefaultTimeoutInterval):
        * Shared/WebURLRequest.h:
        Pipe the default timeout interval from WKURLRequest down to actual implementation. Since
        WebURLRequest is currently implemented with WebCore::ResourceRequest, it automatically respects
        NSURLRequest default timeout interval.

        * UIProcess/WebProcessManager.cpp: (WebKit::WebProcessManager::getAllWebProcessContexts):
        * UIProcess/WebProcessManager.h:
        Added a way to enumerate all contexts running in separate processes.

        * Shared/WebProcessCreationParameters.cpp:
        (WebKit::WebProcessCreationParameters::WebProcessCreationParameters):
        (WebKit::WebProcessCreationParameters::encode):
        (WebKit::WebProcessCreationParameters::decode):
        * Shared/WebProcessCreationParameters.h:
        (WebKit::WebContext::ensureWebProcess):
        (WebKit::WebContext::setDefaultRequestTimeoutInterval):
        * UIProcess/WebContext.h:
        * WebProcess/WebProcess.cpp:
        (WebKit::WebProcess::initializeWebProcess):
        (WebKit::WebProcess::setDefaultRequestTimeoutInterval):
        * WebProcess/WebProcess.h:
        * WebProcess/WebProcess.messages.in:
        Use UI process default timeout interval in separate process contexts, too.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@79253 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/platform/network/ResourceRequestBase.cpp
Source/WebCore/platform/network/ResourceRequestBase.h
Source/WebCore/platform/network/mac/ResourceRequestMac.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKURLRequest.cpp
Source/WebKit2/Shared/API/c/WKURLRequest.h
Source/WebKit2/Shared/WebProcessCreationParameters.cpp
Source/WebKit2/Shared/WebProcessCreationParameters.h
Source/WebKit2/Shared/WebURLRequest.cpp
Source/WebKit2/Shared/WebURLRequest.h
Source/WebKit2/UIProcess/WebContext.cpp
Source/WebKit2/UIProcess/WebContext.h
Source/WebKit2/UIProcess/WebProcessManager.cpp
Source/WebKit2/UIProcess/WebProcessManager.h
Source/WebKit2/WebProcess/WebProcess.cpp
Source/WebKit2/WebProcess/WebProcess.h
Source/WebKit2/WebProcess/WebProcess.messages.in

index 9ffe138..40f5876 100644 (file)
@@ -1,3 +1,35 @@
+2011-02-21  Alexey Proskuryakov  <ap@apple.com>
+
+        Reviewed by Adam Roben.
+
+        REGRESSION (WebKit2): HTTP requests time out after 60 seconds
+        https://bugs.webkit.org/show_bug.cgi?id=54755
+        <rdar://problem/9006592>
+
+        No new tests - it won't be great to have a test that runs for a minute.
+
+        It's now possible to set a default timeout to be used at ResourceRequest creation. If one
+        hasn't been set, ResourceRequest will behave as before (use NSURLRequest default on Mac,
+        or use INT_MAX on other platforms).
+
+        * WebCore.exp.in:
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::defaultTimeoutInterval): Get the ResourceRequest notion of
+        default timeout interval (may be 0 if using NSURLRequest default).
+        (WebCore::ResourceRequestBase::setDefaultTimeoutInterval): Set the static member variable.
+        (WebCore::ResourceRequestBase::updatePlatformRequest): Added an assertion that resource
+        request is updated. Plaform code often calls updateResourceRequest() indirectly from this
+        function, and that must obviously be a no-op.
+        (WebCore::ResourceRequestBase::updateResourceRequest): Added an assertion in the opposite
+        direction.
+        * platform/network/ResourceRequestBase.h: Changed "unspecifiedTimeoutInterval" to
+        "defaultTimeoutInterval". It has been used as default by most platforms anyway.
+        (WebCore::ResourceRequestBase::ResourceRequestBase):
+
+        * platform/network/mac/ResourceRequestMac.mm: (WebCore::ResourceRequest::doUpdatePlatformRequest):
+        Now zero is the magic value, not INT_MAX. We'll use NSURLRequest default if neither
+        setTimeoutInterval() nor setDefaultTimeoutInterval() has been called.
+
 2011-02-21  Martin Robinson  <mrobinson@igalia.com>
 
         Reviewed by Xan Lopez.
index 8461cad..2002bb9 100644 (file)
@@ -492,6 +492,9 @@ __ZN7WebCore19CSSStyleDeclaration11setPropertyERKN3WTF6StringES4_Ri
 __ZN7WebCore19ResourceRequestBase11setHTTPBodyEN3WTF10PassRefPtrINS_8FormDataEEE
 __ZN7WebCore19ResourceRequestBase13setHTTPMethodERKN3WTF6StringE
 __ZN7WebCore19ResourceRequestBase19addHTTPHeaderFieldsERKNS_13HTTPHeaderMapE
+__ZN7WebCore19ResourceRequestBase22defaultTimeoutIntervalEv
+__ZN7WebCore19ResourceRequestBase24s_defaultTimeoutIntervalE
+__ZN7WebCore19ResourceRequestBase25setDefaultTimeoutIntervalEd
 __ZN7WebCore19ResourceRequestBase6setURLERKNS_4KURLE
 __ZN7WebCore19SelectionController10setFocusedEb
 __ZN7WebCore19SelectionController12setSelectionERKNS_16VisibleSelectionEjNS0_19CursorAlignOnScrollENS_15TextGranularityENS_20DirectionalityPolicyE
index ba58461..6a554fe 100644 (file)
@@ -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;
 }
index 9cc9148..bf53010 100644 (file)
@@ -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&);
index 640d237..099fe93 100644 (file)
 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()];
index 608a6e5..a5d4d44 100644 (file)
@@ -1,3 +1,43 @@
+2011-02-21  Alexey Proskuryakov  <ap@apple.com>
+
+        Reviewed by Adam Roben.
+
+        REGRESSION (WebKit2): HTTP requests time out after 60 seconds
+        https://bugs.webkit.org/show_bug.cgi?id=54755
+        <rdar://problem/9006592>
+
+        * Shared/API/c/WKURLRequest.cpp:
+        (WKURLRequestSetDefaultTimeoutInterval):
+        * Shared/API/c/WKURLRequest.h:
+        Added an API to set a default timeout interval for requests created from URLs. The API
+        affects both the UI process and requests created internally by the Web process. Requests
+        created from NSURLRequest or CFURLRequest take timeout from those.
+
+        * Shared/WebURLRequest.cpp: (WebKit::WebURLRequest::setDefaultTimeoutInterval):
+        * Shared/WebURLRequest.h:
+        Pipe the default timeout interval from WKURLRequest down to actual implementation. Since
+        WebURLRequest is currently implemented with WebCore::ResourceRequest, it automatically respects
+        NSURLRequest default timeout interval.
+
+        * UIProcess/WebProcessManager.cpp: (WebKit::WebProcessManager::getAllWebProcessContexts):
+        * UIProcess/WebProcessManager.h:
+        Added a way to enumerate all contexts running in separate processes.
+
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::WebProcessCreationParameters):
+        (WebKit::WebProcessCreationParameters::encode):
+        (WebKit::WebProcessCreationParameters::decode):
+        * Shared/WebProcessCreationParameters.h:
+        (WebKit::WebContext::ensureWebProcess):
+        (WebKit::WebContext::setDefaultRequestTimeoutInterval):
+        * UIProcess/WebContext.h:
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::initializeWebProcess):
+        (WebKit::WebProcess::setDefaultRequestTimeoutInterval):
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in:
+        Use UI process default timeout interval in separate process contexts, too.
+
 2011-02-18  Brian Weinstein  <bweinstein@apple.com>
 
         Reviewed by Adam Roben.
index 433db05..776367b 100644 (file)
@@ -47,3 +47,8 @@ WKURLRef WKURLRequestCopyURL(WKURLRequestRef requestRef)
 {
     return toCopiedURLAPI(toImpl(requestRef)->url());
 }
+
+void WKURLRequestSetDefaultTimeoutInterval(double timeoutInterval)
+{
+    WebURLRequest::setDefaultTimeoutInterval(timeoutInterval);
+}
index 7d146f2..a53ce16 100644 (file)
@@ -38,6 +38,8 @@ WK_EXPORT WKURLRequestRef WKURLRequestCreateWithWKURL(WKURLRef);
 
 WK_EXPORT WKURLRef WKURLRequestCopyURL(WKURLRequestRef);
 
+WK_EXPORT void WKURLRequestSetDefaultTimeoutInterval(double);
+
 #ifdef __cplusplus
 }
 #endif
index a2014cb..d4121f7 100644 (file)
@@ -33,6 +33,7 @@ namespace WebKit {
 WebProcessCreationParameters::WebProcessCreationParameters()
     : shouldTrackVisitedLinks(false)
     , shouldAlwaysUseComplexTextCodePath(false)
+    , defaultRequestTimeoutInterval(INT_MAX)
 #if PLATFORM(MAC)
     , nsURLCacheMemoryCapacity(0)
     , nsURLCacheDiskCapacity(0)
@@ -57,6 +58,7 @@ void WebProcessCreationParameters::encode(CoreIPC::ArgumentEncoder* encoder) con
     encoder->encode(shouldAlwaysUseComplexTextCodePath);
     encoder->encode(languageCode);
     encoder->encode(textCheckerState);
+    encoder->encode(defaultRequestTimeoutInterval);
 #if PLATFORM(MAC)
     encoder->encode(parentProcessName);
     encoder->encode(presenterApplicationPid);
@@ -101,6 +103,8 @@ bool WebProcessCreationParameters::decode(CoreIPC::ArgumentDecoder* decoder, Web
         return false;
     if (!decoder->decode(parameters.textCheckerState))
         return false;
+    if (!decoder->decode(parameters.defaultRequestTimeoutInterval))
+        return false;
 
 #if PLATFORM(MAC)
     if (!decoder->decode(parameters.parentProcessName))
index 7b25740..a0388b7 100644 (file)
@@ -73,6 +73,8 @@ struct WebProcessCreationParameters {
 
     TextCheckerState textCheckerState;
 
+    double defaultRequestTimeoutInterval;
+
 #if PLATFORM(MAC)
     String parentProcessName;
 
index 586bbb4..0525ea7 100644 (file)
@@ -10,6 +10,9 @@
 #include "config.h"
 #include "WebURLRequest.h"
 
+#include "WebContext.h"
+#include "WebProcessManager.h"
+
 using namespace WebCore;
 
 namespace WebKit {
@@ -24,4 +27,19 @@ WebURLRequest::WebURLRequest(const ResourceRequest& request)
 {
 }
 
+double WebURLRequest::defaultTimeoutInterval()
+{
+    return ResourceRequest::defaultTimeoutInterval();
+}
+
+void WebURLRequest::setDefaultTimeoutInterval(double timeoutInterval)
+{
+    ResourceRequest::setDefaultTimeoutInterval(timeoutInterval);
+    
+    Vector<WebContext*> contexts;
+    WebProcessManager::shared().getAllWebProcessContexts(contexts);
+    for (unsigned i = 0; i < contexts.size(); ++i)
+        contexts[i]->setDefaultRequestTimeoutInterval(timeoutInterval);
+}
+
 } // namespace WebKit
index ab167b8..a3a5931 100644 (file)
@@ -61,6 +61,9 @@ public:
 
     const String& url() const { return m_request.url(); }
 
+    static double defaultTimeoutInterval(); // May return 0 when using platform default.
+    static void setDefaultTimeoutInterval(double);
+
 private:
     explicit WebURLRequest(const WebCore::ResourceRequest&);
     explicit WebURLRequest(PlatformRequest);
index ffef45a..4c449a4 100644 (file)
@@ -207,6 +207,8 @@ void WebContext::ensureWebProcess()
 
     parameters.textCheckerState = TextChecker::state();
 
+    parameters.defaultRequestTimeoutInterval = WebURLRequest::defaultTimeoutInterval();
+
     // Add any platform specific parameters
     platformInitializeWebProcess(parameters);
 
@@ -423,6 +425,14 @@ void WebContext::setCacheModel(CacheModel cacheModel)
     m_process->send(Messages::WebProcess::SetCacheModel(static_cast<uint32_t>(m_cacheModel)), 0);
 }
 
+void WebContext::setDefaultRequestTimeoutInterval(double timeoutInterval)
+{
+    if (!hasValidProcess())
+        return;
+
+    m_process->send(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval), 0);
+}
+
 void WebContext::addVisitedLink(const String& visitedURL)
 {
     if (visitedURL.isEmpty())
index fe272b9..ff590f2 100644 (file)
@@ -113,7 +113,9 @@ public:
     CacheModel cacheModel() const { return m_cacheModel; }
     void clearResourceCaches();
     void clearApplicationCache();
-    
+
+    void setDefaultRequestTimeoutInterval(double);
+
     void startMemorySampler(const double interval);
     void stopMemorySampler();
 
index 80e3c2d..0d44f8b 100644 (file)
@@ -69,6 +69,11 @@ WebProcessProxy* WebProcessManager::getWebProcess(WebContext* context)
     return 0;
 }
 
+void WebProcessManager::getAllWebProcessContexts(Vector<WebContext*>& contexts)
+{
+    copyKeysToVector(m_processMap, contexts);
+}
+
 void WebProcessManager::processDidClose(WebProcessProxy* process, WebContext* context)
 {
     if (process == m_sharedProcess) {
index 320829e..a636e5c 100644 (file)
@@ -41,6 +41,8 @@ public:
 
     void contextWasDestroyed(WebContext*);
 
+    void getAllWebProcessContexts(Vector<WebContext*>&);
+
 private:
     WebProcessManager();
 
index cae2872..f1a3d7c 100644 (file)
@@ -190,6 +190,8 @@ void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parame
     for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i)
         setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]);
 
+    setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval);
+
     for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i)
         m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]);
 
@@ -226,6 +228,11 @@ void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlSchem
     SecurityOrigin::setDomainRelaxationForbiddenForURLScheme(true, urlScheme);
 }
 
+void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval)
+{
+    ResourceRequest::setDefaultTimeoutInterval(timeoutInterval);
+}
+
 void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
 {
     WebCore::Font::setCodePath(alwaysUseComplexText ? WebCore::Font::Complex : WebCore::Font::Auto);
index 43c370f..d830871 100644 (file)
@@ -126,6 +126,7 @@ private:
     void registerURLSchemeAsEmptyDocument(const String&);
     void registerURLSchemeAsSecure(const String&) const;
     void setDomainRelaxationForbiddenForURLScheme(const String&) const;
+    void setDefaultRequestTimeoutInterval(double);
     void setAlwaysUsesComplexTextCodePath(bool);
     void languageChanged(const String&) const;
 #if PLATFORM(WIN)
index 449164a..e297179 100644 (file)
@@ -38,6 +38,7 @@ messages -> WebProcess {
     RegisterURLSchemeAsEmptyDocument(WTF::String scheme)
     RegisterURLSchemeAsSecure(WTF::String scheme)
     SetDomainRelaxationForbiddenForURLScheme(WTF::String scheme)
+    SetDefaultRequestTimeoutInterval(double timeoutInterval)
     SetAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
     LanguageChanged(WTF::String language)
 #if PLATFORM(WIN)