打造自己的HTTP代理服务器.docx
《打造自己的HTTP代理服务器.docx》由会员分享,可在线阅读,更多相关《打造自己的HTTP代理服务器.docx(16页珍藏版)》请在冰豆网上搜索。
打造自己的HTTP代理服务器
打造自己的HTTP代理服务器
打造自己的HTTP代理服务器/*=========================================================================
file:
HTTPPROXY.cpp
HTTPProxyv1.0
poweredbyshadow2004/11/14
myweb:
http:
//www.codehome.6600.org
QQ:
176017352
请先阅读有关http代理协议的相关资料,转载请著明出处
==========================================================================*/
#include"stdafx.h"
#include"HTTPPROXY.h"
#defineFD_NOEVENT0
//
#defineBACKUP100
#defineMAXDATALEN65535
intHttpListenPort;
SOCKETHttpListenSock;
//
typedefstruct_CLIENTINFO{
SOCKETclientsock;
SOCKETudpsock;
sockaddr_inclientsock_addr;
}CLIENTINFO,*LPCLIENTINFO;
CLIENTINFOHttpClientInfo;
//
typedefstruct_SOCKINFO{
SOCKETsourcesock;
SOCKETdestsock;
}SOCKINFO,*LPSOCKINFO;
SOCKINFOhttpsockinfo;
//
externlongGetSocketEventId(SOCKETremotesock);
externunsignedlongGetLocalIp();
externunsignedlongGetDomainIp(chardomainname[250]);
/*
longGetSocketEventId(SOCKETremotesock){
longEventId;
HANDLEhevent;
hevent=CreateEvent(NULL,0,0,0);
WSANETWORKEVENTSsocket_events;
EventId=FD_NOEVENT;
if(WSAEventSelect(remotesock,hevent,FD_ACCEPT|FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE)==SOCKET_ERROR)returnEventId;
WSAEnumNetworkEvents(remotesock,hevent,&socket_events);
if(socket_events.lNetworkEvents!
=0){
switch(socket_events.lNetworkEvents){
caseFD_ACCEPT:
EventId=FD_ACCEPT;break;
caseFD_CONNECT:
EventId=FD_CONNECT;break;
caseFD_READ:
EventId=FD_READ;break;
caseFD_WRITE:
EventId=FD_WRITE;break;
caseFD_CLOSE:
EventId=FD_CLOSE;break;
caseFD_OOB:
EventId=FD_OOB;break;
default:
EventId=FD_NOEVENT;break;
}
}
elseEventId=FD_NOEVENT;
returnEventId;
}
//
unsignedlongGetLocalIp()
{
charIP[MAX_PATH],*ip;
charpc_name[80];
structin_addrin;
structhostent*host;
WORDwVersionRequested;
WSADATAwsaData;
wVersionRequested=MAKEWORD(2,0);
ip=IP;
strcpy(ip,"Ipnotget!
");
if(WSAStartup(wVersionRequested,&wsaData))return0;
if(gethostname(pc_name,80)==SOCKET_ERROR){
WSACleanup();
return0;
}
if(!
(host=gethostbyname(pc_name))){
WSACleanup();
return0;
}
in.s_addr=*((unsignedlong*)host->h_addr_list[0]);
strcpy(ip,inet_ntoa(in));
WSACleanup();
returnin.s_addr;
}
//
unsignedlongGetDomainIp(chardomainname[250])
{
charIP[MAX_PATH],*ip;
structin_addrin;
structhostent*host;
WORDwVersionRequested;
WSADATAwsaData;
wVersionRequested=MAKEWORD(2,0);
ip=IP;
strcpy(ip,"Ipnotget!
");
if(WSAStartup(wVersionRequested,&wsaData))return0;
if(!
(host=gethostbyname(domainname))){
WSACleanup();
return0;
}
in.s_addr=*((unsignedlong*)host->h_addr_list[0]);
strcpy(ip,inet_ntoa(in));
WSACleanup();
returnin.s_addr;
}
*/
//
//
UINTHttpReciveThread(LPVOIDinfo){//针对客户端的接收处理线程
LPSOCKINFOpsockinfo;
SOCKETsourcesock,destsock;
chardata[MAXDATALEN];
longeventid;
intdatalen;
psockinfo=(LPSOCKINFO)info;
sourcesock=psockinfo->sourcesock;
destsock=psockinfo->destsock;
TRACE("deailrecivethreadok!
\r\n");
while(true){
eventid=GetSocketEventId(sourcesock);
switch(eventid){
caseFD_CLOSE:
TRACE("sfdclosed\r\n");
closesocket(destsock);
return1;
break;
default:
break;
}
eventid=GetSocketEventId(destsock);
switch(eventid){
caseFD_CLOSE:
closesocket(sourcesock);
TRACE("dfdclosed\r\n");
return1;
break;
default:
break;
}
datalen=recv(sourcesock,data,sizeof(data),0);
if(datalen==0){
closesocket(sourcesock);
closesocket(destsock);
TRACE("sfdclosed\r\n");
break;
}
if(datalen>0){
while(!
send(destsock,data,datalen,0));
}
Sleep
(1);
}
return1;
}
//
UINTHttpSendThread(LPVOIDinfo){//针对远程端的接收处理线程
LPSOCKINFOpsockinfo;
SOCKETsourcesock,destsock;
chardata[MAXDATALEN];
longeventid;
intdatalen;
psockinfo=(LPSOCKINFO)info;
sourcesock=psockinfo->sourcesock;
destsock=psockinfo->destsock;
TRACE("deailsendthreadok!
\r\n");
while(true){
eventid=GetSocketEventId(sourcesock);
switch(eventid){
caseFD_CLOSE:
TRACE("sfdclosed\r\n");
closesocket(destsock);
return1;
break;
default:
break;
}
eventid=GetSocketEventId(destsock);
switch(eventid){
caseFD_CLOSE:
closesocket(sourcesock);
TRACE("dfdclosed\r\n");
return1;
break;
default:
break;
}
datalen=recv(destsock,data,sizeof(data),0);
if(datalen==0){
closesocket(sourcesock);
closesocket(destsock);
TRACE("dfdclosed\r\n");
break;
}
if(datalen>0){
while(!
send(sourcesock,data,datalen,0));
}
Sleep
(1);
}
return1;
}
//
//
UINTHttpProxyServerThread(LPVOIDinfo){//针对一次服务的线程
LPCLIENTINFOpclientinfo;
SOCKETconnectsock,clientsock;
sockaddr_inremotesock_addr;
chardata[MAXDATALEN],url[250],temp[250],httpurl[250],portnum[10];
intdatalen,i,index_start,index_end,port;
CStringHttpString,UrlString,PortString;
pclientinfo=(LPCLIENTINFO)info;
clientsock=pclientinfo->clientsock;
ZeroMemory((void*)data,sizeof(data));
datalen=recv(clientsock,data,sizeof(data),0);
if(datalen<=0){
closesocket(clientsock);
return0;
}
HttpString.Format("%s",data);
UrlString=HttpString;
TRACE("gethttpstring:
\r\n");
TRACE(HttpString);
index_start=HttpString.Find("Host:
",0);//寻找url标记
if(index_start<=0){
closesocket(clientsock);
return0;
}
index_end=HttpString.Find("\r\n",index_start);
if(index_end<=0){
closesocket(clientsock);
return0;
}
UrlString=HttpString.Mid(index_start+6,index_end-index_start-6);//读取url字符串
TRACE("\r\ngeturl:
");
TRACE(UrlString);
wsprintf(url,"%s",UrlString);
strcpy(temp,url);
strcat(temp,":
");
datalen=strlen(temp);
if(HttpString.Find("GET",0)==0){//判断get命令,并处理
index_start=HttpString.Find(temp,0);
strcpy(httpurl,"http:
//");
if(index_start>0){
index_end=HttpString.Find("/",index_start);
if(index_end<=0){
closesocket(clientsock);
return0;
}
PortString=HttpString.Mid(index_start+datalen,index_end-index_start-datalen);
port=atoi(PortString);
strcat(httpurl,temp);
itoa(port,portnum,sizeof(portnum));
strcat(httpurl,portnum);
strcat(httpurl,"/");
}
else{
port=80;
strcat(httpurl,url);
strcat(httpurl,"/");
}
TRACE("gethttpurl:
%s\r\n",httpurl);
HttpString.Replace(httpurl,"/");
HttpString.Replace("Proxy-","");
HttpString.Replace("HTTP/1.0","HTTP/1.1");
}
elseif(HttpString.Find("CONNECT",0)==0){//判断connect命令并处理
index_start=HttpString.Find(temp,0);
if(index_start>0){
index_end=HttpString.Find("",index_start);
if(index_end<=0){
closesocket(clientsock);
return0;
}
PortString=HttpString.Mid(index_start+datalen,index_end-index_start-datalen);
port=atoi(PortString);
}
else{
closesocket(clientsock);
return0;
}
}
TRACE("getnewhttpstring:
\r\n");
TRACE(HttpString);
remotesock_addr.sin_family=AF_INET;
remotesock_addr.sin_port=htons(port);
remotesock_addr.sin_addr.S_un.S_addr=GetDomainIp(url);
connectsock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(connect(connectsock,(constsockaddr*)&remotesock_addr,sizeof(remotesock_addr))==INVALID_SOCKET){//连接远程主机
closesocket(clientsock);
return0;
}
TRACE("\r\nconnecttoremoteipok\r\n");
ZeroMemory((void*)data,sizeof(data));
wsprintf(data,"%s",HttpString);
datalen=strlen(data);
if(HttpString.Find("CONNECT",0)<0)while(!
send(connectsock,data,datalen,0));
else{
strcpy(data,"HTTP/1.0200Connectionestablished\r\nProxy-agent:
CHTTPPROXYV1.0poweredbyshadow\r\n\r\n");
datalen=strlen(data);
while(!
send(clientsock,data,datalen,0));
}
httpsockinfo.sourcesock=clientsock;
httpsockinfo.destsock=connectsock;
AfxBeginThread(HttpReciveThread,(LPVOID)&httpsockinfo);//抛出处理线程
AfxBeginThread(HttpSendThread,(LPVOID)&httpsockinfo);//
Sleep(100);
return1;
}
//
UINTStartHttpProxy(LPVOIDinfo){//端口监听线程
SOCKETNewSock;
intsocklen;
sockaddr_inserversock,remotesock_addr;
serversock.sin_family=AF_INET;
serversock.sin_addr.S_un.S_addr=INADDR_ANY;
serversock.sin_port=htons(HttpListenPort);
HttpListenSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(HttpListenSock==INVALID_SOCKET)return0;
if(bind(HttpListenSock,(constsockaddr*)&serversock,sizeof(serversock))==SOCKET_ERROR)return0;
listen(HttpListenSock,BACKUP);
socklen=sizeof(remotesock_addr);
TRACE("starthttpproxythreadwhile\r\n");
while(true){
NewSock=accept(HttpListenSock,(sockaddr*)&remotesock_addr,&socklen);
TRACE("waittingok...\r\n");
if(NewSock==INVALID_SOCKET){
Sleep
(1);
continue;
}
ZeroMemory((void*)&HttpClientInfo,sizeof(CLIENTINFO));
HttpClientInfo.clientsock=NewSock;
HttpClientInfo.clientsock_addr=remotesock_addr;
TRACE("startproxythread\r\n");
AfxBeginThread(HttpProxyServerThread,(LPVOID)&HttpClientInfo);
Sleep(100);
}
return1;
}
//
CHTTPPROXY:
:
CHTTPPROXY()
{
WSADATAWsaData;
WORDwsaVer;
wsaVer=MAKEWORD(2,0);
WsaStartupOk=false;
if(WSAStartup(wsaVer,&WsaData)!
=SOCKET_ERROR)WsaStartupOk=true;
}
CHTTPPROXY:
:
~CHTTPPROXY()
{
if(WsaStartupOk){
WSACleanup();
}
}
intCHTTPPROXY:
:
StartProxy(intlistenport)
{
HttpListenPort=listenport;
AfxBeginThread(StartHttpProxy,(LPVOID)NULL);
return1;
}
/*=========================================================================
file:
HTTPPROXY.h
==========================================================================*/
classCHTTPPROXY
{
public:
intStartProxy(intlistenport);
boolWsaStartupOk;
CHTTPPROXY();
virtual~CHTTPPROXY();
};
/*=========================================================================
file:
stdafx.h
==========================================================================*/
#include
#include
#include
#include
注:
不要忘了在link选项中添加wsock32.lib和ws2_32.lib,或在文件前部加上如下语句:
#paragmacomment(lib,"wsock32.lib")