📄 resourcehandlewin.cpp
字号:
char buffer[bufferSize]; INTERNET_BUFFERSA buffers; buffers.dwStructSize = sizeof(INTERNET_BUFFERSA); buffers.lpvBuffer = buffer; buffers.dwBufferLength = bufferSize; bool receivedAnyData = false; while ((ok = InternetReadFileExA(handle, &buffers, IRF_NO_WAIT, (DWORD_PTR)this)) && buffers.dwBufferLength) { if (!hasReceivedResponse()) { setHasReceivedResponse(); ResourceResponse response; client()->didReceiveResponse(this, response); } client()->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); } } _RPTF1(_CRT_WARN, "Load error: %i\n", error); } if (d->m_secondaryHandle) InternetCloseHandle(d->m_secondaryHandle); InternetCloseHandle(d->m_resourceHandle); client()->didFinishLoading(this); delete this;}static void __stdcall transferJobStatusCallback(HINTERNET internetHandle, DWORD_PTR jobId, DWORD internetStatus, LPVOID statusInformation, DWORD statusInformationLength){#ifdef RESOURCE_LOADER_DEBUG char buf[64]; _snprintf(buf, sizeof(buf), "status-callback: status=%u, job=%p\n", internetStatus, jobId); OutputDebugStringA(buf);#endif UINT msg; LPARAM lParam; 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) new StringImpl((const UChar*) statusInformation, statusInformationLength); 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; } PostMessage(transferJobWindowHandle, msg, (WPARAM) jobId, lParam);}bool ResourceHandle::start(Frame* frame){ ref(); if (url().isLocalFile()) { String path = url().path(); // windows does not enjoy a leading slash on paths if (path[0] == '/') path = path.substring(1); // FIXME: This is wrong. Need to use wide version of this call. d->m_fileHandle = CreateFileA(path.utf8().data(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // FIXME: perhaps this error should be reported asynchronously for // consistency. if (d->m_fileHandle == INVALID_HANDLE_VALUE) { delete this; return false; } d->m_fileLoadTimer.startOneShot(0.0); return true; } else { static HINTERNET internetHandle = 0; if (!internetHandle) { String userAgentStr = frame->loader()->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 = frame->loader()->referrer(); if (method() == "POST") { d->m_postReferrer = referrer; String host = url().host(); urlHandle = InternetConnectA(internetHandle, host.latin1().data(), url().port(), NULL, // no username NULL, // no password INTERNET_SERVICE_HTTP, flags, (DWORD_PTR)d->m_jobId); } else { String urlStr = 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); } if (urlHandle == INVALID_HANDLE_VALUE) { delete this; return false; } d->m_threadId = GetCurrentThreadId(); return true; }}void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>* timer){ ResourceResponse response; client()->didReceiveResponse(this, response); bool result = false; DWORD bytesRead = 0; do { const int bufferSize = 8192; char buffer[bufferSize]; result = ReadFile(d->m_fileHandle, &buffer, bufferSize, &bytesRead, NULL); if (result && bytesRead) client()->didReceiveData(this, buffer, bytesRead, 0); // Check for end of file. } while (result && bytesRead); // FIXME: handle errors better CloseHandle(d->m_fileHandle); d->m_fileHandle = INVALID_HANDLE_VALUE; client()->didFinishLoading(this);}void ResourceHandle::cancel(){ if (d->m_resourceHandle) InternetCloseHandle(d->m_resourceHandle); else d->m_fileLoadTimer.stop(); client()->didFinishLoading(this); 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::setHasReceivedResponse(bool b){ d->m_hasReceivedResponse = b;}bool ResourceHandle::hasReceivedResponse() const{ return d->m_hasReceivedResponse;}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -