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

📄 clienthttp.cpp

📁 wince 下socket实现的HTTP类
💻 CPP
字号:
/*******************************************************************************
 * (C) Copyright 2008 Giant Electronics LTD 
 * 
 * These computer program listings and specifications are the property of Giant 
 * Electronics LTD and shall not be reproduced or copied or used in whole or in 
 * part without written permission from Giant Electronics LTD .
 *
 * Project:      IViewer 
 * File Name:	ClientHTTP.cpp
 * Programer(s):	Ben Zhan
 * Created:      20080729 
 * Description:	implementation of encapsulating HTTP protocol
 * This class encapsulates HTTP protocol and provides the functionality to request 
 and read files on an HTTP server.
 *******************************************************************************/
#include "stdafx.h"
#include "ClientHTTP.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CClientHTTP::CClientHTTP()
{	
}

CClientHTTP::~CClientHTTP()
{
}

//*******************************************************************************************************   
//   ValidHostChar:     
// Return   TRUE   if   the   specified   character   is   valid   
// for   a   host   name,   i.e.   A-Z   or   0-9   or   -.:     
//*******************************************************************************************************   
BOOL   CClientHTTP::ValidHostChar(TCHAR   ch)   
{   
    return(   iswalpha(ch)   ||   iswdigit(ch)||   ch==('-')   ||   ch==('.')   ||   ch==(':')   );
}

void   CClientHTTP::ParseURL(LPCSTR   url,LPSTR   protocol,int   lprotocol,LPSTR   host,int   lhost,LPSTR   request,int   lrequest,int   *port)   
{   
    LPSTR   work,ptr,ptr2;
    //added by bpan
    //reason: to avoid buffer overflow
    //2008/09/29
    int iMinLen; 
    *protocol = *host = *request = 0;   
    *port=80;

    work   =   _strdup(url);
    //	_strupr(work);  

    ptr   =   strchr(work,':'); //   find   protocol   if   any   
    if(ptr!=NULL)   
    {   
	*(ptr++)   =   0;
	iMinLen = min(lprotocol-1, strlen(work));
	strncpy(protocol,work, iMinLen);
    }   
    else   
    {   
	iMinLen = min(lprotocol -1, 4);
	strncpy(protocol,"HTTP", iMinLen);
	ptr   =   work;   
    }   
    protocol[iMinLen] = TCHAR('\0');

    if(   (*ptr=='/')   &&   (*(ptr+1)=='/')   ) //   skip   past   opening   /'s     
	ptr+=2;   

    ptr2   =   ptr; //   find   host   
    while(   ValidHostChar(*ptr2)   &&   *ptr2   )   
	ptr2++;   

    *ptr2=0;   
    iMinLen = min(lhost -1, strlen(ptr));
    strncpy(host,ptr, iMinLen);
    host[iMinLen] = TCHAR('\0');
    //lstrcpyn(host,ptr,lhost);   
    iMinLen = min(lrequest -1, strlen(url + (ptr2 - work))); 
    strncpy(request,url+(ptr2-work), iMinLen); //   find   the   request   
    request[iMinLen] = TCHAR('\0');
    if( strlen((LPSTR)request) ==0 )
	strcpy(request,"/");



    ptr   =   strchr(host,':'); //   find   the   port   number,   if   any   
    if(ptr!=NULL)   
    {   
	*ptr=0;   
	*port   =   atoi(ptr+1);   
    }   

    free(work);   
}
int   CClientHTTP::SendURLRequest(LPCSTR   lpszURL,HANDLE hCancelEvent)
{
    char acProtocol[20],acHost[256],acRequest[256*4];   
    int  iPort;		
    long nLength;

    memset(m_RequestHeaderBuf,0,HTTPHEADER_MAX_SIZE); 


    ParseURL(lpszURL,acProtocol,sizeof(acProtocol),acHost,sizeof(acHost),
	    acRequest,sizeof(acRequest),&iPort);  
    FormatRequestHeader(acHost,acRequest,nLength);

    SetConnectTimeout(30000);
    if (!Connect(acHost,iPort,hCancelEvent))
		return E_HTTP_CONNECT_FAILED ;

    if (Send((char*)m_RequestHeaderBuf,nLength) != S_SOCKET_OK )
		return E_HTTP_REQUEST_FAILED ;

    return   E_HTTP_SUCCEED ;
}

int   CClientHTTP::SendRequest(bool   bIsPost,   LPCSTR   lpszUrl,   LPSTR lpszPostMsg,  
	int iPostLength, HANDLE hCancelEvent)   
{    

    if(bIsPost)   
    { 
		return SendHTTP( lpszUrl,   
			("Content-Type:   application/x-www-form-urlencoded\r\n"),   
			(unsigned   char*)lpszPostMsg,iPostLength,hCancelEvent);   

    }   
    else 
		return SendHTTP(lpszUrl,NULL,NULL,0,hCancelEvent);

} 

int   CClientHTTP::SendHTTP(LPCSTR   lpszURL,LPCSTR  lpszHeaderReceive,BYTE * post,DWORD   dwPostLength,HANDLE hCancelEvent) 
{   
    char acProtocol[20],acHost[256],acRequest[256];   
    int  iPort;		
    long nLength;

    memset(m_RequestHeaderBuf,0,HTTPHEADER_MAX_SIZE); 


    ParseURL(lpszURL,acProtocol,sizeof(acProtocol),acHost,sizeof(acHost),
	    acRequest,sizeof(acRequest),&iPort);  

	if(dwPostLength)
		FormatPostRequestHeader(acHost,acRequest,dwPostLength,nLength);
	else
		FormatRequestHeader(acHost,acRequest,nLength);


    if (!Connect(acHost,iPort,hCancelEvent))
		return E_HTTP_CONNECT_FAILED ;

    if (Send((char*)m_RequestHeaderBuf,nLength) != S_SOCKET_OK)
		return E_HTTP_REQUEST_FAILED ;


    return   E_HTTP_SUCCEED ;
}  

///根据请求的相对URL输出HTTP请求头
const char *CClientHTTP::FormatRequestHeader(LPSTR lpszServer,
	LPSTR lpszObject,long &lLength,
	LPSTR lpszCookie,LPSTR lpszReferer,
	long lFrom,long lTo,
	int nServerType)
{

    char szTemp[20];
    char* pstr;

    memset(m_RequestHeaderBuf,0,HTTPHEADER_MAX_SIZE); 

    ///第1行:方法,请求的路径,版本
    int iIndex = 0 ;
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"GET ",4);
    iIndex +=4;
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)lpszObject,strlen(lpszObject));
    iIndex +=strlen(lpszObject);

    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)" HTTP/1.0",strlen(" HTTP/1.0"));
    iIndex +=strlen(" HTTP/1.1");	

    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");	



    ///第2行:主机
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"Host:",5);
    iIndex +=5;
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)lpszServer,strlen(lpszServer));
    iIndex +=strlen(lpszServer);
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");


    ///第3行:
    if(lpszReferer != NULL)
    {
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"Referer:",8);
	iIndex +=8;
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)lpszReferer,strlen(lpszReferer));
	iIndex +=strlen(lpszReferer);
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
	iIndex +=strlen("\r\n");
    }

    ///第4行:接收的数据类型
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"Accept:*/*",strlen("Accept:*/*"));
    iIndex +=strlen("Accept:*/*");
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");


    ///第5行:浏览器类型
    pstr="User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)";
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)pstr,strlen(pstr));
    iIndex +=strlen(pstr);
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");


    ///第6行:连接设置,保持
    pstr="Connection:Keep-Alive";
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)pstr,strlen(pstr));
    iIndex +=strlen(pstr);
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");


    ///第7行:Cookie.
    if(lpszCookie != NULL)
    {
	pstr="Set Cookie:0";
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)pstr,strlen(pstr));
	iIndex +=strlen(pstr);
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)lpszCookie,strlen(lpszCookie));
	iIndex +=strlen(lpszCookie);
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
	iIndex +=strlen("\r\n");
    }

    ///第8行:请求的数据起始字节位置(断点续传的关键)
    if(lFrom > 0)
    {
	pstr="Range: bytes=";
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)pstr,strlen(pstr));
	iIndex +=strlen(pstr);		
	_ltoa(lFrom,szTemp,10);
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)szTemp,strlen(szTemp));
	iIndex +=strlen(szTemp);		
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"-",strlen("-"));
	iIndex +=strlen("-");

	if(lTo > lFrom)
	{
	    _ltoa(lTo,szTemp,10);
	    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)szTemp,strlen(szTemp));
	    iIndex +=strlen(szTemp);		
	}
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
	iIndex +=strlen("\r\n");
    }

    ///最后一行:空行
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");

    ///返回结果
    lLength= iIndex ;
    return m_RequestHeaderBuf;

}


///根据请求的相对URL输出HTTP请求头
const char *CClientHTTP::FormatPostRequestHeader(LPSTR lpszServer,LPSTR lpszObject,long lPostDataLength,long &lLength)
{
	
//    char szTemp[20];
    char* pstr;
	
    memset(m_RequestHeaderBuf,0,HTTPHEADER_MAX_SIZE); 
	
    ///第1行:方法,请求的路径,版本
    int iIndex = 0 ;
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"POST ",5);
    iIndex +=5;
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)lpszObject,strlen(lpszObject));
    iIndex +=strlen(lpszObject);
	
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)" HTTP/1.0",strlen(" HTTP/1.0"));
    iIndex +=strlen(" HTTP/1.1");	
	
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");	
	
	
    ///第2行:主机
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"Host:",5);
    iIndex +=5;
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)lpszServer,strlen(lpszServer));
    iIndex +=strlen(lpszServer);
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");
	
    ///第5行:浏览器类型
    pstr="User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)";
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)pstr,strlen(pstr));
    iIndex +=strlen(pstr);
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");
	
	
	pstr = "Content-Type:   application/x-www-form-urlencoded";
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)pstr,strlen(pstr));
    iIndex +=strlen(pstr);
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");
	
	memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"Content-Type:   ",16);
	iIndex +=16;
	char strLength[256];
	sprintf(strLength,"%d",lPostDataLength);
	memcpy(m_RequestHeaderBuf+iIndex,strLength,strlen(strLength));
	iIndex +=strlen(strLength);
	
	
	
    ///最后一行:空行
    memcpy(m_RequestHeaderBuf+iIndex,(BYTE*)"\r\n",strlen("\r\n"));
    iIndex +=strlen("\r\n");
	
    ///返回结果
    lLength= iIndex ;
    return m_RequestHeaderBuf;
	
}


//获取HTTP请求的返回头
int	CClientHTTP::ReceiveResponseHeader(HANDLE hCancelEvent)
{
    char cbuffer;	
    int l,chars;	
    BOOL done;

    int iRes;

    chars   =   0;   
    done   =   FALSE; 
    int iIndex = 0;
    int iRecvedSize = 0 ;
    memset(m_ResponeHeaderBuf,0,HTTPHEADER_MAX_SIZE); 




    try
    {
	while(!done)   
	{
	    iRes = WaitForSocket(WAIT_RECV,20,hCancelEvent);
	    if( iRes != S_SOCKET_OK )
			return iRes;

	    l   = recv(&cbuffer,1);

	    if (l == SOCKET_ERROR) 
	    {
			return E_SOCKET_FAIL ;
	    }
	    else if (l == 0)
	    {
			break;
	    }
	    else if(l<0)   
			break ;

	    switch(cbuffer)   
	    {   
		case   '\r':   
		    break;   
		case   '\n':   
		    if(chars==0)   
			done   =   TRUE;   
		    chars=0;   
		    break;   
		default:   
		    chars++;   
		    break;   
	    }
	    if(iIndex>=(HTTPHEADER_MAX_SIZE-1))
			return E_SOCKET_FAIL ;
	    m_ResponeHeaderBuf[iIndex] = cbuffer;	
			iIndex ++ ;
	}
    }
    catch(...)
    {
	return E_SOCKET_FAIL;
    }
    return   S_SOCKET_OK;   
}
//获取HTTP状态
int CClientHTTP::GetResponseStatus(DWORD &dwStatusCode)
{
    LPSTR pszStr = m_ResponeHeaderBuf;
    LPSTR ptr;
    char acStatusCode[32];
    memset(acStatusCode,0,32);

    ptr = strchr(pszStr,' ');
    if( ptr == NULL )
	return -1;
    pszStr = ptr + 1 ;

    ptr = strchr(pszStr,' ');
    if( ptr == NULL )
	return -1;
    memcpy(acStatusCode,pszStr,ptr-pszStr);		


    dwStatusCode = (DWORD)atoi(acStatusCode);
    return 0;
}


BYTE*	CClientHTTP::GetResponseHeader()
{
    return (BYTE*)m_ResponeHeaderBuf;
}
int CClientHTTP::GetField(LPCSTR lpcSession, LPSTR lpValue,LPSTR lpHeader)
{
    //取得某个域值
    LPSTR lpBuf = m_ResponeHeaderBuf ;
    LPSTR lpStr = new char[strlen(lpcSession)+1] ;
    if( lpStr==NULL)
	return 0;
    strcpy(lpStr,lpcSession);	

    if(lpHeader != NULL)
    {
	lpBuf = lpHeader ;
	_strupr(lpHeader);
	_strupr(lpStr);
    }
    LPSTR   ptr,ptr2;
    ptr = strstr((char*)lpBuf,lpStr);
    if( ptr != NULL)
    {
	ptr += strlen(lpStr);
	ptr += 2;
	ptr2 = strstr(ptr,"\r\n");
	if( ptr2 != NULL )
	{
	    strncpy(lpValue,ptr,ptr2-ptr);
	    lpValue[ptr2-ptr] = 0;
	    return ptr2-ptr;
	}
    }
    return 0;
}


DWORD CClientHTTP::GetMSizeFromW(LPWSTR lpwszStr)
{
    return WideCharToMultiByte(CP_OEMCP,NULL,lpwszStr,-1,NULL,0,NULL,FALSE);
}
DWORD CClientHTTP::GetWSizeFromM(LPCSTR lpcszStr)
{
    return MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);
}

BOOL CClientHTTP::MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize)
{
    // Get the required size of the buffer that receives the Unicode 
    // string. 
    DWORD dwMinSize;
    dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);

    if(dwSize < dwMinSize)
    {
	return FALSE;
    }


    // Convert headers from ASCII to Unicode.
    MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);  
    return TRUE;
}
BOOL CClientHTTP::WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize)
{
    DWORD dwMinSize;
    dwMinSize = WideCharToMultiByte(CP_ACP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);
    if(dwSize < dwMinSize)
    {
	return FALSE;
    }
    WideCharToMultiByte(CP_ACP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE);
    return TRUE;
}

⌨️ 快捷键说明

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