| 65 | } |
| 66 | |
| 67 | void CALLBACK HTTPDownloaderWinHttp::HTTPStatusCallback(HINTERNET hRequest, DWORD_PTR dwContext, DWORD dwInternetStatus, |
| 68 | LPVOID lpvStatusInformation, DWORD dwStatusInformationLength) |
| 69 | { |
| 70 | Request* req = reinterpret_cast<Request*>(dwContext); |
| 71 | switch (dwInternetStatus) |
| 72 | { |
| 73 | case WINHTTP_CALLBACK_STATUS_HANDLE_CREATED: |
| 74 | return; |
| 75 | |
| 76 | case WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING: |
| 77 | { |
| 78 | if (!req) |
| 79 | return; |
| 80 | |
| 81 | pxAssert(hRequest == req->hRequest); |
| 82 | |
| 83 | HTTPDownloaderWinHttp* parent = static_cast<HTTPDownloaderWinHttp*>(req->parent); |
| 84 | std::unique_lock<std::mutex> lock(parent->m_pending_http_request_lock); |
| 85 | pxAssertRel(std::none_of(parent->m_pending_http_requests.begin(), parent->m_pending_http_requests.end(), |
| 86 | [req](HTTPDownloader::Request* it) { return it == req; }), |
| 87 | "Request is not pending at close time"); |
| 88 | |
| 89 | // we can clean up the connection as well |
| 90 | pxAssert(req->hConnection != NULL); |
| 91 | WinHttpCloseHandle(req->hConnection); |
| 92 | delete req; |
| 93 | return; |
| 94 | } |
| 95 | |
| 96 | case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: |
| 97 | { |
| 98 | const WINHTTP_ASYNC_RESULT* res = reinterpret_cast<const WINHTTP_ASYNC_RESULT*>(lpvStatusInformation); |
| 99 | Console.Error("WinHttp async function %p returned error %u", res->dwResult, res->dwError); |
| 100 | req->status_code = HTTP_STATUS_ERROR; |
| 101 | req->state.store(Request::State::Complete); |
| 102 | return; |
| 103 | } |
| 104 | case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE: |
| 105 | { |
| 106 | DbgCon.WriteLn("SendRequest complete"); |
| 107 | if (!WinHttpReceiveResponse(hRequest, nullptr)) |
| 108 | { |
| 109 | Console.Error("WinHttpReceiveResponse() failed: %u", GetLastError()); |
| 110 | req->status_code = HTTP_STATUS_ERROR; |
| 111 | req->state.store(Request::State::Complete); |
| 112 | } |
| 113 | |
| 114 | return; |
| 115 | } |
| 116 | case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE: |
| 117 | { |
| 118 | DbgCon.WriteLn("Headers available"); |
| 119 | |
| 120 | DWORD buffer_size = sizeof(req->status_code); |
| 121 | if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, |
| 122 | WINHTTP_HEADER_NAME_BY_INDEX, &req->status_code, &buffer_size, WINHTTP_NO_HEADER_INDEX)) |
| 123 | { |
| 124 | Console.Error("WinHttpQueryHeaders() for status code failed: %u", GetLastError()); |
nothing calls this directly
no test coverage detected