返回列表 发帖

打造自己的HTTP代理服务器

/*========================================================================= FILE:HTTPPROXY.cpp HTTP Proxy v1.0 powered by shadow 2004/11/14 my web:http://www.codehome.6600.org QQ:176017352 请先阅读有关http代理协议的相关资料,转载请著明出处 ==========================================================================*/ #include "stdafx.h" #include "HTTPPROXY.h" #define FD_NOEVENT 0 // #define BACKUP 100 #define MAXDATALEN 65535 int HttpListenPort; SOCKET HttpListenSock; // typedef struct _CLIENTINFO{ SOCKET clientsock; SOCKET udpsock; sockaddr_in clientsock_addr; }CLIENTINFO,*LPCLIENTINFO; CLIENTINFO HttpClientInfo; // typedef struct _SOCKINFO{ SOCKET sourcesock; SOCKET destsock; }SOCKINFO,*LPSOCKINFO; SOCKINFO httpsockinfo; // extern long GetSocketEventId(SOCKET remotesock); extern unsigned long GetLocalIp(); extern unsigned long GetDomainIp(char domainname[250]); /* long GetSocketEventId(SOCKET remotesock){ long EventId; HANDLE hevent; hevent=CreateEvent(NULL,0,0,0); WSANETWORKEVENTS socket_events; EventId=FD_NOEVENT; if(WSAEventSelect(remotesock,hevent,FD_ACCEPT|FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE)==SOCKET_ERROR) return EventId; WSAEnumNetworkEvents(remotesock,hevent,&socket_events); if(socket_events.lNetworkEvents!=0){ switch(socket_events.lNetworkEvents){ case FD_ACCEPT:EventId=FD_ACCEPT;break; case FD_CONNECT:EventId=FD_CONNECT;break; case FD_READ:EventId=FD_READ;break; case FD_WRITE:EventId=FD_WRITE;break; case FD_CLOSE:EventId=FD_CLOSE;break; case FD_OOB:EventId=FD_OOB;break; default:EventId=FD_NOEVENT;break; } } else EventId=FD_NOEVENT; return EventId; } // unsigned long GetLocalIp() { char IP[MAX_PATH],*ip; char pc_name[80]; struct in_addr in; struct hostent *host; WORD wVersionRequested; WSADATA wsaData; wVersionRequested=MAKEWORD(2,0); ip=IP; strcpy(ip,"Ip not get!"); if(WSAStartup(wVersionRequested,&wsaData)) return 0; if(gethostname(pc_name,80)==SOCKET_ERROR){ WSACleanup(); return 0; } if(!(host=gethostbyname(pc_name))){ WSACleanup(); return 0; } in.s_addr=*((unsigned long *)host->h_addr_list[0]); strcpy(ip,inet_ntoa(in)); WSACleanup(); return in.s_addr; } // unsigned long GetDomainIp(char domainname[250]) { char IP[MAX_PATH],*ip; struct in_addr in; struct hostent *host; WORD wVersionRequested; WSADATA wsaData; wVersionRequested=MAKEWORD(2,0); ip=IP; strcpy(ip,"Ip not get!"); if(WSAStartup(wVersionRequested,&wsaData)) return 0; if(!(host=gethostbyname(domainname))){ WSACleanup(); return 0; } in.s_addr=*((unsigned long *)host->h_addr_list[0]); strcpy(ip,inet_ntoa(in)); WSACleanup(); return in.s_addr; } */ // // UINT HttpReciveThread(LPVOID info){ //针对客户端的接收处理线程 LPSOCKINFO psockinfo; SOCKET sourcesock,destsock; char data[MAXDATALEN]; long eventid; int datalen; psockinfo=(LPSOCKINFO)info; sourcesock=psockinfo->sourcesock; destsock=psockinfo->destsock; TRACE("deail recive thread ok!\r\n"); while(true){ eventid=GetSocketEventId(sourcesock); switch(eventid){ case FD_CLOSE: TRACE("s fdclosed\r\n"); closesocket(destsock); return 1; break; default:break; } eventid=GetSocketEventId(destsock); switch(eventid){ case FD_CLOSE: closesocket(sourcesock); TRACE("d fdclosed\r\n"); return 1; break; default:break; } datalen=recv(sourcesock,data,sizeof(data),0); if(datalen==0){ closesocket(sourcesock); closesocket(destsock); TRACE("s fdclosed\r\n"); break; } if(datalen>0){ while(!send(destsock,data,datalen,0)); } Sleep(1); } return 1; } // UINT HttpSendThread(LPVOID info){ //针对远程端的接收处理线程 LPSOCKINFO psockinfo; SOCKET sourcesock,destsock; char data[MAXDATALEN]; long eventid; int datalen; psockinfo=(LPSOCKINFO)info; sourcesock=psockinfo->sourcesock; destsock=psockinfo->destsock; TRACE("deail send thread ok!\r\n"); while(true){ eventid=GetSocketEventId(sourcesock); switch(eventid){ case FD_CLOSE: TRACE("s fdclosed\r\n"); closesocket(destsock); return 1; break; default:break; } eventid=GetSocketEventId(destsock); switch(eventid){ case FD_CLOSE: closesocket(sourcesock); TRACE("d fdclosed\r\n"); return 1; break; default:break; } datalen=recv(destsock,data,sizeof(data),0); if(datalen==0){ closesocket(sourcesock); closesocket(destsock); TRACE("d fdclosed\r\n"); break; } if(datalen>0){ while(!send(sourcesock,data,datalen,0)); } Sleep(1); } return 1; } // // UINT HttpProxyServerThread(LPVOID info){ //针对一次服务的线程 LPCLIENTINFO pclientinfo; SOCKET connectsock,clientsock; sockaddr_in remotesock_addr; char data[MAXDATALEN],url[250],temp[250],httpurl[250],portnum[10]; int datalen,i,index_start,index_end,port; CString HttpString,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); return 0; } HttpString.Format("%s",data); UrlString=HttpString; TRACE("get http string:\r\n"); TRACE(HttpString); index_start=HttpString.Find("Host: ",0); //寻找url标记 if(index_start<=0){ closesocket(clientsock); return 0; } index_end=HttpString.Find("\r\n",index_start); if(index_end<=0){ closesocket(clientsock); return 0; } UrlString=HttpString.Mid(index_start+6,index_end-index_start-6); //读取 url字符串 TRACE("\r\n get url:"); 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); return 0; } 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("get http url:%s\r\n",httpurl); HttpString.Replace(httpurl,"/"); HttpString.Replace("Proxy-",""); HttpString.Replace("HTTP/1.0","HTTP/1.1"); } else if(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); return 0; } PortString=HttpString.Mid(index_start+datalen,index_end-index_start-datalen); port=atoi(PortString); } else{ closesocket(clientsock); return 0; } } TRACE("get new http string:\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,(const sockaddr *)&remotesock_addr,sizeof(remotesock_addr))==INVALID_SOCKET){ //连接远程主机 closesocket(clientsock); return 0; } TRACE("\r\nconnect to remote ip ok\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.0 200 Connection established\r\nProxy-agent: CHTTPPROXY V1.0 powered by shadow\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); return 1; } // UINT StartHttpProxy(LPVOID info){ //端口监听线程 SOCKET NewSock; int socklen; sockaddr_in serversock,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) return 0; if(bind(HttpListenSock,(const sockaddr *)&serversock,sizeof(serversock))==SOCKET_ERROR) return 0; listen(HttpListenSock,BACKUP); socklen=sizeof(remotesock_addr); TRACE("start http proxy thread while\r\n"); while(true){ NewSock=accept(HttpListenSock,(sockaddr *)&remotesock_addr,&socklen); TRACE("waitting ok...\r\n"); if(NewSock==INVALID_SOCKET){ Sleep(1); continue; } ZeroMemory((void *)&HttpClientInfo,sizeof(CLIENTINFO)); HttpClientInfo.clientsock=NewSock; HttpClientInfo.clientsock_addr=remotesock_addr; TRACE("start proxy thread\r\n"); AfxBeginThread(HttpProxyServerThread,(LPVOID)&HttpClientInfo); Sleep(100); } return 1; } // CHTTPPROXY::CHTTPPROXY() { WSADATA WsaData; WORD wsaVer; wsaVer=MAKEWORD(2,0); WsaStartupOk=false; if(WSAStartup(wsaVer,&WsaData)!=SOCKET_ERROR) WsaStartupOk=true; } CHTTPPROXY::~CHTTPPROXY() { if(WsaStartupOk){ WSACleanup(); } } int CHTTPPROXY::StartProxy(int listenport) { HttpListenPort=listenport; AfxBeginThread(StartHttpProxy,(LPVOID)NULL); return 1; } /*========================================================================= FILE:HTTPPROXY.h ==========================================================================*/ class CHTTPPROXY { public: int StartProxy(int listenport); bool WsaStartupOk; CHTTPPROXY(); virtual ~CHTTPPROXY(); }; /*========================================================================= FILE:stdafx.h ==========================================================================*/ #include #include #include #include 注:不要忘了在link选项中添加wsock32.lib和ws2_32.lib,或在文件前部加上如下语句: #paragma comment(lib,"wsock32.lib") #paragma comment(lib,"ws2_32.lib") 本代码在win2k和vc6.0下编译成功~~ 用法,把这几个文件添加到你的项目中,在WinMain()中添加如下代码: CHTTPPROXY httpproxy; httpproxy.StartProxy(7890); 有问题mailto me!

返回列表 回复 发帖