#include "HttpUtility.h"
#ifdef VCZH_MSVC
#include <Windows.h>
#include <winhttp.h>
#pragma comment(lib,
"WinHttp.lib"
)
namespace
{
using
namespace
collections
;
bool
::
(
const
&
)
{
if
(
==
L""
)
{
=
L"GET"
;
}
=
L""
;
=
L""
;
=
0
;
=
false
;
{
if
(
==
L""
)
{
if
(
.
() >
7
)
{
=
.
(
0
,
8
);
if
(
(
protocol
.
(),
L"https://"
) ==
0
)
{
const
wchar_t
*
=
.
() +
8
;
const
wchar_t
*
=
(
reading
,
L':'
);
const
wchar_t
*
=
(
reading
,
L'/'
);
if
(
index2
)
{
=
index2
;
(
reading
, (
index1
?
index1
:
index2
) -
reading
);
port = INTERNET_DEFAULT_HTTPS_PORT;
=
true
;
if
(
index1
)
{
(
index1
+
1
,
index2
-
index1
-
1
);
=
(
portString
.
());
}
return
true
;
}
}
}
}
if
(
==
L""
)
{
if
(
.
() >
6
)
{
=
.
(
0
,
7
);
if
(
(
protocol
.
(),
L"http://"
) ==
0
)
{
const
wchar_t
*
=
.
() +
7
;
const
wchar_t
*
=
(
reading
,
L':'
);
const
wchar_t
*
=
(
reading
,
L'/'
);
if
(
index2
)
{
=
index2
;
(
reading
, (
index1
?
index1
:
index2
) -
reading
);
port = INTERNET_DEFAULT_HTTP_PORT;
if
(
index1
)
{
(
index1
+
1
,
index2
-
index1
-
1
);
=
(
portString
.
());
}
return
true
;
}
}
}
}
}
return
false
;
}
void
::
(
const
&
)
{
vint utf8Size = WideCharToMultiByte(CP_UTF8, 0, bodyString.Buffer(), (int)bodyString.Length(), NULL, 0, NULL, NULL);
=
(
65001
,
0
,
.
(), (
int
)
.
(),
0
,
0
,
0
,
0
);
char
*
=
new
char
[
utf8Size
+
1
];
ZeroMemory(utf8, utf8Size + 1);
((
utf8
),
0
,(
utf8Size
+
1
));
WideCharToMultiByte(CP_UTF8, 0, bodyString.Buffer(), (int)bodyString.Length(), utf8, (int)utf8Size, NULL, NULL);
(
65001
,
0
,
.
(), (
int
)
.
(),
utf8
, (
int
)
utf8Size
,
0
,
0
);
.
(
utf8Size
);
(&
0
],
utf8
,
utf8Size
);
delete
[]
utf8
;
}
::
()
{
;
char
*
= &
0
];
=
.
();
vint utf16Size = MultiByteToWideChar(CP_UTF8, 0, utf8, (int)totalSize, NULL, 0);
=
(
65001
,
0
,
utf8
, (
int
)
totalSize
,
0
,
0
);
wchar_t
*
=
new
wchar_t
[
utf16Size
+
1
];
ZeroMemory(utf16, (utf16Size + 1) * sizeof(wchar_t));
((
utf16
),
0
,((
utf16Size
+
1
) *
sizeof
(
wchar_t
)));
MultiByteToWideChar(CP_UTF8, 0, utf8, (int)totalSize, utf16, (int)utf16Size);
(
65001
,
0
,
utf8
, (
int
)
totalSize
,
utf16
, (
int
)
utf16Size
);
response
=
utf16
;
delete
[]
utf16
;
return
response
;
}
struct
{
char
*
;
;
()
:buffer(
0
)
, length(
0
)
{
}
(
char
*
,
)
:buffer(
)
, length(
)
{
}
bool
(
const
&
) {
return
false
; }
bool
(
const
&
) {
return
true
; }
};
bool
(
const
&
,
&
)
{
.
= -
1
;
HINTERNET internet = NULL;
HINTERNET connectedInternet = NULL;
HINTERNET requestInternet = NULL;
=
0
;
<
>
;
<
>
;
internet = WinHttpOpen(L"vczh", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
internet
=
(
L"vczh"
,
1
,
0
,
0
,
0
);
error
=
();
if
(!
internet
)
goto
CLEANUP;
connectedInternet
=
(
internet
,
.
.
(), (
int
)
.
,
0
);
error
=
();
if
(!
connectedInternet
)
goto
CLEANUP;
for
(
=
0
;
i
<
.
.
();
i
++)
{
acceptTypes
.
(
.
.
(
i
).
());
}
acceptTypes
.
(
0
);
requestInternet = WinHttpOpenRequest(connectedInternet, request.method.Buffer(), request.query.Buffer(), NULL, WINHTTP_NO_REFERER, &acceptTypes[0], (request.secure ? WINHTTP_FLAG_SECURE : 0));
requestInternet
=
(
connectedInternet
,
.
.
(),
.
.
(),
0
,
0
, &
acceptTypes
0
], (
.
?
0x00800000
:
0
));
error
=
();
if
(!
requestInternet
)
goto
CLEANUP;
if
(
.
L""
&&
.
!=
L""
)
{
WinHttpSetCredentials(requestInternet, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, request.username.Buffer(), request.password.Buffer(), NULL);
(
requestInternet
,
0x00000000
,
0x00000001
,
.
.
(),
.
.
(),
0
);
}
if
(
.
L""
)
{
httpResult = WinHttpAddRequestHeaders(requestInternet, (L"Content-type:" + request.contentType).Buffer(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD);
httpResult
=
(
requestInternet
, (
L"Content-type:"
+
.
).Buffer(), -
1
,
0x80000000
|
0x20000000
);
}
if
(
.
L""
)
{
WinHttpAddRequestHeaders(requestInternet, (L"Cookie:" + request.cookie).Buffer(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD);
(
requestInternet
, (
L"Cookie:"
+
.
).Buffer(), -
1
,
0x80000000
|
0x20000000
);
}
for
(
int
=
0
;
i
<
.
.
();
i
++)
{
=
.
.
()
i
];
=
.
.
().
(
i
);
WinHttpAddRequestHeaders(requestInternet, (key + L":" + value).Buffer(), -1, WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD);
(
requestInternet
, (
key
+
L":"
+
value
).Buffer(), -
1
,
0x80000000
|
0x20000000
);
}
if
(
.
.
() >
0
)
{
httpResult = WinHttpSendRequest(requestInternet, WINHTTP_NO_ADDITIONAL_HEADERS, 0, (LPVOID)&request.body.Get(0), (int)request.body.Count(), (int)request.body.Count(), NULL);
httpResult
=
(
requestInternet
,
0
,
0
, (
)&
.
.
(
0
), (
int
)
.
.
(), (
int
)
.
.
(),
0
);
}
else
{
httpResult = WinHttpSendRequest(requestInternet, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, NULL);
httpResult
=
(
requestInternet
,
0
,
0
,
0
,
0
,
0
,
0
);
}
error
=
();
if (httpResult == FALSE) goto CLEANUP;
if
(
httpResult
==
0
)
goto
CLEANUP;
httpResult = WinHttpReceiveResponse(requestInternet, NULL);
httpResult
=
(
requestInternet
,
0
);
error
=
();
if (httpResult != TRUE) goto CLEANUP;
if
(
httpResult
!=
1
)
goto
CLEANUP;
{
=
sizeof
(
);
=
0
;
httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &headerLength, WINHTTP_NO_HEADER_INDEX);
httpResult
=
(
requestInternet
,
19
|
0x20000000
,
0
, &
statusCode
, &
headerLength
,
0
);
error
=
();
if (httpResult == FALSE) goto CLEANUP;
if
(
httpResult
==
0
)
goto
CLEANUP;
.
=
statusCode
;
}
{
=
sizeof
(
);
httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &headerLength, WINHTTP_NO_HEADER_INDEX);
httpResult
=
(
requestInternet
,
22
,
0
,
0
, &
headerLength
,
0
);
error
=
();
if (error == ERROR_INSUFFICIENT_BUFFER)
{
wchar_t
* =
new
wchar_t
[
headerLength
/
sizeof
(
wchar_t
)];
ZeroMemory(rawHeader, headerLength);
((
rawHeader
),
0
,(
headerLength
));
httpResult = WinHttpQueryHeaders(requestInternet, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, rawHeader, &headerLength, WINHTTP_NO_HEADER_INDEX);
httpResult
=
(
requestInternet
,
22
,
0
,
rawHeader
, &
headerLength
,
0
);
const
wchar_t
*
=
(
rawHeader
,
L"Cookie:"
);
if
(
cookieStart
)
{
const
wchar_t
*
=
(
cookieStart
,
L";"
);
if
(
cookieEnd
)
{
.
(
cookieStart
+
7
,
cookieEnd
-
cookieStart
-
7
);
}
}
delete
[]
rawHeader
;
}
}
while
(
true
)
{
=
0
;
=
WinHttpQueryDataAvailable
(
requestInternet
, &
bytesAvailable
);
error
=
();
if (queryDataAvailableResult == TRUE && bytesAvailable != 0)
if
(
queryDataAvailableResult
==
1
&&
bytesAvailable
!=
0
)
{
char
*
=
new
char
[
bytesAvailable
];
=
0
;
=
(
requestInternet
,
utf8
,
bytesAvailable
, &
bytesRead
);
error
=
();
if (readDataResult == TRUE)
{
availableBuffers
.
(
(
utf8
,
bytesRead
));
}
else
{
delete
[]
utf8
;
}
}
else
{
break
;
}
}
{
=
0
;
FOREACH(BufferPair, p, availableBuffers)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
availableBuffers
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
p
);)
{
totalSize
+=
p
.
;
}
.
.
(
totalSize
);
if
(
totalSize
>
0
)
{
char
*
=
new
char
[
totalSize
];
{
char
*
=
utf8
;
FOREACH(BufferPair, p, availableBuffers)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
availableBuffers
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
p
);)
{
(
temp
,
p
.
,
p
.
);
temp
+=
p
.
;
}
}
(&
.
0
],
utf8
,
totalSize
);
delete
[]
utf8
;
}
FOREACH(BufferPair, p, availableBuffers)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
availableBuffers
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
p
);)
{
delete
[]
p
.
;
}
}
CLEANUP:
if
(
requestInternet
)
(
requestInternet
);
if
(
connectedInternet
)
(
connectedInternet
);
if
(
internet
)
(
internet
);
return
.
!= -
1
;
}
(
const
&
)
{
vint utf8Size = WideCharToMultiByte(CP_UTF8, 0, query.Buffer(), (int)query.Length(), NULL, 0, NULL, NULL);
=
(
65001
,
0
,
.
(), (
int
)
.
(),
0
,
0
,
0
,
0
);
char
*
=
new
char
[
utf8Size
+
1
];
ZeroMemory(utf8, utf8Size + 1);
((
utf8
),
0
,(
utf8Size
+
1
));
WideCharToMultiByte(CP_UTF8, 0, query.Buffer(), (int)query.Length(), utf8, (int)utf8Size, NULL, NULL);
(
65001
,
0
,
.
(), (
int
)
.
(),
utf8
, (
int
)
utf8Size
,
0
,
0
);
wchar_t
*
=
new
wchar_t
[
utf8Size
*
3
+
1
];
ZeroMemory(encoded, (utf8Size * 3 + 1) * sizeof(wchar_t));
((
encoded
),
0
,((
utf8Size
*
3
+
1
) *
sizeof
(
wchar_t
)));
wchar_t
*
=
encoded
;
for
(
=
0
;
i
<
utf8Size
;
i
++)
{
unsigned
char
= (
unsigned
char
)
utf8
[
i
];
if
(
L'a'
<=
x
&&
x
<=
'z'
||
L'A'
<=
x
&&
x
<=
L'Z'
||
L'0'
<=
x
&&
x
<=
L'9'
)
{
writing
[
0
] =
x
;
writing
+=
1
;
}
else
{
writing
[
0
] =
L'%'
;
writing
[
1
] =
L"0123456789ABCDEF"
[
x
/
16
];
writing
[
2
] =
L"0123456789ABCDEF"
[
x
%
16
];
writing
+=
3
;
}
}
=
encoded
;
delete
[]
encoded
;
delete
[]
utf8
;
return
result
;
}
}
#endif