⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpclt.cpp.svn-base

📁 股票软件源码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
		return FALSE;

	CDLocalView	des;
	len	=	destLen;
	des.Destroy( (BYTE *)strDesData.GetBuffer(destLen), (BYTE *)strPostData.GetBuffer(len+1), len );
	(strPostData.GetBuffer(len+1))[len]	=	'\0';
	
	strPostData.ReleaseBuffer();
	strDesData.ReleaseBuffer();

	return TRUE;
}

//////////////////////////////////////////////////////////////
// common methods
DWORD CHttpClient::RequestGet( LPCTSTR lpszURL, CMapStringToString* pmapParam,
						CFile * pFileSave, PROGRESS_CALLBACK fnCallback, void *cookie )
{
	if( NULL == lpszURL || strlen(lpszURL) == 0 )
		return HTTP_STATUS_BAD_REQUEST;

	if( NULL != pFileSave && CFile::hFileNull == pFileSave->m_hFile )
	{
		ASSERT( FALSE );
		return	HTTP_STATUS_BAD_REQUEST;
	}

	CString	strURL	=	lpszURL;
	if( NULL != pmapParam )
	{
		CString	strParam;
		MakeGetData( *pmapParam, strParam );
		if(!strParam.IsEmpty())
			strURL += "?" + strParam;
	}
	return Request( strURL, CString(""), pFileSave, NULL, fnCallback, cookie );
}

DWORD CHttpClient::RequestGet( LPCTSTR lpszURL, CMapStringToString* pmapParam,
						CString *pstrResult, PROGRESS_CALLBACK fnCallback, void *cookie )
{
	if( NULL == lpszURL || strlen(lpszURL) == 0 )
		return HTTP_STATUS_BAD_REQUEST;

	CString	strURL	=	lpszURL;
	if( NULL != pmapParam )
	{
		CString	strParam;
		MakeGetData( *pmapParam, strParam );
		if(!strParam.IsEmpty())
			strURL += "?" + strParam;
	}
	return Request( strURL, CString(""), NULL, pstrResult, fnCallback, cookie );
}

DWORD CHttpClient::RequestPost( LPCTSTR lpszURL, CMapStringToString* pmapParam,
						CFile * pFileSave, PROGRESS_CALLBACK fnCallback, void *cookie )
{
	if( NULL != pFileSave && CFile::hFileNull == pFileSave->m_hFile )
	{
		ASSERT( FALSE );
		return	HTTP_STATUS_BAD_REQUEST;
	}

	CString	strPostData;
	if( NULL != pmapParam )
		MakePostData( *pmapParam, strPostData );

	// PostDataEncoding( strPostData );

	return Request( lpszURL, strPostData, pFileSave, NULL, fnCallback, cookie );
}

DWORD CHttpClient::RequestPost( LPCTSTR lpszURL, CMapStringToString* pmapParam,
						CString *pstrResult, PROGRESS_CALLBACK fnCallback, void *cookie )
{
	CString	strPostData;
	if( NULL != pmapParam )
		MakePostData( *pmapParam, strPostData );

	// PostDataEncoding( strPostData );

	return Request( lpszURL, strPostData, NULL, pstrResult, fnCallback, cookie );
}

void CHttpClient::DoOpenURL( LPCTSTR lpszURL, DWORD dwHttpRequestFlags,
							CString &strHeader, CString &strPostData,
							CInternetSession *pSession,
							CHttpConnection **ppServer, CHttpFile **ppFile,
							PROGRESS_CALLBACK fnCallback, void * cookie )
{
	CString strServerName;
	CString strObject;
	INTERNET_PORT nPort;
	DWORD dwServiceType;
	
	int nVerb = (strPostData.GetLength()>0 ? CHttpConnection::HTTP_VERB_POST : CHttpConnection::HTTP_VERB_GET);

	if (!AfxParseURL(lpszURL, dwServiceType, strServerName, strObject, nPort) ||
		dwServiceType != INTERNET_SERVICE_HTTP)
	{
		ThrowTearException( ERR_TEAR_URLFORMAT );
	}

	if( fnCallback )
		fnCallback( PROG_HTTPCONNECTTING, 0, NULL, cookie );

	CHttpConnection *pServer = pSession->GetHttpConnection(strServerName, dwHttpRequestFlags, nPort, m_strProxyUser, m_strProxyPasswd );
	CHttpFile	* pFile = pServer->OpenRequest(nVerb, strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
	pFile->AddRequestHeaders(strHeader, HTTP_ADDREQ_FLAG_COALESCE);
	if( strPostData.GetLength() > 0 ) // post
	{
		try
		{
			pFile->SendRequestEx( DWORD(strPostData.GetLength()) );
			pFile->WriteString(strPostData);
			pFile->EndRequest();
		}
		catch( CInternetException *pp )	// HTTP_STATUS_BAD_METHOD
		{
			pp->Delete();

			// close up the redirected site
			pFile->Close();
			delete pFile;
			pFile	=	NULL;
			pServer->Close();
			delete pServer;
			pServer	=	NULL;

			pServer = pSession->GetHttpConnection(strServerName, dwHttpRequestFlags, nPort, m_strProxyUser, m_strProxyPasswd );
			pFile = pServer->OpenRequest(nVerb, strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
			pFile->AddRequestHeaders(strHeader, HTTP_ADDREQ_FLAG_COALESCE);
			pFile->SendRequestEx( DWORD(strPostData.GetLength()) );
			pFile->WriteString(strPostData);
			pFile->EndRequest();
		}
	}
	else
	{
		pFile->SendRequest();
	}

	if( fnCallback )
		fnCallback( PROG_REQUESTSENT, 0, NULL, cookie );

	// Bad Post method
	DWORD dwRet	=	0;
	pFile->QueryInfoStatusCode( dwRet );

	// if access was denied, prompt the user for the password
	if (dwRet == HTTP_STATUS_DENIED
		|| dwRet == HTTP_STATUS_PROXY_AUTH_REQ )
	{
		DWORD dwPrompt;
		dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,
			FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
			| FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);

		// if the user cancelled the dialog, bail out
		if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)
			ThrowTearException( ERR_TEAR_CANCEL );
		if( strPostData.GetLength() > 0 ) // post
		{
			try{
				pFile->SendRequestEx( DWORD(strPostData.GetLength()) );
				pFile->WriteString(strPostData);
				pFile->EndRequest();
			}
			catch( CInternetException *pp ) // HTTP_STATUS_BAD_METHOD
			{
				pp->Delete();

				pFile->SendRequestEx( DWORD(strPostData.GetLength()) );
				pFile->WriteString(strPostData);
				pFile->EndRequest();
			}
		}
		else
		{
			pFile->SendRequest();
		}
		pFile->QueryInfoStatusCode(dwRet);
	}

	if( dwRet == HTTP_STATUS_BAD_METHOD )
	{
		// close up the redirected site
		pFile->Close();
		delete pFile;
		pFile	=	NULL;
		pServer->Close();
		delete pServer;
		pServer	=	NULL;

		pServer = pSession->GetHttpConnection(strServerName, dwHttpRequestFlags, nPort, m_strProxyUser, m_strProxyPasswd );
		pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
		pFile->AddRequestHeaders(strHeader, HTTP_ADDREQ_FLAG_COALESCE);
		if( strPostData.GetLength() > 0 ) // post
		{
			pFile->SendRequestEx( DWORD(strPostData.GetLength()) );
			pFile->WriteString(strPostData);
			pFile->EndRequest();
		}
		else
		{
			pFile->SendRequest();
		}
	}

	*ppServer	=	pServer;
	*ppFile	=	pFile;
}

CString CHttpClient::GetNewLocation( CHttpFile * pFile )
{
	CString	strNewLocation;
	pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);

	int nPlace = strNewLocation.Find(_T("Location: "));
	if (nPlace == -1)
	{
		ThrowTearException( ERR_TEAR_REDIRECT );
	}

	strNewLocation = strNewLocation.Mid(nPlace + 10);
	nPlace = strNewLocation.Find('\n');
	if (nPlace > 0)
		strNewLocation = strNewLocation.Left(nPlace);
	return strNewLocation;
}

void CHttpClient::DoSecurityRequest( CHttpFile * pFile, CString &strPostData )
{
	DWORD dwPrompt;
	dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,
		FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
		| FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);

	// if the user cancelled the dialog, bail out
	if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)
		ThrowTearException( ERR_TEAR_CANCEL );
	if( strPostData.GetLength() > 0 ) // post
	{
		try{
			pFile->SendRequestEx( DWORD(strPostData.GetLength()) );
			pFile->WriteString(strPostData);
			pFile->EndRequest();
		}
		catch( CInternetException *pp )
		{
			pp->Delete();
			// HTTP_STATUS_BAD_METHOD
			pFile->SendRequest();
		}
	}
	else
	{
		pFile->SendRequest();
	}
}

CString FormatProxyString( int nProxyType, LPCTSTR lpszProxyAddress, UINT nProxyPort )
{
	if( NULL == lpszProxyAddress || strlen(lpszProxyAddress) <= 0 )
		return "";
	CString strProxy;
	CString	strProxyType;
	if( CProxySocket::TypeSocks4 == nProxyType || CProxySocket::TypeSocks5 == nProxyType )
		strProxyType = "socks=";
	else if( CProxySocket::TypeHTTP == nProxyType )
		strProxyType = "http=";
	strProxy.Format( "%s%s:%d", strProxyType, lpszProxyAddress, nProxyPort );
	return strProxy;
}

DWORD CHttpClient::Request(LPCTSTR lpszURL, CString &strPostData,
						 CFile *pFileSave, CString *pstrResult,
						 PROGRESS_CALLBACK fnCallback, void *cookie )
{
	DWORD	dwRet	=	HTTP_STATUS_BAD_REQUEST;

	if( NULL == lpszURL || strlen(lpszURL) == 0 )
		return dwRet;

	int	nContentLength = 0;
	int nContentLengthLocal = 0;
	int nContentLengthFinished = 0;
	int nContentLengthTotal = 0;

	// prepare header
	CString	strHeader;
	CMapStringToString	mapHeader;
	if( pFileSave && pFileSave->GetPosition() > 0 )
	{
		nContentLengthFinished = (int)pFileSave->GetPosition();
		CString strRange;
		strRange.Format( "bytes=%u-", nContentLengthFinished );
		mapHeader.SetAt( szRange, strRange );
		
	}
	if( pstrResult && pstrResult->GetLength() > 0 )
	{
		nContentLengthFinished = pstrResult->GetLength();
		CString strRange;
		strRange.Format( "bytes=%u-", nContentLengthFinished );
		mapHeader.SetAt( szRange, strRange );
	}
	if( m_strCookie.GetLength() > 0 )
		mapHeader.SetAt( szCookieKey, m_strCookie );
	MakeHttpHeader( mapHeader, strHeader );

	// default type and flags
	DWORD dwHttpRequestFlags =	INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD
								| INTERNET_FLAG_DONT_CACHE
								| INTERNET_FLAG_EXISTING_CONNECT; // | INTERNET_FLAG_KEEP_CONNECTION;
	
	CString	strProxy;
	if( !m_strProxyAddress.IsEmpty() )
		strProxy = FormatProxyString( m_nProxyType, m_strProxyAddress, m_nProxyPort );
	CInternetSession session(	szUserAgentValue, 1, m_nAccessType,
							strProxy, NULL, INTERNET_FLAG_DONT_CACHE );
	// 以下SetOption似乎不起作用
	if( !strProxy.IsEmpty() && !m_strProxyAddress.IsEmpty() )
	{
		session.SetOption( INTERNET_OPTION_PROXY_USERNAME, (LPVOID)(LPCTSTR)m_strProxyUser, m_strProxyUser.GetLength() );
		session.SetOption( INTERNET_OPTION_PROXY_PASSWORD, (LPVOID)(LPCTSTR)m_strProxyPasswd, m_strProxyPasswd.GetLength() );
	}
	session.SetOption( INTERNET_OPTION_RECEIVE_TIMEOUT, 300000 );
	session.SetOption( INTERNET_OPTION_SEND_TIMEOUT, 30000 );
	session.SetOption( INTERNET_OPTION_CONNECT_TIMEOUT, 30000 );

	CHttpConnection* pServer = NULL;
	CHttpFile* pFile = NULL;
	try
	{
		// check to see if this is a reasonable URL
		DoOpenURL( lpszURL, dwHttpRequestFlags, strHeader, strPostData, &session, &pServer, &pFile, fnCallback, cookie );
		if( NULL == pServer || NULL == pFile )
			ThrowTearException( ERR_TEAR_INTERRUPTED );

		pFile->QueryInfoStatusCode(dwRet);

		if (dwRet == HTTP_STATUS_MOVED ||
			dwRet == HTTP_STATUS_REDIRECT ||
			dwRet == HTTP_STATUS_REDIRECT_METHOD)
		{
			CString strNewLocation = GetNewLocation( pFile );

			// close up the redirected site
			pFile->Close();
			delete pFile;
			pFile	=	NULL;
			pServer->Close();
			delete pServer;
			pServer	=	NULL;

			// progress callback
			if( fnCallback )
				fnCallback( PROG_REDIRECTING, 0, NULL, cookie );

			// open new url
			DoOpenURL( strNewLocation, dwHttpRequestFlags,
						strHeader, strPostData,
						&session, &pServer, &pFile, fnCallback, cookie );
			
			pFile->QueryInfoStatusCode(dwRet);
		}

		if (dwRet == HTTP_STATUS_PARTIAL_CONTENT)
			dwRet = HTTP_STATUS_OK;
		if (dwRet != HTTP_STATUS_OK)
			ThrowTearException( ERR_TEAR_INTERRUPTED );

		CString	strInfo;
		pFile->QueryInfo( HTTP_QUERY_SET_COOKIE, strInfo );
		pFile->QueryInfo( HTTP_QUERY_COOKIE, strInfo );
		if( strInfo.GetLength() )
			m_strCookie	=	strInfo;
		pFile->QueryInfo( HTTP_QUERY_CONTENT_LENGTH, strInfo );
		nContentLength	=	atol( strInfo );
		nContentLengthTotal = nContentLength + nContentLengthFinished;
		if( pstrResult && nContentLengthTotal > 0 )
			pstrResult->GetBuffer( nContentLengthTotal+5 );

		DWORD	dwCheckSum	=	0;
		BOOL	bHasCheckSum	=	FALSE;
		CString	strCheckSum;
		pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strCheckSum);
		int nPlace = strCheckSum.Find( szCheckSumKeySuffix );
		if ( -1 != nPlace )
		{
			strCheckSum = strCheckSum.Mid( nPlace+strlen(szCheckSumKeySuffix) );
			nPlace = strCheckSum.Find( '\n' );
			if( nPlace > 0 )
			{
				dwCheckSum = atol( strCheckSum.Left( nPlace ) );
				bHasCheckSum	=	TRUE;
			}
		}

		if( fnCallback )
			fnCallback( PROG_TRANSFERRING, 0, NULL, cookie );

		DWORD	dwCheckSumLocal	=	0;
		TCHAR sz[1028];
		int nRead = pFile->Read(sz+4, 1023);
		while (nRead > 0)
		{
			sz[4+nRead] = '\0';
			if( NULL != pFileSave )
				pFileSave->Write( sz+4, nRead );
			if( NULL != pstrResult )
				*pstrResult	+=	(TCHAR *)(sz+4);
			nContentLengthLocal	+=	nRead;

			if( fnCallback && nContentLengthTotal > 0 )
				fnCallback( PROG_PROGRESS, DWORD(STKLIB_MAXF_PROGRESS*(nContentLengthFinished+nContentLengthLocal)/nContentLengthTotal), NULL, cookie );

			if( bHasCheckSum )
			{
				*((DWORD *)sz)	=	dwCheckSumLocal;
				dwCheckSumLocal = CRC32( sz, nRead );
			}

			nRead = pFile->Read(sz+4, 1023);
		}

		if( pstrResult && nContentLengthTotal > 0 )
			pstrResult->ReleaseBuffer();

		if( (nContentLength > 0 && nContentLengthLocal != nContentLength)
				|| (bHasCheckSum && dwCheckSum != dwCheckSumLocal) )
			ThrowTearException( ERR_TEAR_DATATRANSFER );

		if( fnCallback )
			fnCallback( PROG_PROGRESS, STKLIB_MAX_PROGRESS, NULL, cookie );
	}
	catch (CInternetException* pEx)
	{
		// catch errors from WinINet
		if (HTTP_STATUS_OK == dwRet)
			dwRet	=	HTTP_STATUS_PARTIAL;
		TCHAR szErr[1024];
		pEx->GetErrorMessage(szErr, 1024);
		m_strLastErrorMessage	=	szErr;
		pEx->Delete();
	}
	catch (CTearException* pEx)
	{
		TCHAR szErr[1024];
		pEx->GetErrorMessage(szErr, 1024);
		m_strLastErrorMessage	=	szErr;
		pEx->Delete();
	}
	catch( CException * pEx )
	{
		TCHAR szErr[1024];
		pEx->GetErrorMessage(szErr, 1024);
		m_strLastErrorMessage	=	szErr;
		pEx->Delete();
	}

	if (pFile != NULL)
	{
		pFile->Close();
		delete pFile;
	}
	if (pServer != NULL)
	{
		pServer->Close();
		delete pServer;
	}
	session.Close();

	if(nContentLength > 0 && nContentLengthLocal != nContentLength)
		return Request( lpszURL, strPostData, pFileSave, pstrResult, fnCallback, cookie );

	return dwRet;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -