| 229 | } |
| 230 | |
| 231 | bool HTTPDownloaderWinHttp::StartRequest(HTTPDownloader::Request* request) |
| 232 | { |
| 233 | Request* req = static_cast<Request*>(request); |
| 234 | |
| 235 | std::wstring host_name; |
| 236 | host_name.resize(req->url.size()); |
| 237 | req->object_name.resize(req->url.size()); |
| 238 | |
| 239 | URL_COMPONENTSW uc = {}; |
| 240 | uc.dwStructSize = sizeof(uc); |
| 241 | uc.lpszHostName = host_name.data(); |
| 242 | uc.dwHostNameLength = static_cast<DWORD>(host_name.size()); |
| 243 | uc.lpszUrlPath = req->object_name.data(); |
| 244 | uc.dwUrlPathLength = static_cast<DWORD>(req->object_name.size()); |
| 245 | |
| 246 | const std::wstring url_wide(StringUtil::UTF8StringToWideString(req->url)); |
| 247 | if (!WinHttpCrackUrl(url_wide.c_str(), static_cast<DWORD>(url_wide.size()), 0, &uc)) |
| 248 | { |
| 249 | Console.Error("WinHttpCrackUrl() failed: %u", GetLastError()); |
| 250 | req->callback(HTTP_STATUS_ERROR, req->content_type, Request::Data()); |
| 251 | delete req; |
| 252 | return false; |
| 253 | } |
| 254 | |
| 255 | host_name.resize(uc.dwHostNameLength); |
| 256 | req->object_name.resize(uc.dwUrlPathLength); |
| 257 | |
| 258 | req->hConnection = WinHttpConnect(m_hSession, host_name.c_str(), uc.nPort, 0); |
| 259 | if (!req->hConnection) |
| 260 | { |
| 261 | Console.Error("Failed to start HTTP request for '%s': %u", req->url.c_str(), GetLastError()); |
| 262 | req->callback(HTTP_STATUS_ERROR, req->content_type, Request::Data()); |
| 263 | delete req; |
| 264 | return false; |
| 265 | } |
| 266 | |
| 267 | const DWORD request_flags = uc.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0; |
| 268 | req->hRequest = |
| 269 | WinHttpOpenRequest(req->hConnection, (req->type == HTTPDownloader::Request::Type::Post) ? L"POST" : L"GET", |
| 270 | req->object_name.c_str(), NULL, NULL, NULL, request_flags); |
| 271 | if (!req->hRequest) |
| 272 | { |
| 273 | Console.Error("WinHttpOpenRequest() failed: %u", GetLastError()); |
| 274 | WinHttpCloseHandle(req->hConnection); |
| 275 | return false; |
| 276 | } |
| 277 | |
| 278 | BOOL result; |
| 279 | if (req->type == HTTPDownloader::Request::Type::Post) |
| 280 | { |
| 281 | const std::wstring_view additional_headers(L"Content-Type: application/x-www-form-urlencoded\r\n"); |
| 282 | result = WinHttpSendRequest(req->hRequest, additional_headers.data(), static_cast<DWORD>(additional_headers.size()), |
| 283 | req->post_data.data(), static_cast<DWORD>(req->post_data.size()), |
| 284 | static_cast<DWORD>(req->post_data.size()), reinterpret_cast<DWORD_PTR>(req)); |
| 285 | } |
| 286 | else |
| 287 | { |
| 288 | result = WinHttpSendRequest(req->hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, |
nothing calls this directly
no test coverage detected