Windows中有一组WinINet函数(http://msdn.microsoft.com/en-us/library/aa385473(v=VS.85).aspx),其中关于向Internet发送/接受请求的函数比较奇怪,尤其是HttpSendRequest函数问题更是诡异,下面是代码示例(该代码只是分析出问题,但没找到原因)
- BOOL SendHttpHeaderTest()
- {
- BOOL bRet = FALSE;
- if (ERROR_SUCCESS != ::InternetAttemptConnect(0))
- return FALSE;
- if (!::InternetCheckConnection(_T("http://www.baidu.com"), FLAG_ICC_FORCE_CONNECTION, 0))
- return FALSE;
- TCHAR szModuleFile[MAX_PATH] = {0};
- ::GetModuleFileName(::GetInstance(), szModuleFile, MAX_PATH);
- LPCTSTR lpPath = ::PathFindFileName(szModuleFile);
- HINTERNET hOpen = ::InternetOpen(lpPath, INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, NULL, NULL, 0);
- DWORD dwErr = ::GetLastError();//返回0
- HINTERNET hConnect = ::InternetConnect(hOpen, _T("www.baidu.com"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
- dwErr = ::GetLastError();//返回0
- #if 1
- DWORD dwFlag = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES;
- HINTERNET hOpenRequest = ::HttpOpenRequest(hConnect, _T("GET"), _T("img/baidu_sylogo1.gif"), _T("HTTP/1.1"), _T("http://www.baidu.com/"), NULL, dwFlag, 0);
- dwErr = ::GetLastError();//返回122
- bRet = ::HttpSendRequest(hOpenRequest, NULL, 0, NULL, 0);
- dwErr = ::GetLastError();//返回0
- #endif
- TCHAR szBuff[BUFF_LEN_1024] = {0};
- DWORD dwBuffSize = BUFF_LEN_1024;
- bRet = ::HttpQueryInfo(hOpenRequest, HTTP_QUERY_STATUS_CODE, (LPVOID)szBuff, &dwBuffSize, NULL);
- dwErr = ::GetLastError();//返回0
- //Reference to http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
- int nStatusCode = _tstoi(szBuff);// 值为200,证明请求数据baidu_sylogo1.gif是成功的.
- if (nStatusCode<200 || 206<nStatusCode)
- bRet = FALSE;
- bRet = TRUE;
- ::InternetCloseHandle(hConnect);
- ::InternetCloseHandle(hOpen);
- return bRet;
- }
- #if 2
- HINTERNET hOpenRequest = ::HttpOpenRequest(hConnect, NULL, NULL, NULL, NULL, NULL, dwFlag, 0);
- dwErr = ::GetLastError();//仍然返回122
- LPCTSTR lpHeader =
- _T("GET /img/baidu_sylogo1.gif /HTTP/1.1")//A line
- _T("Referer: http://www.baidu.com/\r\n") //B line
- _T("Host: www.baidu.com") //C line
- _T("\r\n\r\n"); //D line
- DWORD dwHeaderLen = _tcslen(lpHeader);
- bRet = ::HttpAddRequestHeaders(hOpenRequest, lpHeader, dwHeaderLen, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE);
- bRet = ::HttpSendRequest(hOpenRequest, NULL, 0, NULL, 0);
- dwErr = ::GetLastError();//返回0
- #endif
- // 注意观察lpHeaer的值,有如下几个特点:1)它的结尾D行有两个"\r\n\r\n";2)A行结尾没有\r\n;3)B行结尾有\r\n;4)C行结尾没有\r\n.
- // 下面测试一下这4个特点究竟哪个会对HttpSendRequest的调用产生影响.
- Test1: // A行结尾有\r\n
- LPCTSTR lpHeader = _T("GET /img/baidu_sylogo1.gif /HTTP/1.1\r\n")_T("Referer: http://www.baidu.com/")_T("Host: www.baidu.com")_T("\r\n\r\n");
- // HttpSendRequest返回0, dwErr = 12150, 含义ERROR_HTTP_HEADER_NOT_FOUND:The requested header could not be located.
- Test2: // A/B/C行结尾没有\r\n
- LPCTSTR lpHeader = _T("GET /img/baidu_sylogo1.gif /HTTP/1.1")_T("Referer: http://www.baidu.com/")_T("Host: www.baidu.com")_T("\r\n\r\n");
- // HttpSendRequest返回1, dwErr = 0
- Test3: // D行结尾一个\r\n
- LPCTSTR lpHeader = _T("GET /img/baidu_sylogo1.gif /HTTP/1.1")_T("Referer: http://www.baidu.com/")_T("Host: www.baidu.com")_T("\r\n");
- // HttpSendRequest返回1, dwErr = 0
- Test4: // D行结尾没有\r\n
- LPCTSTR lpHeader = _T("GET /img/baidu_sylogo1.gif /HTTP/1.1")_T("Referer: http://www.baidu.com/")_T("Host: www.baidu.com");
- // HttpSendRequest返回1, dwErr = 0
- #if 3
- hOpenRequestHandle = ::HttpOpenRequest(hConnectHandle, NULL, NULL, NULL, NULL, NULL, dwFlag, dwContext);
- LPCTSTR lpHeader = _T("GET /img/baidu_sylogo1.gif /HTTP/1.1")_T("Referer: http://www.baidu.com/");
- DWORD dwLen = _tcslen(lpHeader);
- bRet = ::HttpAddRequestHeaders(hOpenRequestHandle, lpHeader, nLen, HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD);//返回1
- bRet = ::HttpSendRequest(hOpenRequestHandle, NULL, 0, NULL, 0);//返回1
- #endif
参考这里