-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathHttpStream.h
executable file
·147 lines (129 loc) · 3.27 KB
/
HttpStream.h
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
#pragma once
const int CONNECTION_ERROR = 0x0008000;
class HttpStream
{
CHttpConnection* connection;
CHttpFile* request;
bool ownsConnection;
bool postMode;
CArray<byte> postBuffer;
public:
HttpStream(CHttpConnection* connection, CString queryString, bool ownsConnection=true, bool postMode=false)
{
this->ownsConnection = ownsConnection;
this->connection = connection;
this->postMode = postMode;
if(postMode)
{
// {9CEF8854-9CF7-4f19-BE79-989EF60E8C5C}
static const GUID magicNetworkTag =
{ 0x9cef8854, 0x9cf7, 0x4f19, { 0xbe, 0x79, 0x98, 0x9e, 0xf6, 0xe, 0x8c, 0x5c } };
Write<GUID>(magicNetworkTag);
}
if(!connection)
throw CONNECTION_ERROR;
if(!(request = connection->OpenRequest(postMode?_T("POST"):_T("GET"), queryString, null, 1, null, null, INTERNET_FLAG_NO_CACHE_WRITE)))
throw CONNECTION_ERROR;
}
~HttpStream()
{
if(request) {
request->Close();
delete request;
}
if(connection && ownsConnection) {
connection->Close();
delete connection;
}
}
void StartReading()
{
if(postMode) {
if(!request->SendRequestEx(postBuffer.GetCount()))
throw CONNECTION_ERROR;
request->Write(postBuffer.GetData(), postBuffer.GetCount());
if(!request->EndRequest())
throw CONNECTION_ERROR;
}
else {
if(!request || !request->SendRequest())
throw CONNECTION_ERROR;
}
// {9CEF8854-9CF7-4f19-BE79-989EF60E8C5C}
static const GUID magicNetworkTag =
{ 0x9cef8854, 0x9cf7, 0x4f19, { 0xbe, 0x79, 0x98, 0x9e, 0xf6, 0xe, 0x8c, 0x5c } };
GUID tempguid = Read<GUID>();
if(memcmp(&magicNetworkTag, &tempguid, sizeof(GUID)) != 0)
throw CONNECTION_ERROR;
}
UINT FillBuffer(void* buffer, UINT count)
{
UINT read=0;
while(read<count) {
UINT r = request->Read(((char*)buffer)+read, count-read);
read += r;
if(r==0)
throw CONNECTION_ERROR;
}
return read;
}
template<class T>T Read(T& r)
{
if(sizeof(T) != FillBuffer(&r, sizeof(T)))
throw CONNECTION_ERROR;
return r;
}
template<class T>T Read()
{
T r;
if(sizeof(T) != FillBuffer(&r, sizeof(T)))
throw CONNECTION_ERROR;
return r;
}
UINT ReadBuffer(void* buffer, UINT count)
{
return request->Read(buffer, count);
}
CStringA ReadStringA()
{
DWORD bytes = Read<DWORD>();
CStringA s;
if(bytes != FillBuffer(s.GetBuffer(bytes+2), bytes))
throw CONNECTION_ERROR;
s.GetBuffer()[bytes] = '\0';
s.ReleaseBuffer();
return s;
}
CStringW ReadStringW()
{
DWORD bytes = Read<DWORD>();
CStringW s;
UINT read = FillBuffer(s.GetBuffer(bytes/2+2), bytes);
if(bytes != read)
throw CONNECTION_ERROR;
s.GetBuffer()[bytes/2] = 0;
s.ReleaseBuffer();
return s;
}
void Write(const void* buffer, size_t size)
{
ASSERT(postMode);
size_t old = postBuffer.GetCount();
postBuffer.SetSize(old + size);
memcpy(postBuffer.GetData() + old, buffer, size);
}
template<class T>void Write(T data)
{
Write(&data, sizeof(T));
}
void WriteStringW(CStringW string)
{
Write<UINT>(sizeof(WCHAR)*string.GetLength());
Write((LPCWSTR)string, sizeof(WCHAR)*string.GetLength());
}
void WriteStringW(CStringA string)
{
CStringW s(string);
WriteStringW(s);
}
};