Код:
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")
#define SLISTEN_PORT 8080 //ïîðò
#define MESSAGE_BYF 2048
#define LISTEN_BACKLOG 5
////////////////////////////////////////////////////////////////////////
int GetHeader(int socket, char *buf, int maxlen) // ÷èòàåì õåäåð áåç ïîñòà. (äî \n\n èëè \r\n\r\n )
{
int len, i=0, f=0;
char c;
while(f != 2 && i < maxlen)
{
len = recv(socket, &c, 1, 0);
if(len==0 || len==-1)
break;
if(c == '\n')
f++;
else if(c != '\r')
f=0;
buf[i] = c;
i++;
}
buf[i]='\0';
char *p = strstr(buf, "HTTP/1.0");
if(p != NULL)
*(p+7)='1';
return i;
}
////////////////////////////////////////////////////////////////////////
int GetHost(char *buf, char *host, int maxlen) /// ïàðñèì èìÿ õîñòà ñ õåäåðà
{
char *p = strstr(buf, "Host: ");
if( p == NULL )
return 0;
p+=6;
int i;
for(i=0; *(p+i)!='\0' && *(p+i)!='\n' && *(p+i)!='\r' && *(p+i)!=':' && *(p+i)!=' ' && i<maxlen; i++)
host[i] = *(p+i);
if( i == maxlen )
return 0;
host[i] = '\0';
return i;
}
////////////////////////////////////////////////////////////////////////
int GetContLeng(char *buf) /// ïàðñèì äëèííó POST äàííûõ
{
char *p = strstr(buf, "Content-Length: ");
if( p == NULL )
return 0;
p+=16;
char len[8];
int i;
for(i=0; *(p+i)!='\0' && *(p+i)!='\n' && *(p+i)!='\r' && *(p+i)!=' ' && i<8; i++)
len[i] = *(p+i);
if( i == 8 )
return 0;
len[i]='\0';
return atoi(len);
}
////////////////////////////////////////////////////////////////////////
SOCKET SocketConnect(char *host) /// ïîäñîåäåíÿåìñÿ ê ñåðâåðó
{
SOCKET ksocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct hostent *Ip;
Ip = gethostbyname(host);
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)Ip->h_addr)));
clientService.sin_port = htons(80);
if(connect( ksocket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
return SOCKET_ERROR;
return ksocket;
}
//////***************************************************************************************************/////
DWORD WINAPI SocketListen(LPVOID AcceptSocket)
{
int len;
char recvbuf[MESSAGE_BYF], host[256];
if( GetHeader((int)AcceptSocket, recvbuf, MESSAGE_BYF) == SOCKET_ERROR ) //ïîëó÷àåì õåäåð îò áðàóçåðà
return false;
//printf("%s", recvbuf);
if( !GetHost(recvbuf, host, 256) ) /// ïàðñèì õîñò èç õåäåðà
{
char message[]="Proxy error. Host not found in header.";
send((int)AcceptSocket, message, strlen(message), 0);
closesocket((int)AcceptSocket);
return false;
}
SOCKET ConnectSocket = SocketConnect(host); // ïäñîåäåíÿåìñÿ ê ñåðâåðó
if(ConnectSocket == SOCKET_ERROR)
{
char message[]="Proxy error.Cannot connect to host.";
send((int)AcceptSocket, message, strlen(message), 0);
closesocket((int)AcceptSocket);
return false;
}
if( send((int)ConnectSocket,recvbuf,strlen(recvbuf),0) == SOCKET_ERROR) // îòïðàâëÿåì äàííûé íà ñåðâåð
{
char message[]="Proxy error. Cannot send data to host.";
send((int)AcceptSocket, message, strlen(message), 0);
closesocket((int)AcceptSocket);
return false;
}
len = GetContLeng(recvbuf); // ïàðñèì ðàçìåð POST äàííûõ
char contbuf[128];
int recvlen;
while(len > 0) /// ïîëó÷àåì îò áðàóçåðà è îòïàâëÿåì POST äàííûå íà ñåðâåð
{
recvlen = recv((int)AcceptSocket, contbuf, 128, 0);
if(recvlen == SOCKET_ERROR)
break;
send((int)ConnectSocket,contbuf,recvlen,0);
len-=recvlen;
}
while(1) /// ïîëó÷àåì äàííûå îò ñåâåðà è îòïðàâëÿåì áðàóçåðó
{
len = recv((int)ConnectSocket, recvbuf, MESSAGE_BYF, 0);
if(len == 0 || len == SOCKET_ERROR)
break;
send((int)AcceptSocket,recvbuf,len,0);
}
closesocket((int)AcceptSocket);
return true;
}
//***************************************************************************************************************************//
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
{
printf("Error at WSAStartup()\n");
return 0;
}
SOCKET ListenSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (ListenSocket == INVALID_SOCKET)
{
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
SOCKADDR_IN sa = {0};
int len = sizeof(sa);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons( SLISTEN_PORT );
if( bind( ListenSocket, (sockaddr*)&sa, len ) == SOCKET_ERROR )
{
printf("bind() failed.\n");
closesocket(ListenSocket);
return 0;
}
if( listen( ListenSocket, LISTEN_BACKLOG ) == SOCKET_ERROR )
{
printf("Error listening on socket.\n");
closesocket(ListenSocket);
return 0;
}
printf("Server start at port: %d \nWaiting...\n",SLISTEN_PORT );
SOCKET AcceptSocket;
DWORD thID;
while( (AcceptSocket = accept( ListenSocket, (sockaddr*)&sa, &len )) != -1 )
{
printf("Connection from %s:%d AcceptID=%d\n", inet_ntoa(sa.sin_addr), htons(sa.sin_port), AcceptSocket );
CreateThread(0, 0, SocketListen, (LPVOID)AcceptSocket, 0, &thID);
}
return 1;
}