?? request.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 + -