Changeset 119695 in webkit
- Timestamp:
- Jun 7, 2012 2:11:08 AM (12 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r119687 r119695 1 2012-06-06 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [SOUP] WebSoupRequestManager should handle loading errors and zero-length replies 4 https://bugs.webkit.org/show_bug.cgi?id=88087 5 6 Reviewed by Martin Robinson. 7 8 * UIProcess/API/C/soup/WKSoupRequestManager.h: 9 * UIProcess/soup/WebSoupRequestManagerClient.cpp: 10 (WebKit::WebSoupRequestManagerClient::didFailToLoadURIRequest): 11 Call didFailToLoadURIRequest in the client if present. 12 * UIProcess/soup/WebSoupRequestManagerClient.h: 13 * UIProcess/soup/WebSoupRequestManagerProxy.cpp: 14 (WebKit::WebSoupRequestManagerProxy::WebSoupRequestManagerProxy): 15 Initialize m_loadFailed. 16 (WebKit::WebSoupRequestManagerProxy::didReceiveURIRequestData): 17 Don't send more data to the web process if the resource failed to 18 load. 19 (WebKit::WebSoupRequestManagerProxy::didFailToLoadURIRequest): Set 20 m_loadFailed and notifiy the client calling didFailToLoadURIRequest. 21 * UIProcess/soup/WebSoupRequestManagerProxy.h: 22 * UIProcess/soup/WebSoupRequestManagerProxy.messages.in: Add 23 DidFailToLoadURIRequest message. 24 * WebProcess/soup/WebKitSoupRequestGeneric.cpp: 25 (webkitSoupRequestGenericSendAsync): Pass the cancellable to the 26 WebSoupRequestManager. 27 * WebProcess/soup/WebSoupRequestManager.cpp: 28 (WebKit::WebSoupRequestAsyncData::WebSoupRequestAsyncData): Helper 29 struct to save requests. 30 (WebSoupRequestAsyncData): Add a weak pointer to invalidate the 31 request when it's destroyed before the operation has finished. 32 (WebKit::WebSoupRequestAsyncData::~WebSoupRequestAsyncData): 33 Remove the weak pointer. 34 (WebKit::WebSoupRequestAsyncData::requestFailed): Return whther 35 the request failed. 36 (WebKit::WebSoupRequestAsyncData::releaseResult): Return the 37 result and clear the pointer. 38 (WebKit::WebSoupRequestManager::didHandleURIRequest): Create and 39 empty memory stream for zero-length replies instead of creating an 40 error. 41 (WebKit::WebSoupRequestManager::didReceiveURIRequestData): If the 42 request failed and more data expected from the UI process, send a 43 message to the UI process to notify that the resource load failed. 44 (WebKit::WebSoupRequestManager::send): Save request information in 45 the request map. 46 * WebProcess/soup/WebSoupRequestManager.h: 47 1 48 2012-06-06 Andy Estes <aestes@apple.com> 2 49 -
trunk/Source/WebKit2/UIProcess/API/C/soup/WKSoupRequestManager.h
r116738 r119695 35 35 36 36 typedef void (*WKSoupRequestManagerDidReceiveURIRequestCallback)(WKSoupRequestManagerRef soupRequestManagerRef, WKURLRef urlRef, uint64_t requestID, const void* clientInfo); 37 typedef void (*WKSoupRequestManagerDidFailToLoadURIRequestCallback)(WKSoupRequestManagerRef soupRequestManagerRef, uint64_t requestID, const void* clientInfo); 37 38 38 39 struct WKSoupRequestManagerClient { 39 int version; 40 const void* clientInfo; 41 WKSoupRequestManagerDidReceiveURIRequestCallback didReceiveURIRequest; 40 int version; 41 const void* clientInfo; 42 WKSoupRequestManagerDidReceiveURIRequestCallback didReceiveURIRequest; 43 WKSoupRequestManagerDidFailToLoadURIRequestCallback didFailToLoadURIRequest; 42 44 }; 43 45 typedef struct WKSoupRequestManagerClient WKSoupRequestManagerClient; -
trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.cpp
r115411 r119695 34 34 } 35 35 36 void WebSoupRequestManagerClient::didFailToLoadURIRequest(WebSoupRequestManagerProxy* soupRequestManager, uint64_t requestID) 37 { 38 if (m_client.didFailToLoadURIRequest) 39 m_client.didFailToLoadURIRequest(toAPI(soupRequestManager), requestID, m_client.clientInfo); 40 } 41 36 42 } // namespace WebKit -
trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerClient.h
r115411 r119695 32 32 public: 33 33 bool didReceiveURIRequest(WebSoupRequestManagerProxy*, WebURL*, uint64_t requestID); 34 void didFailToLoadURIRequest(WebSoupRequestManagerProxy*, uint64_t requestID); 34 35 }; 35 36 -
trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.cpp
r116738 r119695 34 34 WebSoupRequestManagerProxy::WebSoupRequestManagerProxy(WebContext* context) 35 35 : m_webContext(context) 36 , m_loadFailed(false) 36 37 { 37 38 } … … 69 70 void WebSoupRequestManagerProxy::didReceiveURIRequestData(const WebData* requestData, uint64_t requestID) 70 71 { 72 if (m_loadFailed) 73 return; 74 71 75 ASSERT(m_webContext); 72 76 m_webContext->sendToAllProcesses(Messages::WebSoupRequestManager::DidReceiveURIRequestData(requestData->dataReference(), requestID)); … … 79 83 } 80 84 85 void WebSoupRequestManagerProxy::didFailToLoadURIRequest(uint64_t requestID) 86 { 87 m_loadFailed = true; 88 m_client.didFailToLoadURIRequest(this, requestID); 89 } 90 81 91 } // namespace WebKit -
trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.h
r116738 r119695 53 53 void didHandleURIRequest(const WebData*, uint64_t contentLength, const String& mimeType, uint64_t requestID); 54 54 void didReceiveURIRequestData(const WebData*, uint64_t requestID); 55 void didFailToLoadURIRequest(uint64_t requestID); 55 56 56 57 void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); … … 67 68 WebContext* m_webContext; 68 69 WebSoupRequestManagerClient m_client; 70 bool m_loadFailed; 69 71 }; 70 72 -
trunk/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.messages.in
r115411 r119695 23 23 messages -> WebSoupRequestManagerProxy { 24 24 DidReceiveURIRequest(WTF::String uriString, uint64_t requestID); 25 DidFailToLoadURIRequest(uint64_t requestID); 25 26 } -
trunk/Source/WebKit2/WebProcess/soup/WebKitSoupRequestGeneric.cpp
r115411 r119695 49 49 { 50 50 GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(request), callback, userData, reinterpret_cast<void*>(webkitSoupRequestGenericSendAsync)); 51 WebProcess::shared().soupRequestManager().send(result );51 WebProcess::shared().soupRequestManager().send(result, cancellable); 52 52 } 53 53 -
trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.cpp
r118914 r119695 42 42 } 43 43 44 struct WebSoupRequestAsyncData { 45 WebSoupRequestAsyncData(GSimpleAsyncResult* result, WebKitSoupRequestGeneric* requestGeneric, GCancellable* cancellable) 46 : result(result) 47 , request(requestGeneric) 48 , cancellable(cancellable) 49 { 50 // If the struct contains a null request, it is because the request failed. 51 g_object_add_weak_pointer(G_OBJECT(request), reinterpret_cast<void**>(&request)); 52 } 53 54 ~WebSoupRequestAsyncData() 55 { 56 if (request) 57 g_object_remove_weak_pointer(G_OBJECT(request), reinterpret_cast<void**>(&request)); 58 } 59 60 bool requestFailed() 61 { 62 return g_cancellable_is_cancelled(cancellable.get()) || !request; 63 } 64 65 GRefPtr<GSimpleAsyncResult> releaseResult() 66 { 67 GSimpleAsyncResult* returnValue = result; 68 result = 0; 69 return adoptGRef(returnValue); 70 } 71 72 GSimpleAsyncResult* result; 73 WebKitSoupRequestGeneric* request; 74 GRefPtr<GCancellable> cancellable; 75 GRefPtr<GInputStream> stream; 76 }; 77 44 78 WebSoupRequestManager::WebSoupRequestManager(WebProcess* process) 45 79 : m_process(process) … … 79 113 void WebSoupRequestManager::didHandleURIRequest(const CoreIPC::DataReference& requestData, uint64_t contentLength, const String& mimeType, uint64_t requestID) 80 114 { 81 GRefPtr<GSimpleAsyncResult> result = adoptGRef(m_requestMap.take(requestID)); 115 WebSoupRequestAsyncData* data = m_requestMap.get(requestID); 116 ASSERT(data); 117 GRefPtr<GSimpleAsyncResult> result = data->releaseResult(); 82 118 ASSERT(result.get()); 83 119 84 120 GRefPtr<WebKitSoupRequestGeneric> request = adoptGRef(WEBKIT_SOUP_REQUEST_GENERIC(g_async_result_get_source_object(G_ASYNC_RESULT(result.get())))); 85 if (requestData.size()) { 86 webkitSoupRequestGenericSetContentLength(request.get(), contentLength ? contentLength : -1); 87 webkitSoupRequestGenericSetContentType(request.get(), !mimeType.isEmpty() ? mimeType.utf8().data() : 0); 121 webkitSoupRequestGenericSetContentLength(request.get(), contentLength ? contentLength : -1); 122 webkitSoupRequestGenericSetContentType(request.get(), !mimeType.isEmpty() ? mimeType.utf8().data() : 0); 88 123 89 GInputStream* dataStream; 90 if (requestData.size() == contentLength) { 91 // We don't expect more data, so we can just create a GMemoryInputStream with all the data. 92 dataStream = g_memory_input_stream_new_from_data(g_memdup(requestData.data(), requestData.size()), contentLength, g_free); 93 } else { 94 dataStream = webkitSoupRequestInputStreamNew(contentLength); 95 webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream), requestData.data(), requestData.size()); 96 m_requestStreamMap.set(requestID, dataStream); 97 } 98 g_simple_async_result_set_op_res_gpointer(result.get(), dataStream, g_object_unref); 124 GInputStream* dataStream; 125 if (!requestData.size()) { 126 // Empty reply, just create and empty GMemoryInputStream. 127 dataStream = g_memory_input_stream_new(); 128 m_requestMap.remove(requestID); 129 } else if (requestData.size() == contentLength) { 130 // We don't expect more data, so we can just create a GMemoryInputStream with all the data. 131 dataStream = g_memory_input_stream_new_from_data(g_memdup(requestData.data(), requestData.size()), contentLength, g_free); 132 m_requestMap.remove(requestID); 99 133 } else { 100 GOwnPtr<char> uriString(soup_uri_to_string(soup_request_get_uri(SOUP_REQUEST(request.get())), FALSE)); 101 WebCore::ResourceRequest resourceRequest(String::fromUTF8(uriString.get())); 102 WebCore::ResourceError resourceError(cannotShowURLError(resourceRequest)); 103 g_simple_async_result_set_error(result.get(), g_quark_from_string(resourceError.domain().utf8().data()), 104 resourceError.errorCode(), "%s", resourceError.localizedDescription().utf8().data()); 134 // We expect more data chunks from the UI process. 135 dataStream = webkitSoupRequestInputStreamNew(contentLength); 136 data->stream = dataStream; 137 webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream), requestData.data(), requestData.size()); 105 138 } 139 g_simple_async_result_set_op_res_gpointer(result.get(), dataStream, g_object_unref); 106 140 g_simple_async_result_complete(result.get()); 107 141 } … … 109 143 void WebSoupRequestManager::didReceiveURIRequestData(const CoreIPC::DataReference& requestData, uint64_t requestID) 110 144 { 111 GInputStream* dataStream = m_requestStreamMap.get(requestID); 112 ASSERT(dataStream); 113 webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream), requestData.data(), requestData.size()); 114 if (webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(dataStream))) 115 m_requestStreamMap.remove(requestID); 145 WebSoupRequestAsyncData* data = m_requestMap.get(requestID); 146 // The data might have been removed from the request map if a previous chunk failed 147 // and a new message was sent by the UI process before being notified about the failure. 148 if (!data) 149 return; 150 ASSERT(data->stream.get()); 151 152 if (data->requestFailed()) { 153 // ResourceRequest failed or it was cancelled. It doesn't matter here the error or if it was cancelled, 154 // because that's already handled by the resource handle client, we just want to notify the UI process 155 // to stop reading data from the user input stream. If UI process already sent all the data we simply 156 // finish silently. 157 if (!webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()))) 158 m_process->connection()->send(Messages::WebSoupRequestManagerProxy::DidFailToLoadURIRequest(requestID), 0); 159 m_requestMap.remove(requestID); 160 161 return; 162 } 163 164 webkitSoupRequestInputStreamAddData(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()), requestData.data(), requestData.size()); 165 if (webkitSoupRequestInputStreamFinished(WEBKIT_SOUP_REQUEST_INPUT_STREAM(data->stream.get()))) 166 m_requestMap.remove(requestID); 116 167 } 117 168 118 void WebSoupRequestManager::send(GSimpleAsyncResult* result )169 void WebSoupRequestManager::send(GSimpleAsyncResult* result, GCancellable* cancellable) 119 170 { 120 171 GRefPtr<WebKitSoupRequestGeneric> request = adoptGRef(WEBKIT_SOUP_REQUEST_GENERIC(g_async_result_get_source_object(G_ASYNC_RESULT(result)))); … … 123 174 124 175 uint64_t requestID = generateSoupRequestID(); 125 m_requestMap.set(requestID, result);176 m_requestMap.set(requestID, adoptPtr(new WebSoupRequestAsyncData(result, request.get(), cancellable))); 126 177 m_process->connection()->send(Messages::WebSoupRequestManagerProxy::DidReceiveURIRequest(String::fromUTF8(uriString.get()), requestID), 0); 127 178 } -
trunk/Source/WebKit2/WebProcess/soup/WebSoupRequestManager.h
r116738 r119695 23 23 #include <wtf/HashMap.h> 24 24 #include <wtf/Noncopyable.h> 25 #include <wtf/OwnPtr.h> 25 26 #include <wtf/gobject/GRefPtr.h> 26 27 #include <wtf/text/WTFString.h> … … 39 40 40 41 class WebProcess; 42 struct WebSoupRequestAsyncData; 41 43 42 44 class WebSoupRequestManager { … … 46 48 ~WebSoupRequestManager(); 47 49 48 void send(GSimpleAsyncResult* );50 void send(GSimpleAsyncResult*, GCancellable*); 49 51 GInputStream* finish(GSimpleAsyncResult*); 50 52 … … 60 62 WebProcess* m_process; 61 63 GRefPtr<GPtrArray> m_schemes; 62 HashMap<uint64_t, GSimpleAsyncResult*> m_requestMap; 63 HashMap<uint64_t, GInputStream*> m_requestStreamMap; 64 HashMap<uint64_t, OwnPtr<WebSoupRequestAsyncData> > m_requestMap; 64 65 }; 65 66
Note: See TracChangeset
for help on using the changeset viewer.