2019-02-11 10:46:39 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
#include <winhttp.h>
|
|
|
|
|
|
|
|
using InternetHandle = AutoHandle<Functor<WinHttpCloseHandle>>;
|
|
|
|
|
2019-02-13 12:54:33 +08:00
|
|
|
inline std::optional<std::wstring> ReceiveHttpRequest(HINTERNET request)
|
2019-02-11 10:46:39 +08:00
|
|
|
{
|
|
|
|
WinHttpReceiveResponse(request, NULL);
|
|
|
|
std::string data;
|
|
|
|
DWORD dwSize, dwDownloaded;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
dwSize = 0;
|
|
|
|
WinHttpQueryDataAvailable(request, &dwSize);
|
|
|
|
if (!dwSize) break;
|
|
|
|
std::vector<char> buffer(dwSize);
|
|
|
|
WinHttpReadData(request, buffer.data(), dwSize, &dwDownloaded);
|
2019-02-13 12:54:33 +08:00
|
|
|
data.append(buffer.data(), dwDownloaded);
|
2019-02-11 10:46:39 +08:00
|
|
|
} while (dwSize > 0);
|
|
|
|
|
|
|
|
if (data.empty()) return {};
|
|
|
|
return StringToWideString(data);
|
|
|
|
}
|
|
|
|
|
2019-06-06 08:26:50 +08:00
|
|
|
inline void Unescape(std::wstring& text)
|
2019-02-11 10:46:39 +08:00
|
|
|
{
|
|
|
|
for (int i = 0; i < text.size(); ++i)
|
|
|
|
{
|
|
|
|
if (text[i] == L'\\')
|
|
|
|
{
|
|
|
|
text[i] = 0x200b;
|
|
|
|
if (text[i + 1] == L'r') text[i + 1] = 0x200b; // for some reason \r gets displayed as a newline
|
|
|
|
if (text[i + 1] == L'n') text[i + 1] = L'\n';
|
|
|
|
if (text[i + 1] == L't') text[i + 1] = L'\t';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-06-06 08:26:50 +08:00
|
|
|
|
|
|
|
|
|
|
|
class RateLimiter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
RateLimiter(int tokenCount, int delay) : tokenCount(tokenCount), delay(delay) {}
|
|
|
|
|
|
|
|
bool Request()
|
|
|
|
{
|
|
|
|
auto tokens = this->tokens.Acquire();
|
|
|
|
tokens->push_back(GetTickCount());
|
|
|
|
if (tokens->size() > tokenCount * 5) tokens->erase(tokens->begin(), tokens->begin() + tokenCount * 3);
|
|
|
|
tokens->erase(std::remove_if(tokens->begin(), tokens->end(), [this](DWORD token) { return GetTickCount() - token > delay; }), tokens->end());
|
|
|
|
return tokens->size() < tokenCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
const int tokenCount, delay;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Synchronized<std::vector<DWORD>> tokens;
|
|
|
|
};
|