Mercurial > trustbridge
view ui/downloader_win.cpp @ 11:7e2f14c7aba2
Split up downloader component and further implement it
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Fri, 14 Feb 2014 11:20:15 +0000 |
parents | |
children | 95e1b6edf2fc |
line wrap: on
line source
/** * @file downloader_win.cpp * @brief Downloader implementation for Windows * * We use Windows API here instead of Qt because we want to avoid * QtNetworks SSL stack which is based on OpenSSL and so * we might be incompatible with GPL code. Also using the * native API means that the security of the SSL implementation * is tied to the security of the system. * */ #include "downloader.h" #ifdef Q_OS_WIN #ifndef MYVERSION #define MYVERSION "1" #endif #include <windows.h> #include <winhttp.h> #include <QDebug> #define DEBUG if (1) qDebug() << __PRETTY_FUNCTION__ const QString getLastErrorMsg() { LPWSTR bufPtr = NULL; DWORD err = GetLastError(); FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPWSTR)&bufPtr, 0, NULL); const QString result = (bufPtr) ? QString::fromUtf16((const ushort*)bufPtr).trimmed() : QString("Unknown Error %1").arg(err); LocalFree(bufPtr); return result; } /** @brief open a session with appropiate proxy settings * * @param[inout] *pHSession pointer to a HInternet structure * * On error call getLastError to get extended error information. * * @returns True on success, false on error. */ bool openSession(HINTERNET *pHSession) { WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig; DEBUG; if (!pHSession) { SetLastError(ERROR_INVALID_PARAMETER); return false; } qDebug() << "2"; memset(&proxyConfig, 0, sizeof (WINHTTP_CURRENT_USER_IE_PROXY_CONFIG)); if (WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig)) { if (proxyConfig.fAutoDetect) { // TODO Handle this qDebug() << "Autodetect is set"; } if (proxyConfig.lpszProxy || proxyConfig.lpszProxyBypass) { DEBUG << "Using proxies."; } if (proxyConfig.lpszProxy) { *pHSession = WinHttpOpen(L"M13 "MYVERSION, WINHTTP_ACCESS_TYPE_NAMED_PROXY, proxyConfig.lpszProxy, proxyConfig.lpszProxyBypass, 0); } } if (!*pHSession) { DEBUG << "No IE Proxy falling back to default proxy"; *pHSession = WinHttpOpen(L"M13 "MYVERSION, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); } // Cleanup if (proxyConfig.lpszAutoConfigUrl) { GlobalFree(proxyConfig.lpszAutoConfigUrl); } if (proxyConfig.lpszProxy) { GlobalFree(proxyConfig.lpszProxy); } if (proxyConfig.lpszProxyBypass) { GlobalFree(proxyConfig.lpszProxyBypass); } return *pHSession; } /** @brief initialize a connection in the session * * @param[in] HSession the session to work in. * @param[inout] *pHConnect pointer to the connection. * @param[in] url pointer to the URL in wchar representation. * * On error call getLastError to get extended error information. * * @returns True on success, false on error. */ bool initializeConnection(HINTERNET hSession, HINTERNET *pHConnect, LPCWSTR url) { DEBUG; if (!hSession || !pHConnect) { SetLastError(ERROR_INVALID_PARAMETER); return false; } // Initialize connection. No request is done here. *pHConnect = WinHttpConnect(hSession, url, INTERNET_DEFAULT_HTTPS_PORT, 0); return *pHConnect; } /** @brief Create a request * * @param[in] HSession the session to work in. * @param[in] HConnect the connection to use. * @param[inout] *pHRequest pointer to the request structure to be filled. * @param[in] requestType the HTTP request to be made default is GET * @param[in] resource pointer to the resource to request in wchar * representation. * * On error call getLastError to get extended error information. * This function still does not do any networking but only initializes * it. * * @returns True on success, false on error. */ bool createRequest(HINTERNET hSession, HINTERNET hConnect, HINTERNET *pHRequest, LPCWSTR requestType, LPCWSTR resource) { DEBUG; if (!hSession || !hConnect || !pHRequest) { SetLastError(ERROR_INVALID_PARAMETER); return false; } *pHRequest = WinHttpOpenRequest(hConnect, requestType, resource, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); return *pHRequest; } void Downloader::run() { BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; SYSTEMTIME lastModified; DWORD sizeOfSystemtime = sizeof (SYSTEMTIME); memset(&lastModified, 0, sizeof (SYSTEMTIME)); if (!openSession(&hSession)) { DEBUG << "Failed to open session: " << getLastErrorMsg(); return; } if (!initializeConnection(hSession, &hConnect, L"www.intevation.de")) { DEBUG << "Failed to initialize connection: " << getLastErrorMsg(); goto cleanup; } if (!createRequest(hSession, hConnect, &hRequest, L"GET", L"/")) { DEBUG << "Failed to create the request: " << getLastErrorMsg(); goto cleanup; } if (hRequest) { DEBUG << "Doing Request"; bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); } else { DEBUG << "Error: " << GetLastError(); } if (bResults) { DEBUG << "Recieving Response"; bResults = WinHttpReceiveResponse(hRequest, NULL); } else { DEBUG << "Error: " << GetLastError(); } if (bResults) { DEBUG << "Querying Headers"; bResults = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_LAST_MODIFIED | WINHTTP_QUERY_FLAG_SYSTEMTIME, NULL, &lastModified, &sizeOfSystemtime, WINHTTP_NO_HEADER_INDEX); } else { DWORD errCode = GetLastError(); switch (errCode) { case ERROR_WINHTTP_HEADER_NOT_FOUND: DEBUG << "Header not found"; break; case ERROR_WINHTTP_INCORRECT_HANDLE_STATE: DEBUG << "Incorrect handle state"; break; case ERROR_WINHTTP_INCORRECT_HANDLE_TYPE: DEBUG << "Incorrect handle type"; break; case ERROR_WINHTTP_INTERNAL_ERROR: DEBUG << "Internal error"; break; case ERROR_NOT_ENOUGH_MEMORY: DEBUG << "OOM"; break; default: DEBUG << "Error: " << getLastErrorMsg(); } } DEBUG << "Last modified year: " << lastModified.wYear; if (!bResults) { // Report any errors. DEBUG << "Error" << GetLastError(); emit error(tr("Unknown Problem when connecting"), Unknown); } cleanup: if (hRequest) { WinHttpCloseHandle(hRequest); } if (hConnect) { WinHttpCloseHandle(hConnect); } if (hSession) { WinHttpCloseHandle(hSession); } return; } #endif