summaryrefslogtreecommitdiff
path: root/plugins/Quotes/src/HTTPSession.cpp
blob: 16583b071ab24e6dd8834641b008a8d97b89f1c5 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#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(NULL == g_hNetLib);

		NETLIBUSER nlu = { 0 };
		nlu.cbSize = sizeof(nlu);
		nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_TCHAR;
		nlu.szSettingsModule = QUOTES_PROTOCOL_NAME;
		nlu.ptszDescriptiveName = TranslateT("Quotes HTTP connections");
		g_hNetLib = reinterpret_cast<HANDLE>(CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu));
		return (NULL != g_hNetLib);
	}

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

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

		std::string s = quotes_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;

		NETLIBHTTPREQUEST nlhr = { 0 };
		nlhr.cbSize = sizeof(nlhr);
		nlhr.requestType = REQUEST_GET;
		nlhr.flags = NLHRF_DUMPASTEXT | NLHRF_HTTP11 | NLHRF_REDIRECT;
		char* pURL = &*(m_aURL.begin());
		nlhr.szUrl = pURL;

		nlhr.headersCount = 4;
		nlhr.headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount);
		nlhr.headers[0].szName = "User-Agent";
		nlhr.headers[0].szValue = NETLIB_USER_AGENT;
		nlhr.headers[1].szName = "Connection";
		nlhr.headers[1].szValue = "close";
		nlhr.headers[2].szName = "Cache-Control";
		nlhr.headers[2].szValue = "no-cache";
		nlhr.headers[3].szName = "Pragma";
		nlhr.headers[3].szValue = "no-cache";
		// 			nlhr.headers[4].szName  = "Accept-Encoding";
		// 			nlhr.headers[4].szValue = "deflate, gzip";
		// 			nlhr.headers[5].szName  = "Cookie";
		// 			nlhr.headers[5].szValue = cookie;

		bool bResult = false;
		NETLIBHTTPREQUEST* pReply = NULL;
		{
			mir_cslock lck(m_mx);
			pReply = reinterpret_cast<NETLIBHTTPREQUEST*>(CallService(MS_NETLIB_HTTPTRANSACTION,
				reinterpret_cast<WPARAM>(g_hNetLib), reinterpret_cast<LPARAM>(&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) && (NULL != strstr(_strlwr(pReply->headers[nIndex].szValue), "utf-8"))) {
					wchar_t* p = mir_utf8decodeT(pResult);
					rsResponce = p;
					mir_free(p);
				}
				else {
					// 						USES_CONVERSION;
					// 						LPCTSTR p = A2CT(pResult);
					rsResponce = quotes_a2t(pResult);//p;
				}

				bResult = true;
			}

			CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, reinterpret_cast<LPARAM>(pReply));
		}

		mir_free(nlhr.headers);

		return bResult;
	}

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

HANDLE CImplMI::g_hNetLib = NULL;

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();
}