Changeset 210374 in webkit
- Timestamp:
- Jan 5, 2017 1:27:50 PM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 1 added
- 2 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r210372 r210374 1 2017-01-05 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [SOUP] Network process crash in WebKit::CustomProtocolManagerImpl::didFailWithError 4 https://bugs.webkit.org/show_bug.cgi?id=165082 5 6 Reviewed by Alex Christensen. 7 8 Simplified WebKitSoupRequestGenericClient. 9 10 * platform/network/soup/WebKitSoupRequestGeneric.cpp: 11 (webkitSoupRequestGenericSendAsync): 12 (webkitSoupRequestGenericSendFinish): 13 (webkitSoupRequestGenericGetRequest): 14 * platform/network/soup/WebKitSoupRequestGeneric.h: 15 * platform/network/soup/WebKitSoupRequestGenericClient.h: 16 1 17 2017-01-05 Chris Dumez <cdumez@apple.com> 2 18 -
trunk/Source/WebCore/platform/network/soup/WebKitSoupRequestGeneric.cpp
r185774 r210374 51 51 WebKitSoupRequestGenericClient* client = WEBKIT_SOUP_REQUEST_GENERIC_GET_CLASS(request)->client; 52 52 ASSERT(client); 53 client->start (g_task_new(request, cancellable, callback, userData));53 client->startRequest(adoptGRef(g_task_new(request, cancellable, callback, userData))); 54 54 } 55 55 … … 57 57 { 58 58 g_return_val_if_fail(g_task_is_valid(result, request), nullptr); 59 WebKitSoupRequestGenericClient* client = WEBKIT_SOUP_REQUEST_GENERIC_GET_CLASS(request)->client; 60 ASSERT(client); 61 return client->finish(G_TASK(result), error); 59 auto* inputStream = g_task_propagate_pointer(G_TASK(result), error); 60 return inputStream ? G_INPUT_STREAM(inputStream) : nullptr; 62 61 } 63 62 … … 101 100 } 102 101 103 const ResourceRequest *webkitSoupRequestGenericGetRequest(WebKitSoupRequestGeneric* request)102 const ResourceRequest& webkitSoupRequestGenericGetRequest(WebKitSoupRequestGeneric* request) 104 103 { 105 return &request->priv->resourceRequest;104 return request->priv->resourceRequest; 106 105 } -
trunk/Source/WebCore/platform/network/soup/WebKitSoupRequestGeneric.h
r185774 r210374 59 59 void webkitSoupRequestGenericSetContentType(WebKitSoupRequestGeneric*, const char* mimeType); 60 60 void webkitSoupRequestGenericSetRequest(WebKitSoupRequestGeneric*, const WebCore::ResourceRequest&); 61 const WebCore::ResourceRequest *webkitSoupRequestGenericGetRequest(WebKitSoupRequestGeneric*);61 const WebCore::ResourceRequest& webkitSoupRequestGenericGetRequest(WebKitSoupRequestGeneric*); 62 62 63 63 G_END_DECLS -
trunk/Source/WebCore/platform/network/soup/WebKitSoupRequestGenericClient.h
r185551 r210374 18 18 */ 19 19 20 #ifndef WebKitSoupRequestGenericClient_h 21 #define WebKitSoupRequestGenericClient_h 20 #pragma once 22 21 23 typedef struct _GError GError; 24 typedef struct _GInputStream GInputStream; 22 #include <wtf/glib/GRefPtr.h> 23 25 24 typedef struct _GTask GTask; 26 25 … … 29 28 class WebKitSoupRequestGenericClient { 30 29 public: 31 virtual void start(GTask*) = 0; 32 virtual GInputStream* finish(GTask*, GError**) = 0; 30 virtual void startRequest(GRefPtr<GTask>&&) = 0; 33 31 }; 34 32 35 33 } // namespace WebCore 36 34 37 #endif // WebKitSoupRequestGenericClient_h -
trunk/Source/WebKit2/CMakeLists.txt
r209665 r210374 94 94 95 95 set(NetworkProcess_COMMON_SOURCES 96 NetworkProcess/CustomProtocols/CustomProtocolManager.cpp 97 96 98 NetworkProcess/NetworkConnectionToWebProcess.cpp 97 99 NetworkProcess/NetworkDataTask.cpp -
trunk/Source/WebKit2/ChangeLog
r210364 r210374 1 2017-01-05 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [SOUP] Network process crash in WebKit::CustomProtocolManagerImpl::didFailWithError 4 https://bugs.webkit.org/show_bug.cgi?id=165082 5 6 Reviewed by Alex Christensen. 7 8 CustomProtocolManager uses a Workqueue to receive the IPC messages since r149194. Then we added the Soup 9 implementation adopting that approach, but without making our implementation thread safe. The crash happens 10 because the CustomProtocolManager implementation is used by two threads at the same time, the main thread 11 because of a ping load (probably caused by an image load in the unload handler, I haven't been able to 12 reproduce the crash) and the work queue thread. The reasons to make CustomProtocolManager use a WorkQueue 13 are no longer valid because CustomProtocolManager is now only used in the network process and sync loads don't 14 use any nested run loop, they are just an IPC sync message. So this patch makes CustomProtocolManager a normal 15 message receiver again to ensure messages are handled in the main thread. It also adds the common implementation 16 to a new CustomProtocolManager.cpp file shared by Cocoa and Soup based ports. 17 18 * CMakeLists.txt: Add CustomProtocolManager.cpp. 19 * NetworkProcess/CustomProtocols/Cocoa/CustomProtocolManagerCocoa.mm: 20 (-[WKCustomProtocol initWithRequest:cachedResponse:client:]): Use new CustomProtocolManager API. 21 (-[WKCustomProtocol startLoading]): Ditto. 22 (-[WKCustomProtocol stopLoading]): Ditto. 23 (WebKit::CustomProtocolManager::registerProtocolClass): Register the NSURLProtocol class when not using the 24 network session. 25 (WebKit::CustomProtocolManager::didFailWithError): removeCustomProtocol now receives an ID. 26 (WebKit::CustomProtocolManager::didFinishLoading): Ditto. 27 * NetworkProcess/CustomProtocols/CustomProtocolManager.cpp: Added. 28 (WebKit::generateCustomProtocolID): Moved from CustomProtocolManagerCocoa.mm and CustomProtocolManagerSoup.cpp. 29 (WebKit::CustomProtocolManager::supplementName): Ditto. 30 (WebKit::CustomProtocolManager::CustomProtocolManager): Also removes the work queue initialization. 31 (WebKit::CustomProtocolManager::initialize): Copied and modernized the loop. 32 (WebKit::CustomProtocolManager::addCustomProtocol): Copied from CustomProtocolManagerCocoa.mm. 33 (WebKit::CustomProtocolManager::removeCustomProtocol): Ditto. 34 (WebKit::CustomProtocolManager::startLoading): Send the StartLoading message to the proxy. 35 (WebKit::CustomProtocolManager::stopLoading): Send the StopLoading message to the proxy. 36 * NetworkProcess/CustomProtocols/CustomProtocolManager.h: 37 * NetworkProcess/CustomProtocols/soup/CustomProtocolManagerImpl.cpp: Removed. 38 * NetworkProcess/CustomProtocols/soup/CustomProtocolManagerImpl.h: Removed. 39 * NetworkProcess/CustomProtocols/soup/CustomProtocolManagerSoup.cpp: Moved the implementation from 40 CustomProtocolManagerImpl and updated to the new CustomProtocolManager API. 41 (WebKit::CustomProtocolManager::WebSoupRequestAsyncData::WebSoupRequestAsyncData): 42 (WebKit::CustomProtocolManager::WebSoupRequestAsyncData::~WebSoupRequestAsyncData): 43 (WebKit::CustomProtocolManager::registerProtocolClass): 44 (WebKit::CustomProtocolManager::registerScheme): 45 (WebKit::CustomProtocolManager::supportsScheme): 46 (WebKit::CustomProtocolManager::didFailWithError): 47 (WebKit::CustomProtocolManager::didLoadData): 48 (WebKit::CustomProtocolManager::didReceiveResponse): 49 (WebKit::CustomProtocolManager::didFinishLoading): 50 (WebKit::CustomProtocolManager::wasRedirectedToRequest): 51 * NetworkProcess/cocoa/NetworkSessionCocoa.mm: 52 (WebKit::globalCustomProtocolManager): 53 (WebKit::NetworkSessionCocoa::defaultSession): 54 CustomProtocolManager is no longer refcounted, so just pass a pointer. 55 A static pointer has the same lifetime as the NetworkProcess object in the NetworkProcess, 56 and in the WebProcess it will remain nullptr, just like it used to. 57 * PlatformEfl.cmake: 58 * PlatformGTK.cmake: 59 * WebKit2.xcodeproj/project.pbxproj: 60 1 61 2017-01-05 Antti Koivisto <antti@apple.com> 2 62 -
trunk/Source/WebKit2/NetworkProcess/CustomProtocols/Cocoa/CustomProtocolManagerCocoa.mm
r203174 r210374 27 27 #import "CustomProtocolManager.h" 28 28 29 #import "ChildProcess.h"30 29 #import "CustomProtocolManagerMessages.h" 31 #import "CustomProtocolManagerProxyMessages.h"32 30 #import "DataReference.h" 33 31 #import "NetworkProcess.h" 34 #import "NetworkProcessCreationParameters.h"35 #import "WebCoreArgumentCoders.h"36 #import "WebProcessCreationParameters.h"37 32 #import <Foundation/NSURLSession.h> 38 33 #import <WebCore/NSURLConnectionSPI.h> … … 45 40 using namespace WebKit; 46 41 47 namespace WebKit {48 49 static uint64_t generateCustomProtocolID()50 {51 static uint64_t uniqueCustomProtocolID = 0;52 return ++uniqueCustomProtocolID;53 }54 55 } // namespace WebKit56 57 42 @interface WKCustomProtocol : NSURLProtocol { 58 43 @private … … 90 75 if (!self) 91 76 return nil; 92 93 _customProtocolID = generateCustomProtocolID(); 77 78 if (auto* customProtocolManager = NetworkProcess::singleton().supplement<CustomProtocolManager>()) 79 _customProtocolID = customProtocolManager->addCustomProtocol(self); 94 80 _initializationRunLoop = CFRunLoopGetCurrent(); 81 82 return self; 83 } 84 85 - (CFRunLoopRef)initializationRunLoop 86 { 87 return _initializationRunLoop.get(); 88 } 89 90 - (void)startLoading 91 { 95 92 if (auto* customProtocolManager = NetworkProcess::singleton().supplement<CustomProtocolManager>()) 96 customProtocolManager->addCustomProtocol(self); 97 return self; 98 } 99 100 - (CFRunLoopRef)initializationRunLoop 101 { 102 return _initializationRunLoop.get(); 103 } 104 105 - (void)startLoading 106 { 107 if (auto* customProtocolManager = NetworkProcess::singleton().supplement<CustomProtocolManager>()) 108 customProtocolManager->childProcess()->send(Messages::CustomProtocolManagerProxy::StartLoading(self.customProtocolID, [self request]), 0); 93 customProtocolManager->startLoading(self.customProtocolID, [self request]); 109 94 } 110 95 … … 112 97 { 113 98 if (auto* customProtocolManager = NetworkProcess::singleton().supplement<CustomProtocolManager>()) { 114 customProtocolManager-> childProcess()->send(Messages::CustomProtocolManagerProxy::StopLoading(self.customProtocolID), 0);115 customProtocolManager->removeCustomProtocol(self );99 customProtocolManager->stopLoading(self.customProtocolID); 100 customProtocolManager->removeCustomProtocol(self.customProtocolID); 116 101 } 117 102 } … … 121 106 namespace WebKit { 122 107 123 const char* CustomProtocolManager::supplementName() 124 { 125 return "CustomProtocolManager"; 126 } 127 128 CustomProtocolManager::CustomProtocolManager(ChildProcess* childProcess) 129 : m_childProcess(childProcess) 130 , m_messageQueue(WorkQueue::create("com.apple.WebKit.CustomProtocolManager")) 131 { 132 WebCore::UTF8Encoding(); 133 } 134 135 void CustomProtocolManager::initializeConnection(IPC::Connection* connection) 136 { 137 connection->addWorkQueueMessageReceiver(Messages::CustomProtocolManager::messageReceiverName(), m_messageQueue.get(), this); 138 } 139 140 void CustomProtocolManager::initialize(const NetworkProcessCreationParameters& parameters) 108 void CustomProtocolManager::registerProtocolClass() 141 109 { 142 110 #if !USE(NETWORK_SESSION) 143 111 [NSURLProtocol registerClass:[WKCustomProtocol class]]; 144 112 #endif 145 146 for (size_t i = 0; i < parameters.urlSchemesRegisteredForCustomProtocols.size(); ++i)147 registerScheme(parameters.urlSchemesRegisteredForCustomProtocols[i]);148 }149 150 void CustomProtocolManager::addCustomProtocol(WKCustomProtocol *customProtocol)151 {152 ASSERT(customProtocol);153 LockHolder locker(m_customProtocolMapMutex);154 m_customProtocolMap.add(customProtocol.customProtocolID, customProtocol);155 }156 157 void CustomProtocolManager::removeCustomProtocol(WKCustomProtocol *customProtocol)158 {159 ASSERT(customProtocol);160 LockHolder locker(m_customProtocolMapMutex);161 m_customProtocolMap.remove(customProtocol.customProtocolID);162 113 } 163 114 … … 175 126 m_registeredSchemes.add(scheme); 176 127 } 177 128 178 129 void CustomProtocolManager::unregisterScheme(const String& scheme) 179 130 { … … 211 162 }); 212 163 213 removeCustomProtocol( protocol.get());164 removeCustomProtocol(customProtocolID); 214 165 } 215 166 … … 250 201 }); 251 202 252 removeCustomProtocol( protocol.get());203 removeCustomProtocol(customProtocolID); 253 204 } 254 205 -
trunk/Source/WebKit2/NetworkProcess/CustomProtocols/CustomProtocolManager.h
r208499 r210374 24 24 */ 25 25 26 #ifndef CustomProtocolManager_h 27 #define CustomProtocolManager_h 26 #pragma once 28 27 29 #include " Connection.h"28 #include "MessageReceiver.h" 30 29 #include "NetworkProcessSupplement.h" 31 #include <wtf/WorkQueue.h> 30 #include <wtf/HashMap.h> 31 #include <wtf/HashSet.h> 32 #include <wtf/text/StringHash.h> 32 33 #include <wtf/text/WTFString.h> 33 34 34 35 #if PLATFORM(COCOA) 35 #include <wtf/HashMap.h>36 #include <wtf/HashSet.h>37 36 #include <wtf/RetainPtr.h> 38 #include <wtf/Threading.h>39 #include <wtf/text/StringHash.h>40 37 OBJC_CLASS NSURLSessionConfiguration; 41 38 OBJC_CLASS WKCustomProtocol; 42 #else43 #include "CustomProtocolManagerImpl.h"44 39 #endif 45 40 41 #if USE(SOUP) 42 #include <wtf/glib/GRefPtr.h> 43 44 typedef struct _GCancellable GCancellable; 45 typedef struct _GInputStream GInputStream; 46 typedef struct _GTask GTask; 47 typedef struct _WebKitSoupRequestGeneric WebKitSoupRequestGeneric; 48 #endif 46 49 47 50 namespace IPC { … … 60 63 struct NetworkProcessCreationParameters; 61 64 62 class CustomProtocolManager : public NetworkProcessSupplement, public IPC:: Connection::WorkQueueMessageReceiver {65 class CustomProtocolManager : public NetworkProcessSupplement, public IPC::MessageReceiver { 63 66 WTF_MAKE_NONCOPYABLE(CustomProtocolManager); 64 67 public: … … 67 70 static const char* supplementName(); 68 71 69 ChildProcess* childProcess() const { return m_childProcess; }70 71 72 void registerScheme(const String&); 72 73 void unregisterScheme(const String&); 73 74 bool supportsScheme(const String&); 74 75 75 76 #if PLATFORM(COCOA) 76 void addCustomProtocol(WKCustomProtocol *); 77 void removeCustomProtocol(WKCustomProtocol *); 78 #if USE(NETWORK_SESSION) 79 void registerProtocolClass(NSURLSessionConfiguration *); 77 typedef RetainPtr<WKCustomProtocol> CustomProtocol; 80 78 #endif 79 #if USE(SOUP) 80 struct WebSoupRequestAsyncData { 81 WebSoupRequestAsyncData(GRefPtr<GTask>&&, WebKitSoupRequestGeneric*); 82 ~WebSoupRequestAsyncData(); 83 84 GRefPtr<GTask> task; 85 WebKitSoupRequestGeneric* request; 86 GRefPtr<GCancellable> cancellable; 87 GRefPtr<GInputStream> stream; 88 }; 89 typedef std::unique_ptr<WebSoupRequestAsyncData> CustomProtocol; 90 #endif 91 92 uint64_t addCustomProtocol(CustomProtocol&&); 93 void removeCustomProtocol(uint64_t customProtocolID); 94 void startLoading(uint64_t customProtocolID, const WebCore::ResourceRequest&); 95 void stopLoading(uint64_t customProtocolID); 96 97 #if PLATFORM(COCOA) && USE(NETWORK_SESSION) 98 void registerProtocolClass(NSURLSessionConfiguration*); 81 99 #endif 82 100 83 101 private: 84 // ChildProcessSupplement85 void initializeConnection(IPC::Connection*) override;86 87 102 // NetworkProcessSupplement 88 103 void initialize(const NetworkProcessCreationParameters&) override; … … 97 112 void wasRedirectedToRequest(uint64_t customProtocolID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse); 98 113 114 void registerProtocolClass(); 115 99 116 ChildProcess* m_childProcess; 100 Ref<WorkQueue> m_messageQueue; 117 118 typedef HashMap<uint64_t, CustomProtocol> CustomProtocolMap; 119 CustomProtocolMap m_customProtocolMap; 120 Lock m_customProtocolMapMutex; 101 121 102 122 #if PLATFORM(COCOA) … … 104 124 Lock m_registeredSchemesMutex; 105 125 106 typedef HashMap<uint64_t, RetainPtr<WKCustomProtocol>> CustomProtocolMap;107 CustomProtocolMap m_customProtocolMap;108 Lock m_customProtocolMapMutex;109 110 126 // WKCustomProtocol objects can be removed from the m_customProtocolMap from multiple threads. 111 127 // We return a RetainPtr here because it is unsafe to return a raw pointer since the object might immediately be destroyed from a different thread. 112 128 RetainPtr<WKCustomProtocol> protocolForID(uint64_t customProtocolID); 113 #else 114 // FIXME: Move mac specific code to CustomProtocolManagerImpl. 115 std::unique_ptr<CustomProtocolManagerImpl> m_impl; 129 #endif 130 131 #if USE(SOUP) 132 GRefPtr<GPtrArray> m_registeredSchemes; 116 133 #endif 117 134 }; … … 119 136 } // namespace WebKit 120 137 121 #endif // CustomProtocolManager_h -
trunk/Source/WebKit2/NetworkProcess/CustomProtocols/soup/CustomProtocolManagerSoup.cpp
r192796 r210374 21 21 #include "CustomProtocolManager.h" 22 22 23 #include "ChildProcess.h"24 #include "CustomProtocolManagerImpl.h"25 23 #include "CustomProtocolManagerMessages.h" 26 #include "NetworkProcessCreationParameters.h" 27 #include "WebProcessCreationParameters.h" 24 #include "DataReference.h" 25 #include "NetworkProcess.h" 26 #include "WebKitSoupRequestInputStream.h" 28 27 #include <WebCore/NotImplemented.h> 28 #include <WebCore/ResourceError.h> 29 #include <WebCore/ResourceRequest.h> 30 #include <WebCore/ResourceResponse.h> 31 #include <WebCore/SoupNetworkSession.h> 32 #include <WebCore/WebKitSoupRequestGeneric.h> 33 #include <wtf/NeverDestroyed.h> 34 35 using namespace WebCore; 29 36 30 37 namespace WebKit { 31 38 32 const char* CustomProtocolManager::supplementName() 33 { 34 return "CustomProtocolManager"; 35 } 36 37 CustomProtocolManager::CustomProtocolManager(ChildProcess* childProcess) 38 : m_childProcess(childProcess) 39 , m_messageQueue(WorkQueue::create("com.apple.WebKit.CustomProtocolManager")) 40 , m_impl(std::make_unique<CustomProtocolManagerImpl>(childProcess)) 41 { 42 } 43 44 void CustomProtocolManager::initializeConnection(IPC::Connection* connection) 45 { 46 connection->addWorkQueueMessageReceiver(Messages::CustomProtocolManager::messageReceiverName(), m_messageQueue.get(), this); 47 } 48 49 void CustomProtocolManager::initialize(const NetworkProcessCreationParameters& parameters) 50 { 51 for (size_t i = 0; i < parameters.urlSchemesRegisteredForCustomProtocols.size(); ++i) 52 registerScheme(parameters.urlSchemesRegisteredForCustomProtocols[i]); 39 40 CustomProtocolManager::WebSoupRequestAsyncData::WebSoupRequestAsyncData(GRefPtr<GTask>&& requestTask, WebKitSoupRequestGeneric* requestGeneric) 41 : task(WTFMove(requestTask)) 42 , request(requestGeneric) 43 , cancellable(g_task_get_cancellable(task.get())) 44 { 45 // If the struct contains a null request, it is because the request failed. 46 g_object_add_weak_pointer(G_OBJECT(request), reinterpret_cast<void**>(&request)); 47 } 48 49 CustomProtocolManager::WebSoupRequestAsyncData::~WebSoupRequestAsyncData() 50 { 51 if (request) 52 g_object_remove_weak_pointer(G_OBJECT(request), reinterpret_cast<void**>(&request)); 53 } 54 55 class CustomProtocolRequestClient final : public WebKitSoupRequestGenericClient { 56 public: 57 static CustomProtocolRequestClient& singleton() 58 { 59 static NeverDestroyed<CustomProtocolRequestClient> client; 60 return client; 61 } 62 63 private: 64 void startRequest(GRefPtr<GTask>&& task) override 65 { 66 WebKitSoupRequestGeneric* request = WEBKIT_SOUP_REQUEST_GENERIC(g_task_get_source_object(task.get())); 67 auto* customProtocolManager = NetworkProcess::singleton().supplement<CustomProtocolManager>(); 68 if (!customProtocolManager) 69 return; 70 71 auto customProtocolID = customProtocolManager->addCustomProtocol(std::make_unique<CustomProtocolManager::WebSoupRequestAsyncData>(WTFMove(task), request)); 72 customProtocolManager->startLoading(customProtocolID, webkitSoupRequestGenericGetRequest(request)); 73 } 74 }; 75 76 void CustomProtocolManager::registerProtocolClass() 77 { 78 static_cast<WebKitSoupRequestGenericClass*>(g_type_class_ref(WEBKIT_TYPE_SOUP_REQUEST_GENERIC))->client = &CustomProtocolRequestClient::singleton(); 53 79 } 54 80 55 81 void CustomProtocolManager::registerScheme(const String& scheme) 56 82 { 57 m_impl->registerScheme(scheme); 83 if (!m_registeredSchemes) 84 m_registeredSchemes = adoptGRef(g_ptr_array_new_with_free_func(g_free)); 85 86 if (m_registeredSchemes->len) 87 g_ptr_array_remove_index_fast(m_registeredSchemes.get(), m_registeredSchemes->len - 1); 88 g_ptr_array_add(m_registeredSchemes.get(), g_strdup(scheme.utf8().data())); 89 g_ptr_array_add(m_registeredSchemes.get(), nullptr); 90 91 auto* genericRequestClass = static_cast<SoupRequestClass*>(g_type_class_ref(WEBKIT_TYPE_SOUP_REQUEST_GENERIC)); 92 genericRequestClass->schemes = const_cast<const char**>(reinterpret_cast<char**>(m_registeredSchemes->pdata)); 93 soup_session_add_feature_by_type(SoupNetworkSession::defaultSession().soupSession(), WEBKIT_TYPE_SOUP_REQUEST_GENERIC); 58 94 } 59 95 … … 65 101 bool CustomProtocolManager::supportsScheme(const String& scheme) 66 102 { 67 return m_impl->supportsScheme(scheme); 68 } 69 70 void CustomProtocolManager::didFailWithError(uint64_t customProtocolID, const WebCore::ResourceError& error) 71 { 72 m_impl->didFailWithError(customProtocolID, error); 103 if (scheme.isNull()) 104 return false; 105 106 CString cScheme = scheme.utf8(); 107 for (unsigned i = 0; i < m_registeredSchemes->len; ++i) { 108 if (cScheme == static_cast<char*>(g_ptr_array_index(m_registeredSchemes.get(), i))) 109 return true; 110 } 111 112 return false; 113 } 114 115 void CustomProtocolManager::didFailWithError(uint64_t customProtocolID, const ResourceError& error) 116 { 117 auto* data = m_customProtocolMap.get(customProtocolID); 118 ASSERT(data); 119 120 // Either we haven't started reading the stream yet, in which case we need to complete the 121 // task first, or we failed reading it and the task was already completed by didLoadData(). 122 ASSERT(!data->stream || !data->task); 123 124 if (!data->stream) { 125 GRefPtr<GTask> task = std::exchange(data->task, nullptr); 126 ASSERT(task.get()); 127 g_task_return_new_error(task.get(), g_quark_from_string(error.domain().utf8().data()), 128 error.errorCode(), "%s", error.localizedDescription().utf8().data()); 129 } else 130 webkitSoupRequestInputStreamDidFailWithError(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()), error); 131 132 removeCustomProtocol(customProtocolID); 73 133 } 74 134 75 135 void CustomProtocolManager::didLoadData(uint64_t customProtocolID, const IPC::DataReference& dataReference) 76 136 { 77 m_impl->didLoadData(customProtocolID, dataReference); 78 } 79 80 void CustomProtocolManager::didReceiveResponse(uint64_t customProtocolID, const WebCore::ResourceResponse& response, uint32_t) 81 { 82 m_impl->didReceiveResponse(customProtocolID, response); 137 auto* data = m_customProtocolMap.get(customProtocolID); 138 // The data might have been removed from the request map if a previous chunk failed 139 // and a new message was sent by the UI process before being notified about the failure. 140 if (!data) 141 return; 142 143 if (!data->stream) { 144 GRefPtr<GTask> task = std::exchange(data->task, nullptr); 145 ASSERT(task.get()); 146 147 goffset soupContentLength = soup_request_get_content_length(SOUP_REQUEST(g_task_get_source_object(task.get()))); 148 uint64_t contentLength = soupContentLength == -1 ? 0 : static_cast<uint64_t>(soupContentLength); 149 if (!dataReference.size()) { 150 // Empty reply, just create and empty GMemoryInputStream. 151 data->stream = g_memory_input_stream_new(); 152 } else if (dataReference.size() == contentLength) { 153 // We don't expect more data, so we can just create a GMemoryInputStream with all the data. 154 data->stream = g_memory_input_stream_new_from_data(g_memdup(dataReference.data(), dataReference.size()), contentLength, g_free); 155 } else { 156 // We expect more data chunks from the UI process. 157 data->stream = webkitSoupRequestInputStreamNew(contentLength); 158 webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()), dataReference.data(), dataReference.size()); 159 } 160 g_task_return_pointer(task.get(), data->stream.get(), g_object_unref); 161 return; 162 } 163 164 if (g_cancellable_is_cancelled(data->cancellable.get()) || !data->request) { 165 // ResourceRequest failed or it was cancelled. It doesn't matter here the error or if it was cancelled, 166 // because that's already handled by the resource handle client, we just want to notify the UI process 167 // to stop reading data from the user input stream. If UI process already sent all the data we simply 168 // finish silently. 169 if (!webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()))) 170 stopLoading(customProtocolID); 171 172 return; 173 } 174 175 webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()), dataReference.data(), dataReference.size()); 176 } 177 178 void CustomProtocolManager::didReceiveResponse(uint64_t customProtocolID, const ResourceResponse& response, uint32_t) 179 { 180 auto* data = m_customProtocolMap.get(customProtocolID); 181 // The data might have been removed from the request map if an error happened even before this point. 182 if (!data) 183 return; 184 185 ASSERT(data->task); 186 187 WebKitSoupRequestGeneric* request = WEBKIT_SOUP_REQUEST_GENERIC(g_task_get_source_object(data->task.get())); 188 webkitSoupRequestGenericSetContentLength(request, response.expectedContentLength() ? response.expectedContentLength() : -1); 189 webkitSoupRequestGenericSetContentType(request, !response.mimeType().isEmpty() ? response.mimeType().utf8().data() : 0); 83 190 } 84 191 85 192 void CustomProtocolManager::didFinishLoading(uint64_t customProtocolID) 86 193 { 87 m_impl->didFinishLoading(customProtocolID); 88 } 89 90 void CustomProtocolManager::wasRedirectedToRequest(uint64_t, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&) 194 ASSERT(m_customProtocolMap.contains(customProtocolID)); 195 removeCustomProtocol(customProtocolID); 196 } 197 198 void CustomProtocolManager::wasRedirectedToRequest(uint64_t, const ResourceRequest&, const ResourceResponse&) 91 199 { 92 200 notImplemented(); -
trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm
r209898 r210374 321 321 } 322 322 323 static RefPtr<CustomProtocolManager>& globalCustomProtocolManager()324 { 325 static NeverDestroyed<RefPtr<CustomProtocolManager>> customProtocolManager;326 return customProtocolManager .get();323 static CustomProtocolManager*& globalCustomProtocolManager() 324 { 325 static CustomProtocolManager* customProtocolManager { nullptr }; 326 return customProtocolManager; 327 327 } 328 328 … … 397 397 { 398 398 ASSERT(isMainThread()); 399 static NetworkSession* session = &NetworkSessionCocoa::create(WebCore::SessionID::defaultSessionID(), globalCustomProtocolManager() .get()).leakRef();399 static NetworkSession* session = &NetworkSessionCocoa::create(WebCore::SessionID::defaultSessionID(), globalCustomProtocolManager()).leakRef(); 400 400 return *session; 401 401 } -
trunk/Source/WebKit2/PlatformEfl.cmake
r209700 r210374 2 2 DatabaseProcess/efl/DatabaseProcessMainEfl.cpp 3 3 4 NetworkProcess/CustomProtocols/soup/CustomProtocolManagerImpl.cpp5 4 NetworkProcess/CustomProtocols/soup/CustomProtocolManagerSoup.cpp 6 5 -
trunk/Source/WebKit2/PlatformGTK.cmake
r210238 r210374 29 29 DatabaseProcess/gtk/DatabaseProcessMainGtk.cpp 30 30 31 NetworkProcess/CustomProtocols/soup/CustomProtocolManagerImpl.cpp32 31 NetworkProcess/CustomProtocols/soup/CustomProtocolManagerSoup.cpp 33 32 -
trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
r209896 r210374 1109 1109 5CBC9B8E1C652CA000A8FDCF /* NetworkDataTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CBC9B891C6524A500A8FDCF /* NetworkDataTask.h */; }; 1110 1110 5CE85B201C88E64B0070BFCE /* PingLoad.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE85B1F1C88E6430070BFCE /* PingLoad.h */; }; 1111 5CFECB041E1ED1CC00F88504 /* CustomProtocolManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CFECB031E1ED1C800F88504 /* CustomProtocolManager.cpp */; }; 1111 1112 6501BD1A12F1243400E9F248 /* WKBundleInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65B86F1712F11D7B00B7DD8A /* WKBundleInspector.cpp */; }; 1112 1113 659C551E130006410025C0C2 /* InjectedBundlePageResourceLoadClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6546A82913000164000CEB1C /* InjectedBundlePageResourceLoadClient.cpp */; }; … … 3246 3247 5CBC9B8B1C65257300A8FDCF /* NetworkDataTaskCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkDataTaskCocoa.mm; path = NetworkProcess/cocoa/NetworkDataTaskCocoa.mm; sourceTree = "<group>"; }; 3247 3248 5CE85B1F1C88E6430070BFCE /* PingLoad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PingLoad.h; path = NetworkProcess/PingLoad.h; sourceTree = "<group>"; }; 3249 5CFECB031E1ED1C800F88504 /* CustomProtocolManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CustomProtocolManager.cpp; path = NetworkProcess/CustomProtocols/CustomProtocolManager.cpp; sourceTree = "<group>"; }; 3248 3250 5D442A5516D5856700AC3331 /* PluginService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PluginService.entitlements; sourceTree = "<group>"; }; 3249 3251 5DAD73F1116FF90C00EE5396 /* BaseTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = BaseTarget.xcconfig; sourceTree = "<group>"; }; … … 5922 5924 isa = PBXGroup; 5923 5925 children = ( 5926 5CFECB031E1ED1C800F88504 /* CustomProtocolManager.cpp */, 5924 5927 5C14271A1C23F8BF00D41183 /* Cocoa */, 5925 5928 5C1427141C23F8B000D41183 /* CustomProtocolManager.h */, … … 9491 9494 1A0EC907124C0AB8007EF4A5 /* PluginProcessConnection.cpp in Sources */, 9492 9495 1A0EC910124C0AF5007EF4A5 /* PluginProcessConnectionManager.cpp in Sources */, 9496 5CFECB041E1ED1CC00F88504 /* CustomProtocolManager.cpp in Sources */, 9493 9497 1A7865B916CAC71500ACE83A /* PluginProcessConnectionManagerMessageReceiver.cpp in Sources */, 9494 9498 1A2BB6D014117B4D000F35D4 /* PluginProcessConnectionMessageReceiver.cpp in Sources */,
Note: See TracChangeset
for help on using the changeset viewer.