?? httpdown.cpp
字號(hào):
// HttpDown.cpp : implementation file
//
#include "stdafx.h"
#include "HttpDown.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHttpDown
static const TCHAR szHeaders[] = _T("Accept: */*\r\n");
static const TCHAR AgentName[] = _T("USER");
static DWORD dwHttpRequestFlags = INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE ;
void CSearchSession::OnStatusCallback(DWORD dwContext,
DWORD dwInternetStatus,LPVOID lpvStatusInfomration,
DWORD dwStatusInformationLen)
{
CString strStatus;
switch(dwInternetStatus)
{
case INTERNET_STATUS_STATE_CHANGE:
strStatus= _T("服務(wù)器正忙");
break;
case INTERNET_STATUS_REQUEST_COMPLETE:
strStatus= _T("請(qǐng)求完成");
break;
case INTERNET_STATUS_CONNECTING_TO_SERVER:
strStatus= _T("正在連接到服務(wù)器...");
break;
case INTERNET_STATUS_RESOLVING_NAME:
strStatus.Format(_T("解析主機(jī)地址..."));
break;
case INTERNET_STATUS_NAME_RESOLVED:
strStatus.Format(_T("主機(jī)地址已確認(rèn)"));
break;
case INTERNET_STATUS_CONNECTED_TO_SERVER:
strStatus= _T("成功連接到服務(wù)器");
break;
case INTERNET_STATUS_SENDING_REQUEST:
strStatus= _T("正在發(fā)送請(qǐng)求...");
break;
case INTERNET_STATUS_REQUEST_SENT:
strStatus= _T("請(qǐng)求發(fā)送成功");
break;
case INTERNET_STATUS_RECEIVING_RESPONSE:
strStatus= _T("正在接收數(shù)據(jù)...");
break;
// strStatus= _T("正在接收回應(yīng)...");
// break;
// case INTERNET_STATUS_RESPONSE_RECEIVED:
// strStatus= _T("回應(yīng)接收成功");
// break;
case INTERNET_STATUS_CLOSING_CONNECTION:
strStatus= _T("正在關(guān)閉連接...");
break;
case INTERNET_STATUS_CONNECTION_CLOSED:
strStatus= _T("連接關(guān)閉成功");
break;
case INTERNET_STATUS_HANDLE_CLOSING:
strStatus= _T("正在關(guān)閉連接...");
case INTERNET_STATUS_HANDLE_CREATED:
strStatus= _T("連接已經(jīng)建立");
break;
case INTERNET_STATUS_REDIRECT:
strStatus = _T("重定向地址");
break;
// case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
// default:
// strStatus.Format(_T("未知狀態(tài): %d"), dwInternetStatus);
// break;
}
LPCTSTR pStauts = strStatus;
::SendMessage (AfxGetMainWnd()->m_hWnd,
WM_USER_SERVER_STATUS, (WPARAM)dwContext,(LPARAM)pStauts);
}
CHttpDown::CHttpDown()
{
m_pSession = NULL;
m_pServer =NULL;
m_pFile= NULL;
}
CHttpDown::~CHttpDown()
{
CleanUp();
}
/////////////////////////////////////////////////////////////////////////////
// CHttpDown message handlers
BOOL CHttpDown::InitServer(URLParams *pURLParams)
{
try{
if(!pURLParams->m_strProxy.IsEmpty())
m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext,
INTERNET_OPEN_TYPE_PROXY,pURLParams->m_strProxy,pURLParams->m_strPort);
else
m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext);
int ntimeOut = 30; // very important, can cause a Server time-out if set to low
// or hang the thread if set to high.
/*
The time-out value in milliseconds to use for Internet connection requests.
If a connection request takes longer than this timeout, the request is canceled.
The default timeout is infinite. */
m_pSession->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,1000* ntimeOut);
/* The delay value in milliseconds to wait between connection retries.*/
m_pSession->SetOption(INTERNET_OPTION_CONNECT_BACKOFF,1000);
if(pURLParams->m_dwTimeOut != 0)
m_pSession->SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT,
&pURLParams->m_dwTimeOut,sizeof(pURLParams->m_dwTimeOut));
/* The retry count to use for Internet connection requests. If a connection
attempt still fails after the specified number of tries, the request is canceled.
The default is five. */
m_pSession->SetOption(INTERNET_OPTION_CONNECT_RETRIES,1);
m_pSession->EnableStatusCallback(TRUE);
}
catch (CInternetException* pEx)
{
// catch errors from WinINet
//pEx->ReportError();
m_pSession = NULL;
pEx->Delete();
return FALSE ;
}
return TRUE;
}
BOOL CHttpDown::ParseURL(URLParams *pURLParams)
{
BOOL bRet = FALSE;
if(pURLParams->m_pszURL.IsEmpty()) return bRet;
LPCTSTR lpsz = pURLParams->m_pszURL;
if(lpsz == NULL) return bRet;
int nLen = lstrlen(lpsz);
int i=0;
while (nLen)
{
if( *lpsz == '/') i++;
++lpsz;
nLen--;
}
if( i< 3) pURLParams->m_pszURL += '/';
try
{
AfxParseURL(pURLParams->m_pszURL,pURLParams->m_dwServiceType,
pURLParams->m_strServerName,pURLParams->m_strObject,
pURLParams->m_nPort);
}
catch (CInternetException* pEx)
{
// catch errors from WinINet
//pEx->ReportError();
pEx->Delete();
return bRet;
}
lpsz = pURLParams->m_strObject;
if(lpsz == NULL) return bRet;
bRet = TRUE;
nLen = lstrlen(lpsz);
BOOL bdot = FALSE;
while (nLen)
{
if( *lpsz == '.') bdot = TRUE;
++lpsz;
nLen--;
}
if(pURLParams->m_strObject.GetLength()-1 > 0)
{
if( bdot == FALSE && pURLParams->m_strObject[pURLParams->m_strObject.GetLength()-1] != '/')
pURLParams->m_strObject += '/';
}
return bRet;
}
BOOL CHttpDown::GetHttpFile(LPCTSTR ServerName,LPCTSTR strObject,URLParams *pURLParams)
{
CString rString;
LPCTSTR lpsz;
LPCTSTR lpszStop;
int j=0;
TCHAR sz[4096];
memset(sz,'\0',sizeof(sz));
if(strObject == NULL) return FALSE;
DWORD dwRet = GetHttpStatus(ServerName, strObject,pURLParams);
if(dwRet != HTTP_STATUS_OK){
CString strStatus;
switch(dwRet)
{
case ERROR_INTERNET_TIMEOUT:
strStatus.Format(_T("與服務(wù)器連接超時(shí)"));
break;
case ERROR_INTERNET_NAME_NOT_RESOLVED:
strStatus.Format(_T("無法連接到指定頁面"));
break;
case HTTP_STATUS_NOT_FOUND:
strStatus.Format(_T("找不到服務(wù)器"));
break;
// default:
// strStatus.Format(_T("未知錯(cuò)誤: %d"),dwRet);
// break;
}
LPCSTR line = strStatus;
::SendMessage(AfxGetMainWnd()->m_hWnd,
WM_USER_SERVER_STATUS,0,(LPARAM)line);
// ::SendMessage(AfxGetMainWnd()->m_hWnd,
// WM_USER_SEND_ERRINFO,0,(LPARAM)line);
return FALSE;
}
long xx = pURLParams->m_dwIngoreLength;
CString strLength;
m_pFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH,strLength);
DWORD dwLength = atol(strLength);
if(pURLParams->m_dwIngoreLength != -1 &&
dwLength > pURLParams->m_dwIngoreLength) return FALSE;
if(m_pFile != NULL && m_pServer != NULL && m_pSession != NULL)
{
try
{
while (m_pFile->ReadString(sz, 4095))
{
rString = _T("");
lpsz = sz;
if(lpsz != NULL)
{
lpszStop = sz + lstrlen(sz);
j=0;
while (lpsz < lpszStop)
{
// if(*lpsz =='\n') rString += "\r\n";
if(*lpsz =='\n') rString += '\n';
else rString += sz[j];
++lpsz;
j++;
}
pURLParams->m_Contents += rString;
}
}
}
catch (CInternetException* pEx)
{
m_pFile= NULL;
pEx->Delete();
return 0;
}
}
return TRUE;
}
DWORD CHttpDown::NewConnection(LPCTSTR ServerName,LPCTSTR strObject,URLParams *pURLParams)
{
if(ServerName == NULL || strObject == NULL) return 0;
DWORD dwRet = HTTP_STATUS_OK;
INTERNET_PORT nPort = INTERNET_DEFAULT_HTTP_PORT;
try{
if(!pURLParams->m_strProxy.IsEmpty())
m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext,
INTERNET_OPEN_TYPE_PROXY,pURLParams->m_strProxy,pURLParams->m_strPort);
else
m_pSession = new CSearchSession(AgentName,pURLParams->m_dwContext);
int ntimeOut = 30;
/*
The time-out value in milliseconds to use for Internet connection requests.
If a connection request takes longer than this timeout, the request is canceled.
The default timeout is infinite. */
m_pSession->SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,1000* ntimeOut);
/* The delay value in milliseconds to wait between connection retries.*/
m_pSession->SetOption(INTERNET_OPTION_CONNECT_BACKOFF,1000);
if(pURLParams->m_dwTimeOut != 0)
m_pSession->SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT,
&pURLParams->m_dwTimeOut,sizeof(pURLParams->m_dwTimeOut));
/* The retry count to use for Internet connection requests. If a connection
attempt still fails after the specified number of tries, the request is canceled.
The default is five. */
m_pSession->SetOption(INTERNET_OPTION_CONNECT_RETRIES,2);
m_pSession->EnableStatusCallback(TRUE);
// m_pSession->m_strHttpSite.Format(_T("%s%s"),ServerName,strObject);
}
catch (CInternetException* pEx)
{
// catch errors from WinINet
dwRet = pEx->m_dwError;
m_pSession=NULL;
pEx->Delete();
return dwRet;
}
try
{
m_pServer = m_pSession->GetHttpConnection(ServerName,nPort);
}
catch (CInternetException* pEx)
{
// catch errors from WinINet
dwRet = pEx->m_dwError;
m_pServer = NULL;
pEx->Delete();
CleanUp();
return dwRet;
}
m_strCurrentServer = ServerName;
try
{
// This can never return NULL. The call may have failed, but it can
// never be null.
m_pFile = m_pServer->OpenRequest(_T("GET"),strObject,NULL,
pURLParams->m_dwContext, NULL, NULL, dwHttpRequestFlags);
m_pFile->SendRequest();
}
catch (CInternetException* pEx)
{
// catch errors from WinINet
dwRet = pEx->m_dwError;
m_pFile = NULL;
pEx->Delete();
CleanUp();
return dwRet;
}
return dwRet;
}
DWORD CHttpDown::GetHttpStatus(LPCTSTR lpServerName,LPCTSTR strObject,URLParams *pURLParams)
{
if(lpServerName == NULL || strObject == NULL) return 0;
INTERNET_PORT nPort = INTERNET_DEFAULT_HTTP_PORT;
DWORD dwRet = 1;
if (m_pSession == NULL)
return dwRet;
// m_pSession->m_strHttpSite.Format(_T("%s%s"),lpServerName,strObject);
dwRet = 2;
if(m_pFile != NULL)
{
m_pFile->Close();
delete m_pFile;
m_pFile=NULL;
}
if (m_strCurrentServer != lpServerName)
{
// Picked a new server, close out connection and make a new one:
if (m_pServer != NULL)
{
m_pServer->Close ();
delete m_pServer;
m_pServer = NULL;
}
}
if (m_pServer == NULL)
{
try
{
m_pServer = m_pSession->GetHttpConnection(lpServerName,nPort);
}
catch (CInternetException* pEx)
{
dwRet = pEx->m_dwError;
m_pServer = NULL;
pEx->Delete();
if(!CleanUp()) return FALSE;
return dwRet;
}
m_strCurrentServer = lpServerName;
}
if (m_pServer == NULL) return dwRet;
try
{
// This can never return NULL. The call may have failed, but it can
// never be null.
m_pFile = m_pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
strObject,NULL, pURLParams->m_dwContext, NULL, NULL, dwHttpRequestFlags);
m_pFile->SendRequest();
}
catch (CInternetException* pEx)
{
// catch errors from WinINet
//pEx->ReportError();
dwRet = pEx->m_dwError;
m_pFile = NULL;
pEx->Delete();
if(!CleanUp()) return FALSE;
if(dwRet == ERROR_INTERNET_TIMEOUT ) Sleep(1000); // Connection timed out, try again on new connection
dwRet = NewConnection(lpServerName,strObject,pURLParams);
if(dwRet != HTTP_STATUS_OK) return dwRet;
}
if(m_pFile != NULL)
m_pFile->QueryInfoStatusCode(dwRet);
return dwRet;
}
BOOL CHttpDown::CleanUp()
{
m_strCurrentServer.Empty();
try
{
if(m_pFile != NULL)
{ m_pFile->Close();
delete m_pFile;
m_pFile= NULL;
}
if (m_pServer!= NULL)
{
m_pServer->Close();
delete m_pServer;
m_pServer = NULL;
}
if (m_pSession != NULL)
{
m_pSession->Close();
delete m_pSession;
m_pSession = NULL;
}
}
// catch (CInternetException* pEx)
// {
// // catch errors from WinINet
// pEx->Delete();
// return FALSE;
// }
catch(...)
{
return FALSE;
}
return TRUE;
}
CString CHttpDown::GetHttpFileGet(LPCTSTR pstrURL,
DWORD dwContext/* = 1000*/,DWORD dwTimeOut/* = 0*/,
LPCTSTR pstrProxy/* = NULL*/,LPCTSTR pstrPort/* = NULL*/,
DWORD dwIngoreLength/* = -1*/)
{
URLParams *pURLParams = new URLParams;
pURLParams->m_pszURL = pstrURL;
pURLParams->m_dwContext = dwContext;
pURLParams->m_dwTimeOut = dwTimeOut;
pURLParams->m_dwIngoreLength = dwIngoreLength;
if(pstrProxy != NULL)
pURLParams->m_strProxy = pstrProxy;
if(pstrPort != NULL)
pURLParams->m_strPort = pstrPort;
if(!InitServer(pURLParams)) {
dwError = ERROR_INIT_SERVER;
delete pURLParams;
// return NULL;
return _T("");
}
if(pURLParams->m_pszURL.IsEmpty()){
dwError = ERROR_URL_NULL;
delete pURLParams;
// return NULL;
return _T("");
}
if(!pURLParams){
dwError = ERROR_NEW_PARAMS;
delete pURLParams;
// return NULL;
return _T("");
}
if(!ParseURL(pURLParams)) {
dwError = ERROR_PARSE_URL;
delete pURLParams;
// return NULL;
return _T("");
}
if(!GetHttpFile(pURLParams->m_strServerName,pURLParams->m_strObject,pURLParams))
{
dwError = ERROR_GET_HTTPFILE;
delete pURLParams;
// return NULL;
return _T("");
}
// LPCTSTR pContent = pURLParams->m_Contents;
// delete pURLParams;
// return pContent;
return pURLParams->m_Contents;
}
CString CHttpDown::GetLastErrorText()
//LPCTSTR CHttpDown::GetLastErrorText()
{
CString strError;
switch(dwError)
{
case ERROR_NEW_PARAMS:
strError.Format(_T("內(nèi)存申請(qǐng)失敗"));
break;
case ERROR_INIT_SERVER:
strError.Format(_T("連接到服務(wù)器失敗"));
break;
case ERROR_URL_NULL:
strError.Format(_T("地址為空"));
break;
case ERROR_PARSE_URL:
strError.Format(_T("解析地址失敗"));
break;
case ERROR_GET_HTTPFILE:
strError.Format(_T("接收文件時(shí)出錯(cuò)"));
break;
}
// LPCTSTR pstrError = strError;
// return pstrError;
return strError;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -