summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/network
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/network')
-rw-r--r--WebCore/platform/network/ResourceHandle.h16
-rw-r--r--WebCore/platform/network/ResourceHandleInternal.h31
-rw-r--r--WebCore/platform/network/mac/WebCoreURLResponse.mm19
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp7
-rw-r--r--WebCore/platform/network/qt/ResourceRequestQt.cpp2
-rw-r--r--WebCore/platform/network/qt/SocketStreamHandleQt.cpp7
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp5
-rw-r--r--WebCore/platform/network/win/ResourceHandleWin.cpp507
-rw-r--r--WebCore/platform/network/win/ResourceHandleWin.h46
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