MFC中inet库中 CHttpFile获取响应的Cookie时,发现只能获取到第一个Cookie,获取Cookies代码如下
CString strCookie, strAllCookies;
DWORD dwCookieIndex = 0;
while (pHttpFile->QueryInfo(HTTP_QUERY_SET_COOKIE, strCookie, &dwCookieIndex)) {
strAllCookies += strCookie;
strAllCookies += _T("\r\n");
}
但是抓包或者使用HTTP_QUERY_RAW_HEADERS_CRLF查询全部Http头信息的时候发现Cookie是有多个的。
备注:使用QueryInfo获取Cookie,一次只能获取一条,用dwCookieIndex来控制具体获取哪一条Cookie,该值被QueryInfo内部自动递增。
单步调试进入CHttpFile::QueryInfo函数,MFC源代码如下所示:
BOOL CHttpFile::QueryInfo(DWORD dwInfoLevel, CString& str,
LPDWORD lpdwIndex) const
{
ASSERT(dwInfoLevel <= HTTP_QUERY_MAX);
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
BOOL bRet;
DWORD dwLen = 0;
// ask for nothing to see how long the return really is
str.Empty();
if (HttpQueryInfo(m_hFile, dwInfoLevel, NULL, &dwLen, 0)) //----这行有BUG---------;
bRet = TRUE;
else
{
// now that we know how long it is, ask for exactly that much
// space and really request the header from the API
LPTSTR pstr = str.GetBufferSetLength(dwLen / sizeof(TCHAR));
bRet = HttpQueryInfo(m_hFile, dwInfoLevel, pstr, &dwLen, lpdwIndex);
if (bRet)
str.ReleaseBuffer(dwLen / sizeof(TCHAR));
else
str.ReleaseBuffer(0);
}
return bRet;
}
其中HttpQueryInfo函数的原型如下:
BOOL HttpQueryInfo(
_In_ HINTERNET hRequest,
_In_ DWORD dwInfoLevel,
_Inout_ LPVOID lpvBuffer,
_Inout_ LPDWORD lpdwBufferLength,
_Inout_ LPDWORD lpdwIndex
);
对应注释的那句代码HttpQueryInfo(m_hFile, dwInfoLevel, NULL, &dwLen, 0),这个原先想要的意思是,获取指定Index位置的Cookie的实际长度,但是微软却把0传进去,那肯定会出问题了。
解决方案如下
1.新建一个类,命名为CMyHttpFile,然后从CHttpFile继承,里面重写BOOL CHttpFile::QueryInfo(DWORD dwInfoLevel, CString& str,LPDWORD lpdwIndex) const 函数,全部代码如下
#pragma once
#include "afxinet.h"
class CMyHttpFile : public CHttpFile {
public:
BOOL QueryInfo(DWORD dwInfoLevel, CString &str, LPDWORD lpdwIndex) const {
ASSERT(dwInfoLevel <= HTTP_QUERY_MAX);
ASSERT_VALID(this);
ASSERT(m_hFile != NULL);
BOOL bRet;
DWORD dwLen = 0;
// ask for nothing to see how long the return really is
str.Empty();
if (HttpQueryInfo(m_hFile, dwInfoLevel, NULL, &dwLen, lpdwIndex))
bRet = TRUE;
else {
// now that we know how long it is, ask for exactly that much
// space and really request the header from the API
LPTSTR pstr = str.GetBufferSetLength(dwLen / sizeof(TCHAR));
bRet = HttpQueryInfo(m_hFile, dwInfoLevel, pstr, &dwLen, lpdwIndex);
if (bRet)
str.ReleaseBuffer(dwLen / sizeof(TCHAR));
else
str.ReleaseBuffer(0);
}
return bRet;
}
};
2.使用,代码如下
CMyHttpFile* pHttpFile= (CMyHttpFile*)(pHttpConnect->OpenRequest(CHttpConnection::HTTP_VERB_POST, strPath, NULL, 1, NULL, NULL, INTERNET_FLAG_NO_COOKIES));
然后接下来就用这个pHttpFile操作,这样Cookie就能全部获取到了