1


WinInetAPIを使用すると正常に機能するリクエストがあります。WinHTTP APIを使用してそのリクエストを作成したいと思います。これは、プロジェクトですでに使用しており、単純に優れているためです。私のリクエストはJSONの呼び出しに使用されます。これを呼び出す前に、私はすでに認証しました。認証時に、Cookieを介して送信するSessionIDを取得します。
これが私の動作する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;

そこで、WinHTTPAPIを使用して同じことを実行したいと思います。これが私が今持っているものです:

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を受け取る必要があります。INTERNET_FLAG_NO_COOKIESまた、フラグを指定しないと、最初の呼び出しで401が返されることもわかりました。したがって、Cookieヘッダーの何かが間違っているのではないかと思います。誰かが私が間違っていることを見ますか?または、2つの方法の違いは何ですか?
どうも...

4

2 に答える 2

0

わかりました、見つけました。投稿したコードからはわかりませんでした...
文字列cstrMethodには、認証呼び出しの応答ヘッダーから以前に抽出したユーザーIDが含まれています。このIDは、メソッド呼び出しの作成に使用されます。ここで問題となったのは、ユーザーIDが応答ヘッダーから取得されたために.で終わること\r\nでした。したがって、構築されたメソッド呼び出しにも含まれ\r\nているため、ユーザーIDが間違っているため、401を取得します。
したがって、以降の呼び出しに使用する前に、ヘッダーからユーザーID文字列を削除する必要がありました。
WinInetの呼び出しがを受け入れたのは少し奇妙です\r\n

于 2010-03-15T13:54:02.363 に答える
0

ほぼ正しいように見えます。私があなたなら、Fiddler などの HTTP デバッグ プロキシを接続し、2 つのメソッドの HTTP トラフィックを調べて比較します。それはあなたが何をする必要があるかを示すかもしれません。

于 2010-03-12T12:07:43.290 に答える