summaryrefslogtreecommitdiff
path: root/plugins/CurrencyRates/src/HTTPSession.cpp
blob: 06f1d5409d64b0bc154cd3eace7ef838d5ac773c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "StdAfx.h"

class CHTTPSession::CImpl
{
public:
	CImpl() {}
	virtual ~CImpl() {}

	virtual bool OpenURL(const tstring& rsURL) = 0;
	virtual bool ReadResponce(tstring& rsResponce)const = 0;
};

int find_header(const NETLIBHTTPREQUEST* pRequest, const char* hdr)
{
	for (int i = 0; i < pRequest->headersCount; ++i)
	{
		if (0 == _stricmp(pRequest->headers[i].szName, hdr))
		{
			return i;
		}
	}

	return -1;
}
 
class CImplMI : public CHTTPSession::CImpl
{
public:
	CImplMI() {}

	static bool Init()
	{
		assert(nullptr == g_hNetLib);

		NETLIBUSER nlu = {};
		nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_UNICODE;
		nlu.szSettingsModule = CURRENCYRATES_PROTOCOL_NAME;
		nlu.szDescriptiveName.w = TranslateT("CurrencyRates HTTP connections");
		g_hNetLib = Netlib_RegisterUser(&nlu);
		return (nullptr != g_hNetLib);
	}

	static bool IsValid() { return nullptr != g_hNetLib; }

	virtual bool OpenURL(const tstring& rsURL)
	{
		m_aURL.clear();

		std::string s = currencyrates_t2a(rsURL.c_str());
		const char* psz = s.c_str();
		m_aURL.insert(m_aURL.begin(), psz, psz + mir_strlen(psz) + 1);
		return true;
	}

	virtual bool ReadResponce(tstring &rsResponce)const
	{
		if (true == m_aURL.empty())
			return false;

		NETLIBHTTPHEADER headers[] =
		{
			{ "User-Agent", NETLIB_USER_AGENT },
			{ "Connection", "close" },
			{ "Cache-Control", "no-cache" },
			{ "Pragma", "no-cache" }
		};

		NETLIBHTTPREQUEST nlhr = {};
		nlhr.cbSize = sizeof(nlhr);
		nlhr.requestType = REQUEST_GET;
		nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_REDIRECT;
		nlhr.szUrl = &*(m_aURL.begin());
		nlhr.headersCount = _countof(headers);
		nlhr.headers = headers;

		bool bResult = false;
		NETLIBHTTPREQUEST *pReply = nullptr;
		{
			mir_cslock lck(m_mx);
			pReply = Netlib_HttpTransaction(g_hNetLib, &nlhr);
		}

		if (pReply) {
			if ((200 == pReply->resultCode) && (pReply->dataLength > 0)) {
				TBuffer apBuffer;
				apBuffer.insert(apBuffer.begin(), pReply->pData, pReply->pData + pReply->dataLength);
				apBuffer.push_back('\0');

				char* pResult = &*(apBuffer.begin());
				int nIndex = find_header(pReply, "Content-Type");
				if ((-1 != nIndex) && (nullptr != strstr(_strlwr(pReply->headers[nIndex].szValue), "utf-8"))) {
					rsResponce = ptrW(mir_utf8decodeW(pResult));
				}
				else {
					rsResponce = currencyrates_a2t(pResult);
				}

				bResult = true;
			}

			Netlib_FreeHttpRequest(pReply);
		}
		return bResult;
	}

private:
	static HNETLIBUSER g_hNetLib;
	typedef std::vector<char> TBuffer;
	mutable TBuffer m_aURL;
	mutable mir_cs m_mx;
};

HNETLIBUSER CImplMI::g_hNetLib = nullptr;

CHTTPSession::CHTTPSession()
	: m_pImpl(new CImplMI)
{
}

CHTTPSession::~CHTTPSession()
{
}

bool CHTTPSession::OpenURL(const tstring& rsURL)
{
	return m_pImpl->OpenURL(rsURL);
}

bool CHTTPSession::ReadResponce(tstring& rsResponce)const
{
	return m_pImpl->ReadResponce(rsResponce);
}

bool CHTTPSession::Init()
{
	return CImplMI::Init();
}