2010-03-12 98 views
1


我有一個請求,使用WinInet API時正常工作。我現在想用WinHTTP API提出這個請求,因爲我已經在我的項目中使用它,因爲它更好。我的請求用於調用JSON。在致電之前,我已經認證了。在進行身份驗證時,我獲得了通過Cookie發送的SessionID。
所以這是我工作的WinInet代碼:與WinInet和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; 

所以我現在想使用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就像我與第一種方法做。我還發現,當我沒有指定INTERNET_FLAG_NO_COOKIES標誌時,我會在第一次打電話時收到401。所以我懷疑cookie標頭的內容是錯誤的。有誰看到我做錯了什麼?或者這兩種方法有什麼區別?
Thx ...

回答

0

好吧,我找到了。從我發佈的代碼中不明顯...
字符串cstrMethod包含一個用戶標識,我從響應標頭中提取了先前從身份驗證調用中提取的用戶標識。這個id然後用於構建方法調用。現在的問題是用戶ID來自響應頭,因此它以\r\n結尾。所以構造的方法調用也包含\r\n,因此用戶標識是錯誤的我得到了401。
所以我不得不從頭修剪用戶標識字符串,然後才能使用它進行進一步調用。
嗯,WinInet調用接受\r\n這有點奇怪。

0

看起來正確。 如果我是你,我會連接一個HTTP調試代理,如Fiddler,並檢查和比較兩種方法的HTTP流量。這可能會指示你需要做什麼。

+0

我已經試過用Wireshark。問題是我有HTTPS而不是HTTP,所以我不能讀出太多內容。 – 2010-03-12 12:15:45

+0

Fiddler也可以向您顯示HTTPS流量。 http://www.fiddlertool.com/Fiddler/help/httpsdecryption.asp – Cheeso 2010-03-12 12:26:17

+0

好吧,我嘗試了提琴手,但我看不到我的應用程序的流量。我也嘗試過濾所有過程。很抱歉,新的提琴手...任何提示? – 2010-03-12 13:19:26