Call server with WinInet and WinHTTP
DWORD dwError;
HINTERNET hOpen = NULL, hReq = NULL;
hOpen = InternetOpen(_T(""), INTERNET_OPEN_TYPE_DIRECT, _T(""), _T(""), 0);
if(hOpen == NULL)
{
dwError = GetLastError();
return false;
}
CString cstrCookies = _T("Cookie: JSESSIONID=") + cstrSession;
CString cstr = _T("https://") + cstrServer + _T("/list/") + cstrFileOrFolder;
hReq = InternetOpenUrl(hOpen, cstr, cstrCookies, -1L,
INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_COOKIES, 0); // without NO_COOKIES I'll get a 401
if(hReq == NULL)
{
dwError = GetLastError();
InternetCloseHandle(hOpen);
return false;
}
DWORD dwCode, dwCodeSize;
dwCodeSize = sizeof(DWORD);
if(!HttpQueryInfo(hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwCodeSize, NULL))
{
dwError = GetLastError();
InternetCloseHandle(hReq);
InternetCloseHandle(hOpen);
return false;
}
InternetCloseHandle(hOpen);
InternetCloseHandle(hReq);
return dwCode == 200;
So I now want to do the same using the WinHTTP API. Here is what I have for the moment:
DWORD dwError = 0;
HIN开发者_运维知识库TERNET hConnect = NULL, hRequest = NULL;
hConnect = WinHttpConnect(m_hSession, cstrServer, INTERNET_DEFAULT_HTTPS_PORT, 0);
if (hConnect == NULL)
{
return false;
}
hRequest = WinHttpOpenRequest(hConnect, NULL, cstrMethod + _T("/list/") + cstrFileOrFolder,
NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
if (hRequest == NULL)
{
WinHttpCloseHandle(hConnect);
return false;
}
DWORD dwOptionValue = WINHTTP_DISABLE_COOKIES;
if (WinHttpSetOption(hRequest, WINHTTP_OPTION_DISABLE_FEATURE, &dwOptionValue,
sizeof(dwOptionValue)) != TRUE)
{
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return false;
}
const CString cstrHeaders = _T("Cookie: JSESSIONID=") + cstrSession;
if (WinHttpAddRequestHeaders(hRequest, cstrHeaders, cstrHeaders.GetLength(),
WINHTTP_ADDREQ_FLAG_ADD) != TRUE)
{
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return false;
}
if (WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, -1L, WINHTTP_NO_REQUEST_DATA, 0,
0, 0) != TRUE)
{
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return false;
}
if (WinHttpReceiveResponse(hRequest, NULL) != TRUE)
{
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return false;
}
DWORD dwCode, dwCodeSize;
dwCodeSize = sizeof(DWORD);
if(!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwCode, &dwCodeSize, NULL))
{
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return false;
}
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hRequest);
return dwCode == 200;
With that latter call I always receive a 401 but I should get a 200 like I do with the first method. I also found out that I get a 401 with the first call when I don't specify the INTERNET_FLAG_NO_COOKIES
flag. So I suspect something with the cookie header is wrong. Do anyone see what I'm doing wrong? Or what is the difference between the two methods?
Looks about right. If I were you I would hook up an HTTP debugging proxy, like Fiddler, and examine and compare the HTTP traffic for the two methods. That might point you to what you need to do.
Ok, I found it. Wasn't obvious from the code I posted...
The string cstrMethod
contains a user id that I extracted previously from the response header from an authentication call. This id is then used for constructing the method call. Now problem was that the user id comes from a response header so it ends with \r\n
. So the constructed method call also contains \r\n
and as therefore the user id is wrong I get the 401.
So I had to trim the user id string from the header before I could use it for further calls.
Well it's a little bit odd that the WinInet call accepted the \r\n
.
精彩评论