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

📄 request.cpp

📁 初学者学习HTTP协议的有用代码
💻 CPP
字号:
// Request.cpp: implementation of the Request class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HttpLook.h"
#include "Request.h"

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

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

Request::Request()
{

}

Request::~Request()
{

}
void Request::MenBufferCreate(MemBuffer &m)
{
	m.size=MEM_BUFFER_SIZE;
	m.buffer=(unsigned char *)malloc(m.size);
	m.position=m.buffer;
	return;
}
void Request::MenBufferGrow(MemBuffer &m)
{
	size_t sz;
    sz = m.position - m.buffer;
	m.size=m.size*2;
	m.buffer=(unsigned char *)realloc(m.buffer,m.size);
	m.position=m.buffer+sz;
}
void Request::MenBufferAddbyte(MemBuffer &m,BYTE byte)
{
	if((size_t)(m.position-m.buffer)>=m.size)
	{
		MenBufferGrow(m);
	}
	*m.position=byte;
	m.position++;
}
void Request::MenBufferAdd(MemBuffer &m,unsigned char * buffer,size_t size)
{
	size_t sz=(size_t)(m.position-m.buffer);
	while(sz+size>=m.size)
	{
		MenBufferGrow(m);
		if(sz+size<m.size)
			break;
	}
	memcpy(m.position,buffer,size);
	m.position+=size;
}
void Request::SendRequest(LPCSTR url,HWND hwnd,int nIsPost,CString &strHeaderPost,CString &strHeaderSend,
						  CString &strHeaderRecive,CString &strMessage)
{
 	HTTPRequest			req;
    int					i,rtn;
    LPSTR				buffer;
    req.headerSend							= NULL;
	req.headerReceive						= NULL;
    req.message								= NULL;
    //Read in arguments
    
	if(nIsPost)
    {													/* POST */
		i		= strHeaderPost.GetLength();
		buffer  = (char*) malloc(i+1);
		strcpy(buffer, (LPCTSTR)strHeaderPost);
		rtn	= SendHttp(	url,
						hwnd,
						"Content-Type: application/x-www-form-urlencoded\r\n",
						(unsigned char*)buffer,
						i,
						&req);  
        free(buffer);
    }
    else												/* GET */
        rtn = SendHttp(url,hwnd,NULL,NULL,0,&req);
	if(!rtn)											//Output message and/or headerSend 
	{
		strHeaderSend		= req.headerSend;
		strHeaderRecive	= req.headerReceive;
		strMessage			= req.message;
		free(req.headerSend);
		free(req.headerReceive);
        free(req.message);
    }
    else
		SendMessage(hwnd,WM_SENDMESSAGE,3,0);
}

int Request::SendHttp(LPCSTR url,HWND hwnd,LPCSTR headerReceive,BYTE *post,
					   DWORD postLength,HTTPRequest *req)
{
	WSADATA			WsaData;
	SOCKADDR_IN		sin;
    SOCKET			sock;
    char			buffer[512];
    CString			protocol,host,request;
    int				l,port,chars,err;
    MemBuffer		headersBuffer,messageBuffer;
	char			headerSend[1024];
    BOOL			done;
	ParseURL(url,protocol,host,request,port);
	if(protocol!="HTTP")
		return 1;
	err=WSAStartup(0x0101,&WsaData);
	if(err!=0)
		return 1;
	sock=socket(AF_INET,SOCK_STREAM,0);
	if (sock == INVALID_SOCKET)
       return 1;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(port);
	sin.sin_addr.S_un.S_addr = GetHostAddress(host);
	SendMessage(hwnd,WM_SENDMESSAGE,1,0);
	if( connect(sock,(LPSOCKADDR)&sin, sizeof(SOCKADDR_IN))==SOCKET_ERROR)
	{
        return 1;		
	}
	SendMessage(hwnd,WM_SENDMESSAGE,2,0);
	
////////////////////////////发送请求头////////////////
	if( post == NULL )
	{
		SendMessage(hwnd,WM_SENDMESSAGE,4,0);
        SendString(sock,"GET ");
		strcpy(headerSend, "GET ");
	}
    else 
	{
		SendMessage(hwnd,WM_SENDMESSAGE,5,0);
		SendString(sock,"POST ");
		strcpy(headerSend, "POST ");
	}
//发送请求的内容(必选)
	  SendString(sock,request);
		strcat(headerSend, request);
//发送协议版本(必选)
    SendString(sock," HTTP/1.0\r\n");
		strcat(headerSend, " HTTP/1.0\r\n");
//指定客户能处理的页面类型(可选)
    SendString(sock,"Accept: image/gif, image/x-xbitmap,"
        " image/jpeg, image/pjpeg, application/vnd.ms-excel,"
        " application/msword, application/vnd.ms-powerpoint,"
        " */*\r\n");
		strcat(headerSend, "Accept: image/gif, image/x-xbitmap,"
        " image/jpeg, image/pjpeg, application/vnd.ms-excel,"
        " application/msword, application/vnd.ms-powerpoint,"
        " */*\r\n");
//指定客户能处理的自然语言(可选)
    SendString(sock,"Accept-Language: en-us\r\n");
		strcat(headerSend, "Accept-Language: en-us\r\n");
//指定客户能处理的页面编码方法(可选)
    SendString(sock,"Accept-Encoding: gzip, deflate\r\n");
		strcat(headerSend, "Accept-Encoding: gzip, deflate\r\n");
//描述浏览器的信息(可选)
   SendString(sock,"User-Agent: Mozilla/4.0\r\n");
		strcat(headerSend, "User-Agent: Mozilla/4.0\r\n");
   //以字节计算页面的长度
	if(postLength)
    {
        wsprintf(buffer,"Content-Length: %ld\r\n",postLength);
        SendString(sock,buffer);
		strcat(headerSend, buffer);
    }
	//发送服务器DNS名字(必选)
   SendString(sock,"Host: ");
		strcat(headerSend, "Host: ");
    SendString(sock,host);
		strcat(headerSend, (LPCSTR)host);
	SendString(sock,"\r\n");
		strcat(headerSend, "\r\n");

//发送Post请求的头信息
   if( (headerReceive!=NULL) && *headerReceive )
	{
        SendString(sock,headerReceive);
		strcat(headerSend, headerReceive);
	}
 
  // Send a blank line to signal end of HTTP headerReceive 请求头信息结束 
    SendString(sock,"\r\n");							
	strcat(headerSend, "\r\n");

	SendMessage(hwnd,WM_SENDMESSAGE,6,0);

//发送请求体,在请求类型为post时,是请求的类容
    if( (post!=NULL) && postLength )
	{
        send(sock,(const char*)post,postLength,0);
		post[postLength]	= '\0';		
		strcat(headerSend, (const char*)post);
		SendMessage(hwnd,WM_SENDMESSAGE,7,0);
	}
//保存请求头信息
	req->headerSend		= (char*) malloc( sizeof(char*) * strlen(headerSend));
	strcpy(req->headerSend, (char*) headerSend );

////////////////////////////////接受服务器端数据///////////////////
    MenBufferCreate(headersBuffer);
    chars = 0;
    done = FALSE;
	SendMessage(hwnd,WM_SENDMESSAGE,8,0);
    while(!done)
    {
        l = recv(sock,buffer,1,0);
        if(l<0)
            done=TRUE;

        switch(*buffer)
        {
            case '\r':
                break;
            case '\n'://连续两个换行表示存在一空行,响应头结束
                if(chars==0)
				{
                    done = TRUE;
				}
                chars=0;
                break;
            default:
                chars++;
                break;
        }
        MenBufferAddbyte(headersBuffer,*buffer);
    }
	SendMessage(hwnd,WM_SENDMESSAGE,9,0);
    req->headerReceive	= (char*) headersBuffer.buffer;
    *(headersBuffer.position) = 0;

    MenBufferCreate(messageBuffer);	// Now read the HTTP body
	SendMessage(hwnd,WM_SENDMESSAGE,10,0);
    do
    {
        l = recv(sock,buffer,sizeof(buffer)-1,0);
        if(l<0)
            break;
        *(buffer+l)=0;
        MenBufferAdd(messageBuffer, (unsigned char*)&buffer, l);
    } while(l>0);
	SendMessage(hwnd,WM_SENDMESSAGE,11,0);
    *messageBuffer.position = 0;
    req->message = (char*) messageBuffer.buffer;
    req->messageLength = (messageBuffer.position - messageBuffer.buffer);

    closesocket(sock);// Cleanup
	SendMessage(hwnd,WM_SENDMESSAGE,12,0);
	return 0;
}
void Request::ParseURL(LPCSTR url,CString &protocol,CString &host,CString &request,int &port)
{
	CString strURL,strhost,strrequest,strport;
	strURL.Format("%s",url);
	strURL.TrimLeft();
//	ValidURL(strURL);
	strhost=host;
	strrequest=request;
	protocol="HTTP";
	int nPro=strURL.Find("http://"),nPos;
	if(nPro!=-1)
	{
		nPos=strURL.Find(':');
		nPos++;
		if(strURL.GetAt(nPos)=='/')
		{
			nPos+=2;
		}
	}
	else
		nPos=0;
	char ptrhost[256];
	int i=0;
	TCHAR c=strURL.GetAt(nPos);
	while(c!=':' && c!='/')//读取主机名
	{					
		ptrhost[i]=c;
		nPos++,i++;		
		if(nPos>=strURL.GetLength())
			break;
		c=strURL.GetAt(nPos);
	}
	if(ptrhost[i]!='\0')
		ptrhost[i]='\0';
	strhost.Format("%s",ptrhost);
	if(nPos<strURL.GetLength())//判断是否已到URL末端
	{//1
		c=strURL.GetAt(nPos);
		char ptrport[256];
		i=0;
		if(c==':')
		{//2	
			nPos++;	
			c=strURL.GetAt(nPos);
			while(c!='/')
			{//3	
				ptrhost[i]=c;
				nPos++,i++;				
				if(nPos>=strURL.GetLength())
					break;
				c=strURL.GetAt(nPos);
				if(c<48 && c>57)
				{
					AfxMessageBox("端口号中不能有非数字字符,请重输!");
					break;
				}			
			}//3'
			if(ptrport[i]!='\0')
				ptrport[i]='\0';
			strport.Format("%s",ptrport);
		}//2
		else
			strport="80";
		if(c=='/')//2'
			strrequest=strURL.Right(strURL.GetLength()-nPos);
		else
			strrequest="/";
	}//1
	else
	{
		strport="80" ,strrequest="/";
	}
	host=strhost,port=atoi(strport),request=strrequest;
}
DWORD Request::GetHostAddress(LPCSTR host)
{
    struct hostent *phe;
    char *p;
   phe = gethostbyname( host );           
    if(phe==NULL)
        return 0;  
    p = *phe->h_addr_list;
    return *((DWORD*)p);
}
void Request::SendString(SOCKET sock,LPCSTR str)
{
    send(sock,str,strlen(str),0);
}

⌨️ 快捷键说明

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