📄 resourcehandlewin.cpp
字号:
/* * 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. */#include "config.h"#include "ResourceHandle.h"#include "ResourceHandleClient.h"#include "ResourceHandleInternal.h"#include "ResourceHandleWin.h"#include "CString.h"#include "DocLoader.h"#include "Document.h"#include "Frame.h"#include "FrameLoader.h"#include "Page.h"#include "ResourceError.h"#include "Timer.h"#include <windows.h>#include <wininet.h>namespace WebCore {static unsigned transferJobId = 0;static HashMap<int, ResourceHandle*>* jobIdMap = 0;static HWND transferJobWindowHandle = 0;const LPCWSTR kResourceHandleWindowClassName = L"ResourceHandleWindowClass";// Message types for internal use (keep in sync with kMessageHandlers)enum { handleCreatedMessage = WM_USER, requestRedirectedMessage, requestCompleteMessage};typedef void (ResourceHandle:: *ResourceHandleEventHandler)(LPARAM);static const ResourceHandleEventHandler messageHandlers[] = { &ResourceHandle::onHandleCreated, &ResourceHandle::onRequestRedirected, &ResourceHandle::onRequestComplete};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 = Page::instanceHandle(); wcex.lpszClassName = kResourceHandleWindowClassName; RegisterClassEx(&wcex); transferJobWindowHandle = CreateWindow(kResourceHandleWindowClassName, 0, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, Page::instanceHandle(), 0);}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){ 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; } if (method() == "POST") { // FIXME: Too late to set referrer properly. String urlStr = 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(method() == "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 = postData()->flattenToString(); INTERNET_BUFFERSA buffers; memset(&buffers, 0, sizeof(buffers)); buffers.dwStructSize = sizeof(INTERNET_BUFFERSA); buffers.lpcszHeader = headersLatin1; 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(), formData.length()); d->m_writing = true; HttpSendRequestExA(d->m_secondaryHandle, &buffers, 0, 0, (DWORD_PTR)d->m_jobId); // FIXME: add proper error handling }}void ResourceHandle::onRequestRedirected(LPARAM lParam){ // If already canceled, then ignore this event. if (d->status != 0) return; ResourceRequest request((StringImpl*) lParam); ResourceResponse redirectResponse; client()->willSendRequest(this, request, redirectResponse);}void ResourceHandle::onRequestComplete(LPARAM lParam){ if (d->m_writing) { DWORD bytesWritten; InternetWriteFile(d->m_secondaryHandle, d->m_formDataString + (d->m_formDataLength - 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; } HINTERNET handle = (method() == "POST") ? d->m_secondaryHandle : d->m_resourceHandle; BOOL ok = FALSE; static const int bufferSize = 32768;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -