带有Cookie功能的HTTP访问函数,GET,PUT/POST

本文介绍了一个带有Cookie功能的HTTP访问函数,包括GET和PUT/POST请求的实现。通过函数ParseURLWorker解析URL,获取服务类型、端口等信息,再利用HttpQueryStatusCode获取状态码,HttpOpenRequest和HttpSendRequest发送请求,并处理响应中的Cookie数据。
摘要由CSDN通过智能技术生成
#define AFX_INET_SERVICE_FTP        INTERNET_SERVICE_FTP
#define AFX_INET_SERVICE_HTTP       INTERNET_SERVICE_HTTP
#define AFX_INET_SERVICE_GOPHER     INTERNET_SERVICE_GOPHER
 
#define AFX_INET_SERVICE_UNK        0x1000
#define AFX_INET_SERVICE_FILE       (AFX_INET_SERVICE_UNK+1)
#define AFX_INET_SERVICE_MAILTO     (AFX_INET_SERVICE_UNK+2)
#define AFX_INET_SERVICE_MID        (AFX_INET_SERVICE_UNK+3)
#define AFX_INET_SERVICE_CID        (AFX_INET_SERVICE_UNK+4)
#define AFX_INET_SERVICE_NEWS       (AFX_INET_SERVICE_UNK+5)
#define AFX_INET_SERVICE_NNTP       (AFX_INET_SERVICE_UNK+6)
#define AFX_INET_SERVICE_PROSPERO   (AFX_INET_SERVICE_UNK+7)
#define AFX_INET_SERVICE_TELNET     (AFX_INET_SERVICE_UNK+8)
#define AFX_INET_SERVICE_WAIS       (AFX_INET_SERVICE_UNK+9)
#define AFX_INET_SERVICE_AFS        (AFX_INET_SERVICE_UNK+10)
#define AFX_INET_SERVICE_HTTPS      (AFX_INET_SERVICE_UNK+11)
	// Global Functions
 
	BOOL ParseURLWorker(LPCTSTR pstrURL,
		LPURL_COMPONENTS lpComponents, DWORD& dwServiceType,
		INTERNET_PORT& nPort, DWORD dwFlags)
	{
		// this function will return bogus stuff if lpComponents
		// isn't set up to copy the components
 
		assert(lpComponents != NULL && pstrURL != NULL);
		if (lpComponents == NULL || pstrURL == NULL)
			return FALSE;
		assert(lpComponents->dwHostNameLength == 0 ||
			lpComponents->lpszHostName != NULL);
		assert(lpComponents->dwUrlPathLength == 0 ||
			lpComponents->lpszUrlPath != NULL);
		assert(lpComponents->dwUserNameLength == 0 ||
			lpComponents->lpszUserName != NULL);
		assert(lpComponents->dwPasswordLength == 0 ||
			lpComponents->lpszPassword != NULL);
 
		//ASSERT(AfxIsValidAddress(lpComponents, sizeof(URL_COMPONENTS), TRUE));
 
		LPTSTR pstrCanonicalizedURL;
		TCHAR szCanonicalizedURL[INTERNET_MAX_URL_LENGTH];
		DWORD dwNeededLength = INTERNET_MAX_URL_LENGTH;
		BOOL bRetVal;
		BOOL bMustFree = FALSE;
 
		// Decoding is done in InternetCrackUrl/UrlUnescape 
		// so we don't need the ICU_DECODE flag here.
 
		DWORD dwCanonicalizeFlags = dwFlags &
			(ICU_NO_ENCODE | ICU_NO_META |
			ICU_ENCODE_SPACES_ONLY | ICU_BROWSER_MODE);
 
		DWORD dwCrackFlags = 0;
 
		BOOL bUnescape = FALSE;
 
		if((dwFlags & (ICU_ESCAPE | ICU_DECODE)) && (lpComponents->dwUrlPathLength != 0) )
		{
 
			// We use only the ICU_ESCAPE flag for decoding even if
			// ICU_DECODE is passed.
 
			// Also, if ICU_BROWSER_MODE is passed we do the unescaping
			// manually because InternetCrackUrl doesn't do
			// Browser mode unescaping
 
			if (dwFlags & ICU_BROWSER_MODE)
				bUnescape = TRUE;
			else
				dwCrackFlags |= ICU_ESCAPE;
		}
 
		bRetVal = InternetCanonicalizeUrl(pstrURL, szCanonicalizedURL,
			&dwNeededLength, dwCanonicalizeFlags);
 
		if (!bRetVal)
		{
			if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
				return FALSE;
 
			pstrCanonicalizedURL = new TCHAR[dwNeededLength];
			if (pstrCanonicalizedURL == NULL)
				return FALSE;
 
			bMustFree = TRUE;
			bRetVal = InternetCanonicalizeUrl(pstrURL, pstrCanonicalizedURL,
				&dwNeededLength, dwCanonicalizeFlags);
			if (!bRetVal)
			{
				delete [] pstrCanonicalizedURL;
				return FALSE;
			}
		}
		else
			pstrCanonicalizedURL = szCanonicalizedURL;
 
		// now that it's safely canonicalized, crack it
 
		bRetVal = InternetCrackUrl(pstrCanonicalizedURL, 0,
			dwCrackFlags, lpComponents);
 
		if(bUnescape)
		{
			if((UrlUnescape(lpComponents->lpszUrlPath,NULL,NULL,URL_UNESCAPE_INPLACE | URL_DONT_UNESCAPE_EXTRA_INFO)))
			{
				if (bMustFree)
					delete [] pstrCanonicalizedURL;
 
				return FALSE;
			}
 
			lpComponents->dwUrlPathLength = lstrlen(lpComponents->lpszUrlPath);
		}
 
		if (bMustFree)
			delete [] pstrCanonicalizedURL;
 
		// convert to MFC-style service ID
 
		if (!bRetVal)
			dwServiceType = AFX_INET_SERVICE_UNK;
		else
		{
			nPort = lpComponents->nPort;
			switch (lpComponents->nScheme)
			{
			case INTERNET_SCHEME_FTP:
				dwServiceType = AFX_INET_SERVICE_FTP;
				break;
 
			case INTERNET_SCHEME_GOPHER:
				dwServiceType = AFX_INET_SERVICE_GOPHER;
				break;
 
			case INTERNET_SCHEME_HTTP:
				dwServiceType = AFX_INET_SERVICE_HTTP;
				break;
 
			case INTERNET_SCHEME_HTTPS:
				dwServiceType = AFX_INET_SERVICE_HTTPS;
				break;
 
			case INTERNET_SCHEME_FILE:
				dwServiceType = AFX_INET_SERVICE_FILE;
				break;
 
			case INTERNET_SCHEME_NEWS:
				dwServiceType = AFX_INET_SERVICE_NNTP;
				break;
 
			case INTERNET_SCHEME_MAILTO:
				dwServiceType = AFX_INET_SERVICE_MAILTO;
				break;
 
			default:
				dwServiceType = AFX_INET_SERVICE_UNK;
			}
		}
 
		return bRetVal;
	}
 
	BOOL ParseURL(LPCTSTR pstrURL, DWORD& dwServiceType,
		string& strServer, string& strObject, INTERNET_PORT& nPort)
	{
		dwServiceType = AFX_INET_SERVICE_UNK;
 
		assert(pstrURL != NULL);
		if (pstrURL == NULL)
			return FALSE;
 
		URL_COMPONENTS urlComponents;
		memset(&urlComponents, 0, sizeof(URL_COMPONENTS));
		urlComponents.dwStructSize = sizeof(URL_COMPONENTS);
 
		urlComponents.dwHostNameLength = INTERNET_MAX_URL_LENGTH;
		urlComponents.lpszHostName = new char[INTERNET_MAX_URL_LENGTH+1];
		urlComponents.dwUrlPathLength = INTERNET_MAX_URL_LENGTH;
		urlComponents.lpszUrlPath = new char[INTERNET_MAX_URL_LENGTH+1];
 
		BOOL bRetVal = ParseURLWorker(pstrURL, &urlComponents,
			dwServiceType, nPort, ICU_BROWSER_MODE);
 
		strServer = urlComponents.lpszHostName;
		strObject = urlComponents.lpszUrlPath;
		delete urlComponents.lpszHostName;
		delete urlComponents.lpszUrlPath;
		return bRetVal;
	}
 
	BOOL HttpQueryStatusCode(HINTERNET hRequest, DWORD& dwStatusCode)
	{
		CHAR szBuffer[80];
		DWORD dwLen = _countof(szBuffer);
		BOOL bRet;
 
		bRet = HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE,
			szBuffer, &dwLen, NULL);
 
		if (bRet)
			dwStatusCode = (DWORD)atol(szBuffer);
		return bRet;
	}
 
	set<string> dict;
	string cookies;
 
	dict.insert("Max-Age");
	dict.insert("expires");
	dict.insert("domain");
	dict.insert("path");
	dict.insert("secure");
	dict.insert("HttpOnly");
	string HttpGet(LPCTSTR url, const string& queryString)
	{
		string result;
		DWORD dwVersion = GetVersion();
		stringstream agent;
		agent << "Mozilla/4.0 (System " << (int)LOBYTE(LOWORD(dwVersion)) << ".";
		agent << (int)HIBYTE(LOWORD(dwVersion)) << "." << (int)HIWORD(dwVersion) << "; Fyter HTTP Module)";
		stringstream req;
		//req << "Accept: */*/r/n";//Range: bytes=%u-/r/n
		req << "Accept-Language:zh-cn/r/n";
		if( !cookies.empty() )
			req << "Cookie:" + cookies + "/r/n";
		req << "Content-Type:application/x-www-form-urlencoded/r/n/r/n";
 
		string finalURL = url;
		finalURL += queryString;
 
		string host;
		string obj;
		DWORD type;
		INTERNET_PORT port;
 
		if( !ParseURL(finalURL.c_str(), type, host, obj, port) )
			goto close;
 
		HINTERNET hInternet = InternetOpen(agent.str().c_str(),
			INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
		HINTERNET hSession = InternetConnect(hInternet, host.c_str(), port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
		LPSTR szAccept[] = {"text/*" , NULL};
 
		HINTERNET hRequest = HttpOpenRequest(hSession, "GET", obj.c_str(),
			NULL, NULL, (LPCSTR*)szAccept, INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD, 0);
 
		HttpSendRequest(hRequest, req.str().c_str(), -1, NULL, 0);
 
		LPSTR lpszData; // 数据缓冲
		DWORD dwSize; // 缓冲尺寸
		DWORD dwDownloaded; // 下载的长度
 
		DWORD status = 0;
		if(!HttpQueryStatusCode(hRequest, status))
			goto close;
		if( status < 200 || status >= 300)
			goto close;
 
		char value[1000];
		DWORD valueLen = sizeof(value);
		if(HttpQueryInfo(hRequest, HTTP_QUERY_SET_COOKIE, value, &valueLen, 0))
		{
			stringstream ss(value);
			string sub;
			cookies.clear();
			while(getline(ss,sub,';'))
			{
				stringstream ss2(sub);
				string sub2;
				getline(ss2,sub2,'=');
				sub2.erase(0, sub2.find_first_not_of(" /t/n/r"));
				sub2.erase(sub2.find_last_not_of(" /t/n/r")+1);
				
				if(dict.find(sub2) == dict.end())
				{
					cookies = sub + ";";
				}
			}
		}
		
		// 接收数据循环
		while(1)
		{
			if (!InternetQueryDataAvailable(hRequest,&dwSize,0,0) || dwSize == 0 )
			{
				break;
			}
			else
			{ 
				lpszData = new char[dwSize+1];
 
				if(!InternetReadFile(hRequest,(LPVOID)lpszData,dwSize,&dwDownloaded))
				{
					delete[] lpszData;
					break;
				}
				else
				{
					//lpszData[dwDownloaded]='/0';
					result.insert(result.size() , lpszData, dwDownloaded);
 
					delete[] lpszData;
					if (dwDownloaded == 0)
						break;
				}
			}
		}
 
		close:
		InternetCloseHandle(hRequest);
		InternetCloseHandle(hSession);
		InternetCloseHandle(hInternet);
 
		return result;
	}
 
	string HttpPost(LPCTSTR url, const string& postContent)
	{
		string result;
		DWORD dwVersion = GetVersion();
		stringstream agent;
		agent << "Mozilla/4.0 (System " << (int)LOBYTE(LOWORD(dwVersion)) << ".";
		agent << (int)HIBYTE(LOWORD(dwVersion)) << "." << (int)HIWORD(dwVersion) << "; Fyter HTTP Module)";
		stringstream req;
		req << "Accept-Language:zh-cn/r/n";
		if( !cookies.empty() )
			req << "Cookie:" + cookies + "/r/n";
		req << "Content-Type:application/x-www-form-urlencoded/r/n";
		req << "Content-Length: " << postContent.length() << "/r/n/r/n";
 
		string host;
		string obj;
		DWORD type;
		INTERNET_PORT port;
 
		if( !ParseURL(url, type, host, obj, port) )
			goto close;
 
		HINTERNET hInternet = InternetOpen(agent.str().c_str(), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
		HINTERNET hSession = InternetConnect(hInternet, host.c_str(), port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
		char* szAccept[] = {"text/xml" , NULL};
 
		HINTERNET hRequest = HttpOpenRequest(hSession, "POST", obj.c_str(), NULL, NULL, (LPCSTR*)szAccept, 0, 0);
		HttpSendRequest(hRequest, req.str().c_str(), -1, (LPVOID)postContent.c_str(), postContent.length());
		
		LPSTR lpszData; // 数据缓冲
		DWORD dwSize; // 缓冲尺寸
		DWORD dwDownloaded; // 下载的长度
 
		DWORD status = 0;
		if(!HttpQueryStatusCode(hRequest, status))
			goto close;
		if( status < 200 || status >= 300)
			goto close;
 
		char value[1000];
		DWORD valueLen = sizeof(value);
		if(HttpQueryInfo(hRequest, HTTP_QUERY_SET_COOKIE, value, &valueLen, 0))
		{
			stringstream ss(value);
			string sub;
			cookies.clear();
			while(getline(ss,sub,';'))
			{
				stringstream ss2(sub);
				string sub2;
				getline(ss2,sub2,'=');
				sub2.erase(0, sub2.find_first_not_of(" /t/n/r"));
				sub2.erase(sub2.find_last_not_of(" /t/n/r")+1);
				
				if(dict.find(sub2) == dict.end())
				{
					cookies = sub + ";";
				}
			}
		}
 
		// 接收数据循环
		while(1)
		{
			if (!InternetQueryDataAvailable(hRequest,&dwSize,0,0) || dwSize == 0 )
			{
				break;
			}
			else
			{
				lpszData = new char[dwSize+1];
 
				if(!InternetReadFile(hRequest,(LPVOID)lpszData,dwSize,&dwDownloaded))
				{
					delete[] lpszData;
					break;
				}
				else
				{
					result.insert(result.size() , lpszData, dwDownloaded);
delete[] lpszData; if (dwDownloaded == 0) break; } } } close: InternetCloseHandle(hRequest); InternetCloseHandle(hSession); InternetCloseHandle(hInternet); return result; }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值