diff options
Diffstat (limited to 'WebCore/platform/network')
-rw-r--r-- | WebCore/platform/network/ResourceHandle.h | 16 | ||||
-rw-r--r-- | WebCore/platform/network/ResourceHandleInternal.h | 31 | ||||
-rw-r--r-- | WebCore/platform/network/mac/WebCoreURLResponse.mm | 19 | ||||
-rw-r--r-- | WebCore/platform/network/qt/QNetworkReplyHandler.cpp | 7 | ||||
-rw-r--r-- | WebCore/platform/network/qt/ResourceRequestQt.cpp | 2 | ||||
-rw-r--r-- | WebCore/platform/network/qt/SocketStreamHandleQt.cpp | 7 | ||||
-rw-r--r-- | WebCore/platform/network/soup/ResourceHandleSoup.cpp | 5 | ||||
-rw-r--r-- | WebCore/platform/network/win/ResourceHandleWin.cpp | 507 | ||||
-rw-r--r-- | WebCore/platform/network/win/ResourceHandleWin.h | 46 |
9 files changed, 220 insertions, 420 deletions
diff --git a/WebCore/platform/network/ResourceHandle.h b/WebCore/platform/network/ResourceHandle.h index 1cb9ee0..2ea42b1 100644 --- a/WebCore/platform/network/ResourceHandle.h +++ b/WebCore/platform/network/ResourceHandle.h @@ -46,11 +46,6 @@ typedef unsigned long DWORD; typedef unsigned long DWORD_PTR; typedef void* LPVOID; typedef LPVOID HINTERNET; -typedef unsigned WPARAM; -typedef long LPARAM; -typedef struct HWND__* HWND; -typedef _W64 long LONG_PTR; -typedef LONG_PTR LRESULT; #endif @@ -168,14 +163,11 @@ public: static void forceContentSniffing(); #if USE(WININET) - void setHasReceivedResponse(bool = true); - bool hasReceivedResponse() const; + void setSynchronousInternetHandle(HINTERNET); void fileLoadTimer(Timer<ResourceHandle>*); - void onHandleCreated(LPARAM); - void onRequestRedirected(LPARAM); - void onRequestComplete(LPARAM); - friend void __stdcall transferJobStatusCallback(HINTERNET, DWORD_PTR, DWORD, LPVOID, DWORD); - friend LRESULT __stdcall ResourceHandleWndProc(HWND, unsigned message, WPARAM, LPARAM); + void onRedirect(); + bool onRequestComplete(); + static void CALLBACK internetStatusCallback(HINTERNET, DWORD_PTR, DWORD, LPVOID, DWORD); #endif #if PLATFORM(QT) || USE(CURL) || USE(SOUP) || PLATFORM(ANDROID) diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h index 7b6db90..96fbf00 100644 --- a/WebCore/platform/network/ResourceHandleInternal.h +++ b/WebCore/platform/network/ResourceHandleInternal.h @@ -92,16 +92,13 @@ namespace WebCore { #endif #if USE(WININET) , m_fileLoadTimer(loader, &ResourceHandle::fileLoadTimer) - , m_resourceHandle(0) - , m_secondaryHandle(0) - , m_jobId(0) - , m_threadId(0) - , m_writing(false) - , m_formDataString(0) - , m_formDataLength(0) + , m_internetHandle(0) + , m_connectHandle(0) + , m_requestHandle(0) + , m_sentEndRequest(false) , m_bytesRemainingToWrite(0) + , m_loadSynchronously(false) , m_hasReceivedResponse(false) - , m_resend(false) #endif #if USE(CURL) , m_handle(0) @@ -167,17 +164,15 @@ namespace WebCore { #endif #if USE(WININET) Timer<ResourceHandle> m_fileLoadTimer; - HINTERNET m_resourceHandle; - HINTERNET m_secondaryHandle; - unsigned m_jobId; - DWORD m_threadId; - bool m_writing; - char* m_formDataString; - int m_formDataLength; - int m_bytesRemainingToWrite; - String m_postReferrer; + HINTERNET m_internetHandle; + HINTERNET m_connectHandle; + HINTERNET m_requestHandle; + bool m_sentEndRequest; + Vector<char> m_formData; + size_t m_bytesRemainingToWrite; + bool m_loadSynchronously; bool m_hasReceivedResponse; - bool m_resend; + String m_redirectUrl; #endif #if USE(CURL) CURL* m_handle; diff --git a/WebCore/platform/network/mac/WebCoreURLResponse.mm b/WebCore/platform/network/mac/WebCoreURLResponse.mm index 9be4714..e287e5f 100644 --- a/WebCore/platform/network/mac/WebCoreURLResponse.mm +++ b/WebCore/platform/network/mac/WebCoreURLResponse.mm @@ -29,7 +29,6 @@ #import "config.h" #import "WebCoreURLResponse.h" -#import "FoundationExtras.h" #import "MIMETypeRegistry.h" #import <objc/objc-class.h> #import <wtf/Assertions.h> @@ -327,12 +326,12 @@ static NSDictionary *createExtensionToMIMETypeMap() ]; } -static NSString *mimeTypeFromUTITree(CFStringRef uti) +static RetainPtr<NSString> mimeTypeFromUTITree(CFStringRef uti) { // Check if this UTI has a MIME type. RetainPtr<CFStringRef> mimeType(AdoptCF, UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)); if (mimeType) - return (NSString *)HardAutorelease(mimeType.releaseRef()); + return (NSString *)mimeType.get(); // If not, walk the ancestory of this UTI via its "ConformsTo" tags and return the first MIME type we find. RetainPtr<CFDictionaryRef> decl(AdoptCF, UTTypeCopyDeclaration(uti)); @@ -354,7 +353,7 @@ static NSString *mimeTypeFromUTITree(CFStringRef uti) if (CFGetTypeID(object) != CFStringGetTypeID()) continue; - if (NSString *mimeType = mimeTypeFromUTITree((CFStringRef)object)) + if (RetainPtr<NSString> mimeType = mimeTypeFromUTITree((CFStringRef)object)) return mimeType; } } @@ -366,13 +365,13 @@ static NSString *mimeTypeFromUTITree(CFStringRef uti) -(void)adjustMIMETypeIfNecessary { - NSString *result = [self MIMEType]; - NSString *originalResult = result; + RetainPtr<NSString> result = [self MIMEType]; + RetainPtr<NSString> originalResult = result; #ifdef BUILDING_ON_TIGER // When content sniffing is disabled, Tiger's CFNetwork automatically returns application/octet-stream for certain // extensions even when scouring the UTI maps would end up with a better result, so we'll give a chance for that to happen. - if ([[self URL] isFileURL] && [result caseInsensitiveCompare:@"application/octet-stream"] == NSOrderedSame) + if ([[self URL] isFileURL] && [result.get() caseInsensitiveCompare:@"application/octet-stream"] == NSOrderedSame) result = nil; #endif @@ -403,7 +402,7 @@ static NSString *mimeTypeFromUTITree(CFStringRef uti) #ifndef BUILDING_ON_TIGER // <rdar://problem/5321972> Plain text document from HTTP server detected as application/octet-stream // Make the best guess when deciding between "generic binary" and "generic text" using a table of known binary MIME types. - if ([result isEqualToString:@"application/octet-stream"] && [self respondsToSelector:@selector(allHeaderFields)] && [[[self performSelector:@selector(allHeaderFields)] objectForKey:@"Content-Type"] hasPrefix:@"text/plain"]) { + if ([result.get() isEqualToString:@"application/octet-stream"] && [self respondsToSelector:@selector(allHeaderFields)] && [[[self performSelector:@selector(allHeaderFields)] objectForKey:@"Content-Type"] hasPrefix:@"text/plain"]) { static NSSet *binaryExtensions = createBinaryExtensionsSet(); if (![binaryExtensions containsObject:[[[self suggestedFilename] pathExtension] lowercaseString]]) result = @"text/plain"; @@ -413,12 +412,12 @@ static NSString *mimeTypeFromUTITree(CFStringRef uti) #ifdef BUILDING_ON_LEOPARD // Workaround for <rdar://problem/5539824> - if ([result isEqualToString:@"text/xml"]) + if ([result.get() isEqualToString:@"text/xml"]) result = @"application/xml"; #endif if (result != originalResult) - [self _setMIMEType:result]; + [self _setMIMEType:result.get()]; } @end diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 30f7011..ca3af75 100644 --- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -161,10 +161,8 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode load m_method = QNetworkAccessManager::PostOperation; else if (r.httpMethod() == "PUT") m_method = QNetworkAccessManager::PutOperation; -#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) else if (r.httpMethod() == "DELETE") m_method = QNetworkAccessManager::DeleteOperation; -#endif #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) else if (r.httpMethod() == "OPTIONS") m_method = QNetworkAccessManager::CustomOperation; @@ -246,6 +244,9 @@ void QNetworkReplyHandler::finish() if (m_shouldFinish) return; + if (!m_reply) + return; + sendResponseIfNeeded(); if (!m_resourceHandle) @@ -465,12 +466,10 @@ void QNetworkReplyHandler::start() putDevice->setParent(m_reply); break; } -#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) case QNetworkAccessManager::DeleteOperation: { m_reply = manager->deleteResource(m_request); break; } -#endif #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) case QNetworkAccessManager::CustomOperation: m_reply = manager->sendCustomRequest(m_request, m_resourceHandle->firstRequest().httpMethod().latin1().data()); diff --git a/WebCore/platform/network/qt/ResourceRequestQt.cpp b/WebCore/platform/network/qt/ResourceRequestQt.cpp index 4d576c7..7e162ed 100644 --- a/WebCore/platform/network/qt/ResourceRequestQt.cpp +++ b/WebCore/platform/network/qt/ResourceRequestQt.cpp @@ -47,9 +47,7 @@ QNetworkRequest ResourceRequest::toNetworkRequest(QObject* originatingFrame) con { QNetworkRequest request; request.setUrl(url()); -#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) request.setOriginatingObject(originatingFrame); -#endif const HTTPHeaderMap &headers = httpHeaderFields(); for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); diff --git a/WebCore/platform/network/qt/SocketStreamHandleQt.cpp b/WebCore/platform/network/qt/SocketStreamHandleQt.cpp index e666ff7..cc508b6 100644 --- a/WebCore/platform/network/qt/SocketStreamHandleQt.cpp +++ b/WebCore/platform/network/qt/SocketStreamHandleQt.cpp @@ -148,12 +148,9 @@ void SocketStreamHandlePrivate::socketErrorCallback(int error) } #ifndef QT_NO_OPENSSL -void SocketStreamHandlePrivate::socketSslErrors(const QList<QSslError>&) +void SocketStreamHandlePrivate::socketSslErrors(const QList<QSslError>& error) { - // FIXME: based on http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-68#page-15 - // we should abort on certificate errors. - // We don't abort while this is still work in progress. - static_cast<QSslSocket*>(m_socket)->ignoreSslErrors(); + QMetaObject::invokeMethod(this, "socketErrorCallback", Qt::QueuedConnection, Q_ARG(int, error[0].error())); } #endif diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp index 0009e36..0d84388 100644 --- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp +++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp @@ -866,7 +866,10 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer) return; } - response.setMimeType(g_file_info_get_content_type(info)); + // According to http://library.gnome.org/devel/gio/stable/gio-GContentType.html + // GContentType on Unix is the mime type, but not on Win32. + GOwnPtr<gchar> mimeType(g_content_type_get_mime_type(g_file_info_get_content_type(info))); + response.setMimeType(mimeType.get()); response.setExpectedContentLength(g_file_info_get_size(info)); GTimeVal tv; diff --git a/WebCore/platform/network/win/ResourceHandleWin.cpp b/WebCore/platform/network/win/ResourceHandleWin.cpp index 832a8e2..5de2e1b 100644 --- a/WebCore/platform/network/win/ResourceHandleWin.cpp +++ b/WebCore/platform/network/win/ResourceHandleWin.cpp @@ -27,43 +27,38 @@ #include "config.h" #include "ResourceHandle.h" -#include "CachedResourceLoader.h" -#include "Document.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "Page.h" +#include "HTTPParsers.h" +#include "MIMETypeRegistry.h" +#include "MainThread.h" +#include "NotImplemented.h" #include "ResourceError.h" #include "ResourceHandleClient.h" #include "ResourceHandleInternal.h" -#include "ResourceHandleWin.h" +#include "SharedBuffer.h" #include "Timer.h" -#include "WebCoreInstanceHandle.h" - +#include "UnusedParam.h" #include <wtf/text/CString.h> #include <windows.h> #include <wininet.h> namespace WebCore { -static unsigned transferJobId = 0; -static HashMap<int, ResourceHandle*>* jobIdMap = 0; +static inline HINTERNET createInternetHandle(const String& userAgent, bool asynchronous) +{ + String userAgentString = userAgent; + HINTERNET internetHandle = InternetOpenW(userAgentString.charactersWithNullTermination(), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, asynchronous ? INTERNET_FLAG_ASYNC : 0); -static HWND transferJobWindowHandle = 0; -const LPCWSTR kResourceHandleWindowClassName = L"ResourceHandleWindowClass"; + if (asynchronous) + InternetSetStatusCallback(internetHandle, &ResourceHandle::internetStatusCallback); -// Message types for internal use (keep in sync with kMessageHandlers) -enum { - handleCreatedMessage = WM_USER, - requestRedirectedMessage, - requestCompleteMessage -}; + return internetHandle; +} -typedef void (ResourceHandle:: *ResourceHandleEventHandler)(LPARAM); -static const ResourceHandleEventHandler messageHandlers[] = { - &ResourceHandle::onHandleCreated, - &ResourceHandle::onRequestRedirected, - &ResourceHandle::onRequestComplete -}; +static HINTERNET asynchronousInternetHandle(const String& userAgent) +{ + static HINTERNET internetHandle = createInternetHandle(userAgent, true); + return internetHandle; +} static String queryHTTPHeader(HINTERNET requestHandle, DWORD infoLevel) { @@ -79,69 +74,13 @@ static String queryHTTPHeader(HINTERNET requestHandle, DWORD infoLevel) return String::adopt(characters); } -static int addToOutstandingJobs(ResourceHandle* job) -{ - if (!jobIdMap) - jobIdMap = new HashMap<int, ResourceHandle*>; - transferJobId++; - jobIdMap->set(transferJobId, job); - return transferJobId; -} - -static void removeFromOutstandingJobs(int jobId) -{ - if (!jobIdMap) - return; - jobIdMap->remove(jobId); -} - -static ResourceHandle* lookupResourceHandle(int jobId) -{ - if (!jobIdMap) - return 0; - return jobIdMap->get(jobId); -} - -static LRESULT CALLBACK ResourceHandleWndProc(HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - if (message >= handleCreatedMessage) { - UINT index = message - handleCreatedMessage; - if (index < _countof(messageHandlers)) { - unsigned jobId = (unsigned) wParam; - ResourceHandle* job = lookupResourceHandle(jobId); - if (job) { - ASSERT(job->d->m_jobId == jobId); - ASSERT(job->d->m_threadId == GetCurrentThreadId()); - (job->*(messageHandlers[index]))(lParam); - } - return 0; - } - } - return DefWindowProc(hWnd, message, wParam, lParam); -} - -static void initializeOffScreenResourceHandleWindow() -{ - if (transferJobWindowHandle) - return; - - WNDCLASSEX wcex; - memset(&wcex, 0, sizeof(WNDCLASSEX)); - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.lpfnWndProc = ResourceHandleWndProc; - wcex.hInstance = WebCore::instanceHandle(); - wcex.lpszClassName = kResourceHandleWindowClassName; - RegisterClassEx(&wcex); - - transferJobWindowHandle = CreateWindow(kResourceHandleWindowClassName, 0, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, - HWND_MESSAGE, 0, WebCore::instanceHandle(), 0); -} - class WebCoreSynchronousLoader : public ResourceHandleClient, public Noncopyable { public: WebCoreSynchronousLoader(ResourceError&, ResourceResponse&, Vector<char>&, const String& userAgent); + ~WebCoreSynchronousLoader(); + + HINTERNET internetHandle() const { return m_internetHandle; } virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived); @@ -152,13 +91,20 @@ private: ResourceError& m_error; ResourceResponse& m_response; Vector<char>& m_data; + HINTERNET m_internetHandle; }; WebCoreSynchronousLoader::WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data, const String& userAgent) : m_error(error) , m_response(response) , m_data(data) + , m_internetHandle(createInternetHandle(userAgent, false)) +{ +} + +WebCoreSynchronousLoader::~WebCoreSynchronousLoader() { + InternetCloseHandle(m_internetHandle); } void WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) @@ -183,107 +129,79 @@ void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& err ResourceHandleInternal::~ResourceHandleInternal() { - if (m_fileHandle != INVALID_HANDLE_VALUE) - CloseHandle(m_fileHandle); } ResourceHandle::~ResourceHandle() { - if (d->m_jobId) - removeFromOutstandingJobs(d->m_jobId); } -void ResourceHandle::onHandleCreated(LPARAM lParam) +static void callOnRedirect(void* context) { - if (!d->m_resourceHandle) { - d->m_resourceHandle = HINTERNET(lParam); - if (d->status != 0) { - // We were canceled before Windows actually created a handle for us, close and delete now. - InternetCloseHandle(d->m_resourceHandle); - delete this; - return; - } + ResourceHandle* handle = static_cast<ResourceHandle*>(context); + handle->onRedirect(); +} - if (request().httpMethod() == "POST") { - // FIXME: Too late to set referrer properly. - String urlStr = request().url().path(); - int fragmentIndex = urlStr.find('#'); - if (fragmentIndex != -1) - urlStr = urlStr.left(fragmentIndex); - static LPCSTR accept[2]={"*/*", NULL}; - HINTERNET urlHandle = HttpOpenRequestA(d->m_resourceHandle, - "POST", urlStr.latin1().data(), 0, 0, accept, - INTERNET_FLAG_KEEP_CONNECTION | - INTERNET_FLAG_FORMS_SUBMIT | - INTERNET_FLAG_RELOAD | - INTERNET_FLAG_NO_CACHE_WRITE | - INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | - INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP, - (DWORD_PTR)d->m_jobId); - if (urlHandle == INVALID_HANDLE_VALUE) { - InternetCloseHandle(d->m_resourceHandle); - delete this; - } - } - } else if (!d->m_secondaryHandle) { - assert(request().httpMethod() == "POST"); - d->m_secondaryHandle = HINTERNET(lParam); - - // Need to actually send the request now. - String headers = "Content-Type: application/x-www-form-urlencoded\n"; - headers += "Referer: "; - headers += d->m_postReferrer; - headers += "\n"; - const CString& headersLatin1 = headers.latin1(); - String formData = request().httpBody()->flattenToString(); - INTERNET_BUFFERSA buffers; - memset(&buffers, 0, sizeof(buffers)); - buffers.dwStructSize = sizeof(INTERNET_BUFFERSA); - buffers.lpcszHeader = headersLatin1.data(); - buffers.dwHeadersLength = headers.length(); - buffers.dwBufferTotal = formData.length(); - - d->m_bytesRemainingToWrite = formData.length(); - d->m_formDataString = (char*)malloc(formData.length()); - d->m_formDataLength = formData.length(); - strncpy(d->m_formDataString, formData.latin1().data(), formData.length()); - d->m_writing = true; - HttpSendRequestExA(d->m_secondaryHandle, &buffers, 0, 0, (DWORD_PTR)d->m_jobId); - // FIXME: add proper error handling +static void callOnRequestComplete(void* context) +{ + ResourceHandle* handle = static_cast<ResourceHandle*>(context); + handle->onRequestComplete(); +} + +void ResourceHandle::internetStatusCallback(HINTERNET internetHandle, DWORD_PTR context, DWORD internetStatus, + LPVOID statusInformation, DWORD statusInformationLength) +{ + ResourceHandle* handle = reinterpret_cast<ResourceHandle*>(context); + + switch (internetStatus) { + case INTERNET_STATUS_REDIRECT: + handle->d->m_redirectUrl = String(static_cast<UChar*>(statusInformation), statusInformationLength); + callOnMainThread(callOnRedirect, handle); + break; + + case INTERNET_STATUS_REQUEST_COMPLETE: + callOnMainThread(callOnRequestComplete, handle); + break; + + default: + break; } } -void ResourceHandle::onRequestRedirected(LPARAM lParam) +void ResourceHandle::onRedirect() { - // If already canceled, then ignore this event. - if (d->status != 0) - return; + ResourceRequest newRequest = firstRequest(); + newRequest.setURL(KURL(ParsedURLString, d->m_redirectUrl)); + + ResourceResponse response(firstRequest().url(), String(), 0, String(), String()); - ResourceRequest request((StringImpl*) lParam); - ResourceResponse redirectResponse; - client()->willSendRequest(this, request, redirectResponse); + if (ResourceHandleClient* resourceHandleClient = client()) + resourceHandleClient->willSendRequest(this, newRequest, response); } -void ResourceHandle::onRequestComplete(LPARAM lParam) +bool ResourceHandle::onRequestComplete() { - if (d->m_writing) { + if (!d->m_internetHandle) { // 0 if canceled. + deref(); // balances ref in start + return false; + } + + if (d->m_bytesRemainingToWrite) { DWORD bytesWritten; - InternetWriteFile(d->m_secondaryHandle, - d->m_formDataString + (d->m_formDataLength - d->m_bytesRemainingToWrite), + InternetWriteFile(d->m_requestHandle, + d->m_formData.data() + (d->m_formData.size() - d->m_bytesRemainingToWrite), d->m_bytesRemainingToWrite, &bytesWritten); d->m_bytesRemainingToWrite -= bytesWritten; - if (!d->m_bytesRemainingToWrite) { - // End the request. - d->m_writing = false; - HttpEndRequest(d->m_secondaryHandle, 0, 0, (DWORD_PTR)d->m_jobId); - free(d->m_formDataString); - d->m_formDataString = 0; - } - return; + if (d->m_bytesRemainingToWrite) + return true; + d->m_formData.clear(); } - HINTERNET handle = (request().httpMethod() == "POST") ? d->m_secondaryHandle : d->m_resourceHandle; + if (!d->m_sentEndRequest) { + HttpEndRequestW(d->m_requestHandle, 0, 0, reinterpret_cast<DWORD_PTR>(this)); + d->m_sentEndRequest = true; + return true; + } static const int bufferSize = 32768; char buffer[bufferSize]; @@ -293,9 +211,10 @@ void ResourceHandle::onRequestComplete(LPARAM lParam) buffers.dwBufferLength = bufferSize; BOOL ok = FALSE; - while ((ok = InternetReadFileExA(handle, &buffers, IRF_NO_WAIT, (DWORD_PTR)this)) && buffers.dwBufferLength) { - if (!hasReceivedResponse()) { - setHasReceivedResponse(); + while ((ok = InternetReadFileExA(d->m_requestHandle, &buffers, d->m_loadSynchronously ? 0 : IRF_NO_WAIT, reinterpret_cast<DWORD_PTR>(this))) && buffers.dwBufferLength) { + if (!d->m_hasReceivedResponse) { + d->m_hasReceivedResponse = true; + ResourceResponse response; response.setURL(firstRequest().url()); @@ -317,160 +236,112 @@ void ResourceHandle::onRequestComplete(LPARAM lParam) response.setTextEncodingName(extractCharsetFromMediaType(httpContentType)); } - client()->didReceiveResponse(this, response); + if (ResourceHandleClient* resourceHandleClient = client()) + resourceHandleClient->didReceiveResponse(this, response); } - client()->didReceiveData(this, buffer, buffers.dwBufferLength, 0); + + if (ResourceHandleClient* resourceHandleClient = client()) + resourceHandleClient->didReceiveData(this, buffer, buffers.dwBufferLength, 0); buffers.dwBufferLength = bufferSize; } - PlatformDataStruct platformData; - platformData.errorString = 0; - platformData.error = 0; - platformData.loaded = ok; - - if (!ok) { - int error = GetLastError(); - if (error == ERROR_IO_PENDING) - return; - DWORD errorStringChars = 0; - if (!InternetGetLastResponseInfo(&platformData.error, 0, &errorStringChars)) { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - platformData.errorString = new TCHAR[errorStringChars]; - InternetGetLastResponseInfo(&platformData.error, platformData.errorString, &errorStringChars); - } - } -#ifdef RESOURCE_LOADER_DEBUG - char buf[64]; - _snprintf(buf, sizeof(buf), "Load error: %i\n", error); - OutputDebugStringA(buf); -#endif - } - - if (d->m_secondaryHandle) - InternetCloseHandle(d->m_secondaryHandle); - InternetCloseHandle(d->m_resourceHandle); + if (!ok && GetLastError() == ERROR_IO_PENDING) + return true; - client()->didFinishLoading(this, 0); - delete this; + if (ResourceHandleClient* resourceHandleClient = client()) + resourceHandleClient->didFinishLoading(this, 0); + + InternetCloseHandle(d->m_requestHandle); + InternetCloseHandle(d->m_connectHandle); + deref(); // balances ref in start + return false; } -static void __stdcall transferJobStatusCallback(HINTERNET internetHandle, - DWORD_PTR jobId, - DWORD internetStatus, - LPVOID statusInformation, - DWORD statusInformationLength) +bool ResourceHandle::start(NetworkingContext* context) { -#ifdef RESOURCE_LOADER_DEBUG - char buf[64]; - _snprintf(buf, sizeof(buf), "status-callback: status=%u, job=%p\n", - internetStatus, jobId); - OutputDebugStringA(buf); -#endif + if (request().url().isLocalFile()) { + ref(); // balanced by deref in fileLoadTimer + if (d->m_loadSynchronously) + fileLoadTimer(0); + else + d->m_fileLoadTimer.startOneShot(0.0); + return true; + } - UINT msg; - LPARAM lParam; + if (!d->m_internetHandle) + d->m_internetHandle = asynchronousInternetHandle(context->userAgent()); - switch (internetStatus) { - case INTERNET_STATUS_HANDLE_CREATED: - // tell the main thread about the newly created handle - msg = handleCreatedMessage; - lParam = (LPARAM) LPINTERNET_ASYNC_RESULT(statusInformation)->dwResult; - break; - case INTERNET_STATUS_REQUEST_COMPLETE: -#ifdef RESOURCE_LOADER_DEBUG - _snprintf(buf, sizeof(buf), "request-complete: result=%p, error=%u\n", - LPINTERNET_ASYNC_RESULT(statusInformation)->dwResult, - LPINTERNET_ASYNC_RESULT(statusInformation)->dwError); - OutputDebugStringA(buf); -#endif - // tell the main thread that the request is done - msg = requestCompleteMessage; - lParam = 0; - break; - case INTERNET_STATUS_REDIRECT: - // tell the main thread to observe this redirect (FIXME: we probably - // need to block the redirect at this point so the application can - // decide whether or not to follow the redirect) - msg = requestRedirectedMessage; - lParam = (LPARAM) StringImpl::create((const UChar*) statusInformation, - statusInformationLength).releaseRef(); - break; - case INTERNET_STATUS_USER_INPUT_REQUIRED: - // FIXME: prompt the user if necessary - ResumeSuspendedDownload(internetHandle, 0); - case INTERNET_STATUS_STATE_CHANGE: - // may need to call ResumeSuspendedDownload here as well - default: - return; + if (!d->m_internetHandle) + return false; + + DWORD flags = INTERNET_FLAG_KEEP_CONNECTION + | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS + | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP; + + d->m_connectHandle = InternetConnectW(d->m_internetHandle, firstRequest().url().host().charactersWithNullTermination(), firstRequest().url().port(), + 0, 0, INTERNET_SERVICE_HTTP, flags, reinterpret_cast<DWORD_PTR>(this)); + + if (!d->m_connectHandle) + return false; + + String urlStr = firstRequest().url().path(); + String urlQuery = firstRequest().url().query(); + + if (!urlQuery.isEmpty()) { + urlStr.append('?'); + urlStr.append(urlQuery); } - PostMessage(transferJobWindowHandle, msg, (WPARAM) jobId, lParam); -} + String httpMethod = firstRequest().httpMethod(); + String httpReferrer = firstRequest().httpReferrer(); -bool ResourceHandle::start(NetworkingContext* context) -{ - ref(); - if (request().url().isLocalFile()) { - d->m_fileLoadTimer.startOneShot(0.0); - return true; - } else { - static HINTERNET internetHandle = 0; - if (!internetHandle) { - String userAgentStr = context->userAgent() + String("", 1); - LPCWSTR userAgent = reinterpret_cast<const WCHAR*>(userAgentStr.characters()); - // leak the Internet for now - internetHandle = InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, INTERNET_FLAG_ASYNC); - } - if (!internetHandle) { - delete this; - return false; - } - static INTERNET_STATUS_CALLBACK callbackHandle = - InternetSetStatusCallback(internetHandle, transferJobStatusCallback); - - initializeOffScreenResourceHandleWindow(); - d->m_jobId = addToOutstandingJobs(this); - - DWORD flags = - INTERNET_FLAG_KEEP_CONNECTION | - INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | - INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP; - - // For form posting, we can't use InternetOpenURL. We have to use - // InternetConnect followed by HttpSendRequest. - HINTERNET urlHandle; - String referrer = context->referrer(); - if (request().httpMethod() == "POST") { - d->m_postReferrer = referrer; - String host = request().url().host(); - urlHandle = InternetConnectA(internetHandle, host.latin1().data(), - request().url().port(), - NULL, // no username - NULL, // no password - INTERNET_SERVICE_HTTP, - flags, (DWORD_PTR)d->m_jobId); - } else { - String urlStr = request().url().string(); - int fragmentIndex = urlStr.find('#'); - if (fragmentIndex != -1) - urlStr = urlStr.left(fragmentIndex); - String headers; - if (!referrer.isEmpty()) - headers += String("Referer: ") + referrer + "\r\n"; - - urlHandle = InternetOpenUrlA(internetHandle, urlStr.latin1().data(), - headers.latin1().data(), headers.length(), - flags, (DWORD_PTR)d->m_jobId); - } + LPCWSTR httpAccept[] = { L"*/*", 0 }; - if (urlHandle == INVALID_HANDLE_VALUE) { - delete this; - return false; - } - d->m_threadId = GetCurrentThreadId(); + d->m_requestHandle = HttpOpenRequestW(d->m_connectHandle, httpMethod.charactersWithNullTermination(), urlStr.charactersWithNullTermination(), + 0, httpReferrer.charactersWithNullTermination(), httpAccept, flags, reinterpret_cast<DWORD_PTR>(this)); - return true; + if (!d->m_requestHandle) { + InternetCloseHandle(d->m_connectHandle); + return false; + } + + if (firstRequest().httpBody()) { + firstRequest().httpBody()->flatten(d->m_formData); + d->m_bytesRemainingToWrite = d->m_formData.size(); + } + + Vector<UChar> httpHeaders; + const HTTPHeaderMap& httpHeaderFields = firstRequest().httpHeaderFields(); + + for (HTTPHeaderMap::const_iterator it = httpHeaderFields.begin(); it != httpHeaderFields.end(); ++it) { + if (equalIgnoringCase(it->first, "Accept") || equalIgnoringCase(it->first, "Referer") || equalIgnoringCase(it->first, "User-Agent")) + continue; + + if (!httpHeaders.isEmpty()) + httpHeaders.append('\n'); + + httpHeaders.append(it->first.characters(), it->first.length()); + httpHeaders.append(':'); + httpHeaders.append(it->second.characters(), it->second.length()); } + + INTERNET_BUFFERSW internetBuffers; + ZeroMemory(&internetBuffers, sizeof(internetBuffers)); + internetBuffers.dwStructSize = sizeof(internetBuffers); + internetBuffers.lpcszHeader = httpHeaders.data(); + internetBuffers.dwHeadersLength = httpHeaders.size(); + internetBuffers.dwBufferTotal = d->m_bytesRemainingToWrite; + + HttpSendRequestExW(d->m_requestHandle, &internetBuffers, 0, 0, reinterpret_cast<DWORD_PTR>(this)); + + ref(); // balanced by deref in onRequestComplete + + if (d->m_loadSynchronously) + while (onRequestComplete()) { + // Loop until finished. + } + + return true; } void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>*) @@ -517,37 +388,29 @@ void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>*) void ResourceHandle::cancel() { - if (d->m_resourceHandle) - InternetCloseHandle(d->m_resourceHandle); - else + if (d->m_requestHandle) { + d->m_internetHandle = 0; + InternetCloseHandle(d->m_requestHandle); + InternetCloseHandle(d->m_connectHandle); + } else d->m_fileLoadTimer.stop(); - - client()->didFinishLoading(this, 0); - - if (!d->m_resourceHandle) - // Async load canceled before we have a handle -- mark ourselves as in error, to be deleted later. - // FIXME: need real cancel error - client()->didFail(this, ResourceError()); } -void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame) +void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data) { UNUSED_PARAM(storedCredentials); WebCoreSynchronousLoader syncLoader(error, response, data, request.httpUserAgent()); ResourceHandle handle(request, &syncLoader, true, false); - handle.start(frame); -} - -void ResourceHandle::setHasReceivedResponse(bool b) -{ - d->m_hasReceivedResponse = b; + handle.setSynchronousInternetHandle(syncLoader.internetHandle()); + handle.start(context); } -bool ResourceHandle::hasReceivedResponse() const +void ResourceHandle::setSynchronousInternetHandle(HINTERNET internetHandle) { - return d->m_hasReceivedResponse; + d->m_internetHandle = internetHandle; + d->m_loadSynchronously = true; } bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*) diff --git a/WebCore/platform/network/win/ResourceHandleWin.h b/WebCore/platform/network/win/ResourceHandleWin.h deleted file mode 100644 index 2964bcb..0000000 --- a/WebCore/platform/network/win/ResourceHandleWin.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ResourceHandleWin_h -#define ResourceHandleWin_h - -#include <windows.h> - -namespace WebCore { - -struct PlatformDataStruct -{ - DWORD error; - BOOL loaded; - LPTSTR errorString; -}; - -struct PlatformResponseStruct -{ -}; - -} - -#endif |