212 lines
4.6 KiB
C++
212 lines
4.6 KiB
C++
#include "precomp.h"
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
#include "download.h"
|
|
#include "uniconv.h"
|
|
#include "except.h"
|
|
|
|
#ifdef _WIN32
|
|
#include <winhttp.h>
|
|
#include <malloc.h>
|
|
#else
|
|
#include <curl/curl.h>
|
|
#endif
|
|
|
|
#ifndef _WIN32
|
|
class CurlWriteBuffer
|
|
{
|
|
public:
|
|
CurlWriteBuffer(void * buffer, size_t size)
|
|
{
|
|
this->buffer = (char *)buffer;
|
|
this->size = size;
|
|
offset = 0;
|
|
}
|
|
|
|
int Append(void * buffer, size_t size)
|
|
{
|
|
if (this->offset + size > this->size)
|
|
size = this->size - offset;
|
|
|
|
if (size > 0)
|
|
{
|
|
memcpy(this->buffer + offset, buffer, size);
|
|
offset += size;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
static size_t
|
|
Callback(void *contents, size_t size, size_t nmemb, void *userp)
|
|
{
|
|
return ((CurlWriteBuffer *)userp)->Append(contents, size * nmemb);
|
|
}
|
|
|
|
size_t offset;
|
|
size_t size;
|
|
char * buffer;
|
|
};
|
|
|
|
#endif
|
|
|
|
void UrlDownloadToString(const char * url, char * buffer, int * len)
|
|
{
|
|
#ifndef LICENSING_NO_NETWORKING
|
|
#ifdef _WIN32
|
|
HRESULT result = ERROR_SUCCESS;
|
|
|
|
URL_COMPONENTS urlComponents;
|
|
|
|
do {
|
|
ZeroMemory(&urlComponents, sizeof(urlComponents));
|
|
urlComponents.dwStructSize = sizeof(urlComponents);
|
|
|
|
urlComponents.dwHostNameLength = (DWORD)-1;
|
|
urlComponents.dwUrlPathLength = (DWORD)-1;
|
|
|
|
auto urlw = s2w(url);
|
|
|
|
if (!WinHttpCrackUrl(urlw.c_str(), urlw.size(), 0L, &urlComponents))
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
wstring hostName(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
|
|
|
|
unique_ptr<VOID, decltype(&WinHttpCloseHandle)> internet_ptr(WinHttpOpen(L"ANSCENTER Licensing SDK", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0L), WinHttpCloseHandle);
|
|
if (!internet_ptr)
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
unique_ptr<VOID, decltype(&WinHttpCloseHandle)> connection_ptr(WinHttpConnect(internet_ptr.get(), hostName.c_str(), urlComponents.nPort, 0L), WinHttpCloseHandle);
|
|
if (connection_ptr == NULL)
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
wstring objectPath(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
|
|
|
|
DWORD requestFlags = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
|
|
if (urlComponents.nScheme == INTERNET_SCHEME_HTTPS)
|
|
requestFlags |= WINHTTP_FLAG_SECURE;
|
|
|
|
unique_ptr<VOID, decltype(&WinHttpCloseHandle)> request_ptr(WinHttpOpenRequest(connection_ptr.get(), L"GET", objectPath.c_str(), NULL, NULL, NULL, requestFlags), WinHttpCloseHandle);
|
|
if (!request_ptr)
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
if (!WinHttpSendRequest(request_ptr.get(), NULL, 0L, NULL, 0, 0L, NULL))
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
if (!WinHttpReceiveResponse(request_ptr.get(), NULL))
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
DWORD status;
|
|
DWORD statusSize = sizeof(DWORD);
|
|
|
|
if (!WinHttpQueryHeaders(request_ptr.get(), WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &status, &statusSize, WINHTTP_NO_HEADER_INDEX))
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
if (status != HTTP_STATUS_OK)
|
|
{
|
|
WCHAR buffer[1024];
|
|
DWORD bufferSize = 1024;
|
|
|
|
if (!WinHttpQueryHeaders(request_ptr.get(), WINHTTP_QUERY_STATUS_TEXT, WINHTTP_HEADER_NAME_BY_INDEX, buffer, &bufferSize, WINHTTP_NO_HEADER_INDEX))
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
result = ERROR_WINHTTP_INVALID_URL;
|
|
break;
|
|
}
|
|
|
|
if (status != HTTP_STATUS_OK)
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
|
|
DWORD offset = 0, count;
|
|
char lbuf[0x100];
|
|
|
|
do {
|
|
if (WinHttpReadData(request_ptr.get(), lbuf, 0x100, &count))
|
|
{
|
|
if (count == 0)
|
|
{
|
|
*len = offset;
|
|
break;
|
|
}
|
|
|
|
if (offset + count > *len)
|
|
{
|
|
result = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
memcpy(buffer + offset, lbuf, count);
|
|
offset += count;
|
|
} else
|
|
{
|
|
result = GetLastError();
|
|
break;
|
|
}
|
|
} while (true);
|
|
} while (false);
|
|
|
|
if (result != ERROR_SUCCESS)
|
|
throw new LicensingException(result, "networking error while downloading url contents");
|
|
#else
|
|
CURL *curl;
|
|
CURLcode res;
|
|
|
|
if ((curl = curl_easy_init()) == NULL)
|
|
throw new LicensingException(STATUS_NET_ERROR, "cURL initalization failed");
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
CurlWriteBuffer curlBuffer(buffer, *len);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteBuffer::Callback);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &curlBuffer);
|
|
|
|
res = curl_easy_perform(curl);
|
|
|
|
if(res != CURLE_OK)
|
|
{
|
|
curl_easy_cleanup(curl);
|
|
throw new LicensingException(STATUS_NET_ERROR, curl_easy_strerror(res));
|
|
}
|
|
|
|
*len = curlBuffer.offset;
|
|
|
|
curl_easy_cleanup(curl);
|
|
#endif
|
|
#else // !LICENSING_NO_NETWORKING
|
|
throw new LicensingException(STATUS_GENERIC_ERROR, "networking support not built in");
|
|
#endif
|
|
}
|