Сервер вызовов с WinInet и WinHTTP - PullRequest
1 голос
/ 12 марта 2010


У меня есть запрос, который отлично работает, когда я использую WinInet API. Теперь я хочу сделать этот запрос с WinHTTP API, так как я уже использую его в своем проекте, и он просто лучше. Мой запрос используется для вызова JSON. Я уже аутентифицировался, прежде чем позвонить. При аутентификации я получаю SessionID, который отправляю через cookie.
Итак, вот мой рабочий код WinInet:

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;

Так что теперь я хочу сделать то же самое, используя WinHTTP API. Вот что у меня на данный момент:

DWORD dwError = 0;
HINTERNET 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;

С этим последним вызовом я всегда получаю 401, но я должен получить 200, как я сделал с первым методом. Я также узнал, что я получаю 401 с первым вызовом, когда я не указываю флаг INTERNET_FLAG_NO_COOKIES. Поэтому я подозреваю, что с заголовком cookie что-то не так. Кто-нибудь видит, что я делаю не так? Или в чем разница между этими двумя методами?
Thx ...

Ответы [ 3 ]

0 голосов
/ 15 марта 2010

Хорошо, я нашел это. Не было очевидно из кода, который я разместил ...
Строка cstrMethod содержит идентификатор пользователя, который я ранее извлек из заголовка ответа из аутентификационного вызова. Этот идентификатор затем используется для построения вызова метода. Теперь проблема заключалась в том, что идентификатор пользователя происходит из заголовка ответа, поэтому он заканчивается на \r\n. Таким образом, вызов сконструированного метода также содержит \r\n и, следовательно, неверный идентификатор пользователя, я получаю 401.
Поэтому мне пришлось вырезать строку идентификатора пользователя из заголовка, прежде чем я смог использовать ее для дальнейших вызовов.
Ну, немного странно, что вызов WinInet принял \r\n.

0 голосов
/ 18 октября 2013

Используйте эту ссылку (http://msdn.microsoft.com/en-us/library/windows/desktop/aa384068(v=vs.85).aspx), чтобы найти эквиваленты каждого метода.

0 голосов
/ 12 марта 2010

выглядит примерно так. На вашем месте я бы подключил прокси-сервер отладки HTTP, такой как Fiddler, и исследовал и сравнивал HTTP-трафик для двух методов. Это может указать вам на то, что вам нужно сделать.

...