HTTPProxy服务器

Posted 125096

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTTPProxy服务器相关的知识,希望对你有一定的参考价值。

HttpProxyServer.h

#ifndef  HTTPPROXYSERVER
#define HTTPPROXYSERVER
#pragma once
#include <windows.h>
#include <stdio.h>
#include <wininet.h>
#include <errno.h>
#include <tchar.h>
#include <assert.h>
#pragma comment(lib,"Ws2_32.lib")


#define defineServiceName							TEXT("HTTPProxyService 0.0.1")														//服务名
#define defineServiceDisplayName				TEXT("HTTP Proxy Service")																//服务显示名
#define defineServicePath								TEXT("\\HTTPProxyService.exe")														//当前文件名称
#define defineServiceDescription				TEXT("HTTP Proxy Service 0.0.1(HTTP Proxy V1.0 By FX)")			//服务描述

#define MAX_HOSTNAME								1024			//最大主机名称
#define DEFAULTPORT										80			//默认主机端口
#define LISTENPORT										8000			//代理服务器监听端口
#define DEFLISNUM											500			//linsten最大队列
#define HEADLEN													7			//http://头长度
#define TIMEOUT											10000			//recv延时时间	
#define MAXSIZE												20480			//缓冲大小
#define GET_STYLE													1			//get请求类型
#define HEAD_STYLE												2			//head请求类型
#define POST_STYLE												3			//post请求类型
#define CONNECT_STYLE										4			//connect请求类型

char ErrorMsg[]="HTTP/1.1 403 Forbidden\r\n\r\n<body><h1>403 Forbidden</h1></body>";			//SOCK错误消息
char ConnectionEstablished[]="HTTP/1.0 200 OK\r\n\r\n";																				//HTTP成功


HANDLE							g_hSerHandMutex;					//服务分发起等待句柄
SERVICE_STATUS			ServiceStatus;							//服务的状态。注意 ServiceStatus 一个全局变量,所以你可以跨多个函数使用它。
SERVICE_STATUS_HANDLE hStatus;								//服务状态

//服务函数
void WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );

//处理 SCM 控制请求。服务控制
VOID WINAPI ServiceHandler(DWORD fdwControl);

//启动自己的工作线程 HTTPProxyFun 0.0.1
DWORD WINAPI HTTPProxyFun(LPVOID lpParam);

//现在,准备工作已经就绪,你可以开始编码了。服务程序控制台程序的一个子集。因此,开始你可以定义一个 main 函数,它是程序的入口点。对于服务程序来说,main 的代码令人惊讶地简短,因为它只创建分派表并启动控制分派机。
int   ModifyRequest(char *SenderBuf,char *ReceiveBuf,int DataLen,int MethodLength);

//检测查询请求类型长度
int   CheckRequest(char *ReceiveBuf,int *MethodLength);

//获取主机名和端口
void  GetHostNameAndPort(char *ReceiveBuf,int datalen,char *HostName,UINT *RemotePort);

//获取域名后面的部分
char  *GetURLRootPoint(char * ReceiveBuf,int DataLen,int *HostNaneLen);

//主机名解析IP地址
char  *DNS(char *HostName);

//连接远程主机
BOOL  ConnectToRemoteHost(SOCKET *ServerSocket,char *HostName,const UINT RemotePort);

//发送请求
BOOL  SendRequest(SOCKET* CSsocket, char *SenderBuf, char *ReceiveBuf, int DataLen);

//HTTP代理线程
DWORD WINAPI ZXHTTPProxyThread(SOCKET* CSsocket);

//信息传递线程 
void  TransferData(SOCKET* CSsocket);

//安装服务
void  InstallCmdService(void);

//移除服务
void  RemoveCmdService(void);

//使用信息
void  usage(char *par);






#endif


httpProxyService.cpp

#include "HttpProxyServer.h"

int main(int argc,char *argv[])
{
	HANDLE hThread=CreateThread(NULL,0,HTTPProxyFun,NULL,0,NULL);
	assert(hThread);
	WaitForSingleObject(hThread,INFINITE);
	CloseHandle(hThread);

	return 0;


    SERVICE_TABLE_ENTRY ServiceTable[2];								 //分派表
    ServiceTable[0].lpServiceName = defineServiceName;					 //线程名字 lpServiceName: 指向表示服务名称字符串的指针;当定义了多个服务时,那么这个域必须指定
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;//线程入口地址lpServiceProc: 指向服务主函数的指针(服务入口点);
    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;								 //最后一个必须为NULL分派表的最后一项必须是服务名和服务主函数域的 NULL 指针,
																		 //文本例子程序中只宿主一个服务,所以服务名的定义是可选的。
   //printf("HTTP Proxy V1.0 By LZX.\r\nUsage: %s ProxyPort\r\n",argv[0]);
	if(argc==2)
	{
		if(!_stricmp(argv[1],"-i"))
		{
			usage(argv[0]);
			InstallCmdService();
		}
		else if(!stricmp(argv[1],"-u"))
		{
			usage(argv[0]);
			RemoveCmdService();
		}
		else usage(argv[0]);
		return 0;
	}
	else usage(argv[0]);

	StartServiceCtrlDispatcher(ServiceTable);// 启动服务的控制分派机线程
	/****************************************************************************
		服务控制管理器(SCM:Services Control Manager)是一个管理系统所有服
		务的进程。当 SCM 启动某个服务时,它等待某个进程的主线程来调用
		StartServiceCtrlDispatcher 函数。将分派表传递给StartServiceCtrlDispatcher。
		这将把调用进程的主线程转换为控制分派器。该分派器启动一个新线程,该线
		程运行分派表中每个服务的 ServiceMain 函数(本文例子中只有一个服务)分
		派器还监视程序中所有服务的执行情况。然后分派器将控制请求从 SCM 传给服
		务。
			注意:如果 StartServiceCtrlDispatcher 函数30秒没有被调用,便会报错,
		为了避免这种情况,我们必须在 ServiceMain 函数中(参见本文例子)或在非
		主函数的单独线程中初始化服务分派表。分派表中所有的服务执行完之后(例如,
		用户通过“服务”控制面板程序停止它们),或者发生错误时。
		StartServiceCtrlDispatcher 调用返回。然后主进程终止。
	****************************************************************************/
	return 0;
}


/*******************************************************************************
该函数是服务的入口点。它运行在一个单独的线程当中,这个线程是由控制分派器创建的。
ServiceMain 应该尽可能早早为服务注册控制处理器。这要通过调用 RegisterServiceCtrlHadler 
函数来实现。你要将两个参数传递给此函数:服务名和指向 ControlHandlerfunction 的指针。
它指示控制分派器调用 ControlHandler 函数处理 SCM 控制请求。注册完控制处理器之后,
获得状态句柄(hStatus)。通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务
的状态。
ServiceMain 函数中,你给结构的几个域赋值,它们在服务运行的整个过程中都保持不变,比如:
dwServiceType。
*******************************************************************************/
//服务函数
void WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv )
{

	//定义变量
    DWORD   status = 0; 
    DWORD   specificError = 0xfffffff;
	HANDLE hThread;
    ServiceStatus.dwServiceType        = SERVICE_WIN32; //dwServiceType:指示服务类型,创建 Win32 服务。赋值 SERVICE_WIN32;
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING; //dwCurrentState:指定服务的当前状态。因为服务的初始化在这里没有完成,所以这里的状态为 SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE; //这个域通知 SCM 服务接受哪个域。本文例子是允许 STOP 和 SHUTDOWN 请求。SCM 控制请求。
    ServiceStatus.dwWin32ExitCode      = 0; 
    ServiceStatus.dwServiceSpecificExitCode = 0; 
    ServiceStatus.dwCheckPoint         = 0; 
    ServiceStatus.dwWaitHint           = 0; 
	//dwWin32ExitCode 和 dwServiceSpecificExitCode:这两个域在你终止服务并报告退出细节时很有用。初始化服务时并不退出,因此,它们的值为 0;
	//dwCheckPoint 和 dwWaitHint:这两个域表示初始化某个服务进程时要30秒以上。本文例子服务的初始化过程很短,所以这两个域的值都为 0。
    
	//调用RegisterServiceCtrlHandler()注册一个ServiceHandler函数用来处理程序对Service的控制要求
    hStatus = RegisterServiceCtrlHandler(TEXT("ServiceName"),(LPHANDLER_FUNCTION)ServiceHandler); 
    if (hStatus==0) return; 

	

    // Handle error condition 
    status = GetLastError(); 
    if (status!=NO_ERROR) 
    { 
        ServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
        ServiceStatus.dwCheckPoint         = 0; 
        ServiceStatus.dwWaitHint           = 0; 
        ServiceStatus.dwWin32ExitCode      = status; 
        ServiceStatus.dwServiceSpecificExitCode = specificError; 
        SetServiceStatus(hStatus, &ServiceStatus); 
        return; 
    } 
    // Initialization complete - report running status 
    ServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
    ServiceStatus.dwCheckPoint         = 0; 
    ServiceStatus.dwWaitHint           = 0;  
    SetServiceStatus(hStatus, &ServiceStatus);//通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的状态。
	
	//启动自己的工作线程
	WaitForSingleObject(g_hSerHandMutex,INFINITE);


	//设置服务状态
	ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
	ServiceStatus.dwWin32ExitCode = 0;
	ServiceStatus.dwCheckPoint    = 0;
	ServiceStatus.dwWaitHint      = 0;
	if(SetServiceStatus(hStatus,&ServiceStatus)==0)
	{
		OutputDebugString(TEXT("SetServiceStatus in CmdControl in Switch Error !\n"));
	}

	ReleaseMutex(g_hSerHandMutex);
	CloseHandle(g_hSerHandMutex);
	hThread=CreateThread(NULL,0,HTTPProxyFun,NULL,0,NULL);
	assert(hThread);
	WaitForSingleObject(hThread,INFINITE);
	CloseHandle(hThread);
	return;
}

//它指示控制分派器调用 ControlHandler 函数处理 SCM 控制请求。服务控制
void WINAPI ServiceHandler(DWORD fdwControl) 
{ 

    switch(fdwControl)
    {
    case SERVICE_CONTROL_PAUSE:			//控制暂停
		{
				ServiceStatus.dwCurrentState = SERVICE_PAUSED;
		}
        break;
    case SERVICE_CONTROL_CONTINUE://控制继续
		{
				ServiceStatus.dwCurrentState = SERVICE_RUNNING;
		}
        break;
    case SERVICE_CONTROL_STOP:			//控制停止
		{
			WaitForSingleObject(g_hSerHandMutex,INFINITE);

			//设置服务状态
			ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
			ServiceStatus.dwWin32ExitCode = 0;
			ServiceStatus.dwCheckPoint    = 0;
			ServiceStatus.dwWaitHint      = 0;
			if(SetServiceStatus(hStatus,&ServiceStatus)==0)
			{
				OutputDebugString(TEXT("SetServiceStatus in CmdControl in Switch Error !\n"));
			}

			ReleaseMutex(g_hSerHandMutex);
			CloseHandle(g_hSerHandMutex);
		}
		//break;  此处没有break是否是作者故意为之?fx 2016年5月17日11:18:45
    case SERVICE_CONTROL_SHUTDOWN:		//控制关闭
		{
			ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
			ServiceStatus.dwWin32ExitCode = 0;
			ServiceStatus.dwCheckPoint    = 0;
			ServiceStatus.dwWaitHint      = 0;
			SetServiceStatus(hStatus,&ServiceStatus);
		}
        return ;
    default:
        break;
    }

	//设置状态
    SetServiceStatus(hStatus,&ServiceStatus);
    return ;
}

//启动自己的工作线程(HTTP Proxy V1.0 By LZX)
DWORD WINAPI HTTPProxyFun(LPVOID lpParam)
{

	//设置变量
	int LisPort=LISTENPORT;
	
	//初始化网络库
    WSADATA WSAData;
    if(WSAStartup(MAKEWORD(2,2), &WSAData)) return 1;

	
	//创建socket
    SOCKET ProxyServer= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(ProxyServer == SOCKET_ERROR)return 1;

	//绑定端口
    struct sockaddr_in Server={0};
    Server.sin_family = AF_INET;
    Server.sin_port = htons(LisPort);
    Server.sin_addr.S_un.S_addr = INADDR_ANY;
    if(bind(ProxyServer, (LPSOCKADDR)&Server, sizeof(Server)) == SOCKET_ERROR) return 1;


	//监听连接
    if(listen(ProxyServer, DEFLISNUM) == SOCKET_ERROR)return 1;


	//定义变量
    SOCKET AcceptSocket = INVALID_SOCKET;
    SOCKET *CSsocket;
    while(true)
    {
		//接受客户端连接
        AcceptSocket = accept(ProxyServer, NULL, NULL);
        CSsocket = (SOCKET*)malloc(sizeof(SOCKET)*2);
        if (CSsocket == NULL)continue;

		//创建线程处理客户端连接请求
        CSsocket[0] = AcceptSocket;
        HANDLE hThread = CreateThread (NULL,0, (LPTHREAD_START_ROUTINE)ZXHTTPProxyThread,CSsocket,0,NULL); 
        if (hThread == NULL) Sleep(1000);
        else CloseHandle(hThread);
	}

	return true;
}


//主机名解析IP地址
char *DNS(char *HostName)
{
	//参数效验
	assert(HostName);
	if (HostName==NULL)return NULL;

	//获取主机地址
    HOSTENT *hostent = NULL;
    IN_ADDR iaddr;
    hostent = gethostbyname(HostName);
    if (hostent == NULL)
    {
        return NULL;
    }
    iaddr = *((LPIN_ADDR)*hostent->h_addr_list);
    return inet_ntoa(iaddr);
}

//连接远程主机
BOOL ConnectToRemoteHost(SOCKET *ServerSocket,char *HostName,const UINT RemotePort)
{
	//参数效验
	assert(*ServerSocket!=SOCKET_ERROR);
	assert(HostName!=NULL);
	assert(RemotePort>0);
	if (*ServerSocket==SOCKET_ERROR)return false;
	if (*HostName==NULL)return false;
	if (RemotePort<0)return false;

	//地址信息
	sockaddr_in Server={0};
    Server.sin_family = AF_INET;
    Server.sin_port = htons(RemotePort);
    if (inet_addr(HostName) != INADDR_NONE)
    {
        Server.sin_addr.s_addr = inet_addr(HostName);
    }
    else
    {
		//解析主机地址
        if (DNS(HostName) != NULL)
        {
            Server.sin_addr.s_addr = inet_addr(DNS(HostName));
        }
        else
        {
            assert(FALSE);
            return FALSE;
        }
    }

	//创建socket
    *ServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (*ServerSocket == INVALID_SOCKET) return FALSE;

    //设置socket接收的超时时间为10秒 
    UINT TimeOut = TIMEOUT;
    setsockopt(*ServerSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut));

    // 连接远程主机
    if (connect(*ServerSocket, (const SOCKADDR *)&Server,sizeof(Server)) == SOCKET_ERROR)
    {
        closesocket(*ServerSocket);
        return FALSE;
    }

    return TRUE;
}


//获取主机名和端口
void GetHostNameAndPort(char *ReceiveBuf,int datalen,char *HostName,UINT *RemotePort)
{
	//参数效验
	assert(datalen>0);
	assert(RemotePort!=NULL);
	assert(HostName!=NULL);
	if (datalen<0)return;
	if (RemotePort==NULL)return;
	if (HostName==NULL)return;


	//解析主机端口
    char *fp = ReceiveBuf;
    for(int i = 0;i < datalen && *fp != ':' && *fp != '\0' && *fp != '\r' && *fp != '/';i++)
    {    
		//解析主机
        HostName[i]=*fp++;

		//解析端口
        if(*fp == ':') *RemotePort=atoi(fp+1);
        else *RemotePort=DEFAULTPORT;
    }
}

//获取域名后面的部分
char * GetURLRootPoint(char * ReceiveBuf,int DataLen,int *HostNaneLen)
{
	//参数效验
	assert(DataLen>0);
	assert(ReceiveBuf!=NULL);
	assert(HostNaneLen!=NULL);
	if (DataLen<0)return NULL;
	if (ReceiveBuf==NULL)return NULL;
	if (HostNaneLen==NULL)return NULL;
	

	//解析操作
    for(int i = 0;i < DataLen; i++)
    {
        if(ReceiveBuf[i] == '/')
        {
            *HostNaneLen = i;
            return &ReceiveBuf[i];
        }
    }
    return NULL;
}


//检测查询请求类型长度
int CheckRequest(char *ReceiveBuf,int *MethodLength)
{
	//参数效验
	assert(ReceiveBuf!=NULL);
	assert(MethodLength!=NULL);
	if (ReceiveBuf==NULL)return NULL;
	if (MethodLength==NULL)return NULL;

    if(!strnicmp(ReceiveBuf,"GET ",4))
    {
        *MethodLength = 4;
        return GET_STYLE;
    }
    else if(!strnicmp(ReceiveBuf,"HEAD ",5)) //Looks like the same with GET
    {
        *MethodLength = 5;
        return HEAD_STYLE;
    }
    else if(!strnicmp(ReceiveBuf,"POST ",5))
    {
        *MethodLength = 5;
        return POST_STYLE;
    }
    else if(!strnicmp(ReceiveBuf,"CONNECT ",8))
    {
        *MethodLength = 8;
        return CONNECT_STYLE;
    }
    else
    {
        return 0;
    }
}
//修改请求信息
int ModifyRequest(char *SenderBuf,char *ReceiveBuf,int DataLen,int MethodLength)
{

	//参数效验
	assert(SenderBuf!=NULL);
	assert(ReceiveBuf!=NULL);
	assert(DataLen>0);
	assert(MethodLength>0);
	if (SenderBuf==NULL)return NULL;
	if (ReceiveBuf==NULL)return NULL;
	if (DataLen<0)return NULL;
	if (MethodLength<0)return NULL;

	//设置变量
    strncpy(SenderBuf,ReceiveBuf,MethodLength);
    int HedLen = 0;

	//http头判断
    if(strncmp(ReceiveBuf+MethodLength,"http://",HEADLEN)) return 0;

	//获取域名后面的部分
    char * Getrootfp = GetURLRootPoint(ReceiveBuf+MethodLength+HEADLEN,DataLen
		-MethodLength-HEADLEN,&HedLen);
    if(Getrootfp == NULL)
        return 0;

    memcpy(SenderBuf+MethodLength,Getrootfp,DataLen-MethodLength-HEADLEN-HedLen);

	//返回长度
    return DataLen-HEADLEN-HedLen;
}

//信息传递线程 
void TransferData(SOCKET* CSsocket)
{
	//参数效验
	assert(CSsocket!=NULL);
	if (CSsocket==NULL)return;


	//定义变量
    SOCKET ClientSocket = CSsocket[0];
    SOCKET ServerSocket = CSsocket[1];
	timeval timeset={0};			//超时时间
    fd_set readfd,writefd;
    int result,i=0;
	char read_in1[MAXSIZE]={0};
	char send_out1[MAXSIZE]={0};
	char read_in2[MAXSIZE]={0};
	char send_out2[MAXSIZE]={0};		//ServerSocket套接字接受数据
	char SenderBuf[MAXSIZE]={0};
    int read1=0;
	int totalread1=0;				//ClientSocket套接字接受长度
	int send1=0;
    int read2=0;
	int totalread2=0;				//ServerSocket套接字接受长度
	int send2=0;
    int sendcount1=0;
	int sendcount2=0;
    int maxfd=0;						//最大套接字范围

    maxfd=max(ClientSocket,ServerSocket)+1;
    memset(read_in1,0,MAXSIZE);
    memset(read_in2,0,MAXSIZE);
    memset(send_out1,0,MAXSIZE);
    memset(send_out2,0,MAXSIZE);

    timeset.tv_sec=TIMEOUT;
    timeset.tv_usec=0;
    while(true)
    {
		//初始化为空集合
        FD_ZERO(&readfd);
        FD_ZERO(&writefd);

		//添加套接字到集合
        FD_SET((UINT)ClientSocket, &readfd);
        FD_SET((UINT)ClientSocket, &writefd);
        FD_SET((UINT)ServerSocket, &writefd);
        FD_SET((UINT)ServerSocket, &readfd);

		//查询事件
        result=select(maxfd,&readfd,&writefd,NULL,×et);
        if((result<0) && (errno!=EINTR)) break;
        else if(result==0) break;

		//3.接受远程服务端数据
        if(FD_ISSET(ServerSocket, &readfd))		//检查s是不是set的成员,如果是返回TRTUE  
        {
			//fx 2016年5月17日16:18:03
			//由于已近连接了远程服务器,所有会先收到服务器的数据
			//最大长度判断
            if(totalread2<MAXSIZE)
            {
                read2=recv(ServerSocket,read_in2,MAXSIZE-totalread2, 0);
                if(read2==0)break;
                if((read2<0) && (errno!=EINTR)) break;

                memcpy(send_out2+totalread2,read_in2,read2);
                  totalread2+=read2;
                  memset(read_in2,0,MAXSIZE);
            }

        }

		//4.转发数据到客户端
        if(FD_ISSET(ClientSocket, &writefd))		//检查s是不是set的成员,如果是返回TRTUE  
         {
				int err2=0;
                sendcount2=0;
                while(totalread2>0)		//接受长度
                {
                     send2=send(ClientSocket, send_out2+sendcount2, totalread2, 0);
                    if(send2==0)break;
                    if((send2<0) && (errno!=EINTR))
                    {
						err2=1;
                        break;
                    }
                    if((send2<0) && (errno==ENOSPC)) break;
                    sendcount2+=send2;
                    totalread2-=send2;

                }
				if(err2==1) break;
               if((totalread2>0) && (sendcount2 > 0))
			  {
                /* move not sended data to start addr */
                memcpy(send_out2, send_out2+sendcount2, totalread2);
                memset(send_out2+totalread2, 0, MAXSIZE-totalread2);
			 }
            else	memset(send_out2,0,MAXSIZE);
        }

		//1.接受客户端请求
        if(FD_ISSET(ClientSocket, &readfd))			//检查s是不是set的成员,如果是返回TRTUE  
        {
            if(totalread1<MAXSIZE)
             {
                read1=recv(ClientSocket, read_in1, MAXSIZE-totalread1, 0);
                if((read1==SOCKET_ERROR) || (read1==0)) break;
  
                memcpy(send_out1+totalread1,read_in1,read1);
                totalread1+=read1;
                memset(read_in1,0,MAXSIZE);
            }

			//发送请求
            if(SendRequest(CSsocket,SenderBuf,send_out1,totalread1))
                totalread1=0;
        }

		//2.收到客户端请求转发到服务器
        if(FD_ISSET(ServerSocket, &writefd))
        {
            int err=0;
            sendcount1=0;
            while(totalread1>0)
            {
                send1=send(ServerSocket, send_out1+sendcount1, totalread1, 0);
                if(send1==0)break;
                if((send1<0) && (errno!=EINTR))
                {
                    err=1;
                    break;
                }

                if((send1<0) && (errno==ENOSPC)) break;
                sendcount1+=send1;
                totalread1-=send1;
            }

            if(err==1) break;
            if((totalread1>0) && (sendcount1>0))
            {
                memcpy(send_out1,send_out1+sendcount1,totalread1);
                memset(send_out1+totalread1,0,MAXSIZE-totalread1);
            }
            else
            memset(send_out1,0,MAXSIZE);
        }
        Sleep(5);
    }

    closesocket(ClientSocket);
    closesocket(ServerSocket);

	return;
}

//发送请求
BOOL SendRequest(SOCKET* CSsocket, char *SenderBuf, char *ReceiveBuf, int DataLen)
{
	//参数效验
	assert(CSsocket!=NULL);
	assert(SenderBuf!=NULL);
	assert(ReceiveBuf!=NULL);
	assert(DataLen>0);
	if (CSsocket==NULL)return false;
	if (SenderBuf==NULL)return false;
	if (ReceiveBuf==NULL)return false;
	if (DataLen<0)return false;

    //CSsocket[0] ClientSocket
    //CSsocket[1] ServerSocket
    DWORD  dwThreadID;
    char   HostName[MAX_HOSTNAME] = {0};
    UINT   RemotePort = 0;

    int Flag=0, MethodLength=0, SendLength=0;

	//检测查询请求类型是否合法
    Flag = CheckRequest(ReceiveBuf,&MethodLength);
    if(Flag==0) return 0;

    if(Flag==GET_STYLE || Flag==HEAD_STYLE || Flag==POST_STYLE)
    {
        SendLength=ModifyRequest(SenderBuf,ReceiveBuf,DataLen,MethodLength);
        if(SendLength==NULL)return 0;

		//获取主机名和端口
        GetHostNameAndPort(ReceiveBuf+MethodLength+HEADLEN,DataLen-MethodLength-HEADLEN,HostName,&RemotePort);

		//连接远程主机
        if(ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort)==FALSE)return 0;

		//发送数据
        if(send(CSsocket[1],SenderBuf,SendLength,0) == SOCKET_ERROR) return 0;
    }
	else if(Flag==CONNECT_STYLE)
    {
		//获取主机名和端口
        GetHostNameAndPort(ReceiveBuf+MethodLength,DataLen-MethodLength,HostName,&RemotePort);

		//连接远程主机
        if(ConnectToRemoteHost(&CSsocket[1],HostName,RemotePort)==FALSE) return 0;
		
		//发送数据
        send(CSsocket[0], ConnectionEstablished, strlen(ConnectionEstablished),0);
    }
    if(CSsocket[0] && CSsocket[1])
    {
		//开启线程
        HANDLE ThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TransferData,(LPVOID)CSsocket,0,&dwThreadID);
        if (ThreadHandle != NULL)WaitForSingleObject(ThreadHandle, INFINITE);
	    CloseHandle(ThreadHandle); 	
    }
	else	return FALSE;


    return TRUE;
}

//HTTP代理线程
DWORD WINAPI ZXHTTPProxyThread(SOCKET* CSsocket)
{
	//参数效验
	assert(CSsocket!=NULL);
	if(CSsocket==NULL) return NULL;

	//分配内存
    char *ReceiveBuf = (char*)malloc(sizeof(char)*MAXSIZE);
    char *SenderBuf  = (char*)malloc(sizeof(char)*MAXSIZE);
    memset(ReceiveBuf,0,MAXSIZE);
    memset( SenderBuf,0,MAXSIZE);

	//接受数据
    int DataLen = 0;
    DataLen = recv(CSsocket[0],ReceiveBuf,MAXSIZE,0);
    if(DataLen == SOCKET_ERROR || DataLen == 0)
    {
		closesocket(CSsocket[0]);
		closesocket(CSsocket[1]);
		free(CSsocket);
		free(ReceiveBuf);
		free(SenderBuf);
		return 0;
    }

	//发送请求
    if(SendRequest(CSsocket, SenderBuf, ReceiveBuf, DataLen)==FALSE)
         send(CSsocket[0],ErrorMsg,strlen(ErrorMsg),0);


    closesocket(CSsocket[0]);
    closesocket(CSsocket[1]);
    free(CSsocket);
    free(ReceiveBuf);
    free(SenderBuf);
    return 0;
}

//安装服务
void InstallCmdService(void)
{
	//变量定义
	SC_HANDLE        schSCManager;
	SC_HANDLE        schService;
	TCHAR             lpCurrentPath[MAX_PATH];
	TCHAR             lpImagePath[MAX_PATH];
	TCHAR             *lpHostName;
    WIN32_FIND_DATA  FileData;
	HANDLE           hSearch;
	DWORD            dwErrorCode;
	SERVICE_STATUS   InstallServiceStatus;

	//构造文件路径
	GetSystemDirectory(lpImagePath,MAX_PATH);
	_tcscat(lpImagePath,defineServicePath);
    lpHostName=NULL;
	
	//拷贝文件
	hSearch=FindFirstFile(lpImagePath,&FileData);
	if(hSearch==INVALID_HANDLE_VALUE)
	{
		//文件不存在就复制到系统目录
		GetModuleFileName(NULL,lpCurrentPath,MAX_PATH);
		if(CopyFile(lpCurrentPath,lpImagePath,FALSE)==0) 
		{
			dwErrorCode=GetLastError();
			if(dwErrorCode==5)
			{
				printf("Failure ... Access is Denied !\n");         
			}
			else
			{
				printf("Failure !\n");
			}
	     	return ;
		}
   		else
		{
   			printf("复制文件到系统目录成功\n");
		}
	}
	else
	{
		printf("系统目录文件以及存在!\n");
		FindClose(hSearch);
	}


	//打开服务器管理器
	schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS);
    if(schSCManager==NULL)
	{
		printf("Open Service Control Manager Database Failure !\n");
		return ;
	}

	//创建服务
	schService=CreateService(schSCManager,defineServiceName,defineServiceDisplayName,SERVICE_ALL_ACCESS,
		                     SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
							 SERVICE_ERROR_IGNORE,lpImagePath,NULL,NULL,NULL,NULL,NULL); 
	if(schService==NULL)
	{
		dwErrorCode=GetLastError();
		if(dwErrorCode!=ERROR_SERVICE_EXISTS)
		{
			//创建服务失败
      		printf("创建服务失败\n");
			CloseServiceHandle(schSCManager);
       		return ;
		}
		else
		{
			//服务已近存在,直接打开
			printf("already Exists !\n");
			schService=OpenService(schSCManager,defineServiceDisplayName,SERVICE_START);
			if(schService==NULL)
			{
				printf("服务打开失败\n");
				CloseServiceHandle(schSCManager);
				return ;
			}
		}
	}
	else
	{
		printf("创建服务成功\n");
	}

	//更改服务配置参数
	BOOL bSuccess;
	SERVICE_DESCRIPTION ServiceDescription;
	ServiceDescription.lpDescription=defineServiceDescription;
	bSuccess=ChangeServiceConfig2(schService,SERVICE_CONFIG_DESCRIPTION,&ServiceDescription);
	
	//启动服务
	if(StartService(schService,0,NULL)==0)                         
	{
		dwErrorCode=GetLastError();
		if(dwErrorCode==ERROR_SERVICE_ALREADY_RUNNING)
		{
			printf("already Running !\n");
        	CloseServiceHandle(schSCManager);  
         	CloseServiceHandle(schService);
         	return ;
		}
	}
	else
	{
		//服务运行中
		printf("服务运行中1\n");
	}

	//查询服务状态
	while(QueryServiceStatus(schService,&InstallServiceStatus)!=0)           
	{
		if(InstallServiceStatus.dwCurrentState==SERVICE_START_PENDING)
			Sleep(100);
		else
			break;
	}

	if(InstallServiceStatus.dwCurrentState!=SERVICE_RUNNING)
	{
		printf("服务运行失败 !\n");        //服务失败               
	}
	else
	{
		printf("服务运行中 2!\n");	//服务运行中
	}

	CloseServiceHandle(schSCManager);
	CloseServiceHandle(schService);
	return ;
}

//移除服务
void RemoveCmdService(void) 
{
	//变量定义
	SC_HANDLE        schSCManager;
	SC_HANDLE        schService;
	TCHAR             lpImagePath[MAX_PATH];
	TCHAR             *lpHostName;
    WIN32_FIND_DATA  FileData;
	SERVICE_STATUS   RemoveServiceStatus;
	HANDLE           hSearch;
	DWORD            dwErrorCode;

	//打开服务器管理器
	GetSystemDirectory(lpImagePath,MAX_PATH);
	_tcscat(lpImagePath,defineServicePath);
	lpHostName=NULL;
	schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS);
    if(schSCManager==NULL)
	{
		printf("Opening SCM ......... ");
		dwErrorCode=GetLastError();
		if(dwErrorCode!=5)
		{
			printf("Failure !\n"); 
		}
		else
		{
			printf("Failure ... Access is Denied !\n");
		}
		return ;
	}

	//打开服务
	schService=OpenService(schSCManager,defineServiceName,SERVICE_ALL_ACCESS);
	if(schService==NULL) 
	{
    	printf("Opening Service ..... ");
		dwErrorCode=GetLastError();
		if(dwErrorCode==1060)
		{
			printf("no Exists !\n");
		}
		else
		{
			printf("Failure !\n");
		}
		CloseServiceHandle(schSCManager);
	}
	else
	{
		//查询服务状态
     	if(QueryServiceStatus(schService,&RemoveServiceStatus)!=0)
		{
       		if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED)
			{
         		printf("already Stopped !\n"); //服务以及停止
			}
     		else
			{

				//停止服务
     			if(ControlService(schService,SERVICE_CONTROL_STOP,&RemoveServiceStatus)!=0)
				{
      				while(RemoveServiceStatus.dwCurrentState==SERVICE_STOP_PENDING)         
					{
    					Sleep(10);
	    				QueryServiceStatus(schService,&RemoveServiceStatus);
					}
      				if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED)
					{
      					printf("Success !\n");	//服务停止成功
					}
      				else
					{
					    printf("Failure !\n");	//服务停止失败
					}
				}
				else
				{
					printf("Failure !\n");          
				}
			}
		}
    	else
		{
    		printf("Query Failure !\n");
		}

     	printf("Removing Service .... "); 
		//删除服务
      	if(DeleteService(schService)==0)
		{
      		printf("Failure !\n");   
		}
     	else
		{
      		printf("Success !\n");
		}
	}

	CloseServiceHandle(schSCManager);        
	CloseServiceHandle(schService);


	//删除文件
	printf("Removing File ....... ");
	Sleep(1500);
	hSearch=FindFirstFile(lpImagePath,&FileData);
	if(hSearch==INVALID_HANDLE_VALUE)
	{
		printf("no Exists !\n");
	}
	else
	{
		if(DeleteFile(lpImagePath)==0)
		{
			printf("Failure !\n");               
		}
		else
		{
			printf("Success !\n");
		}
		FindClose(hSearch);
	}

	return ;
}

void  usage(char *par)
{
	printf("\t\tHTTP Proxy Service 0.0.1\n");
	printf("\t\tUsage: %s -i (to install service)\n",par);
	printf("\t\t       %s -u (to  remove service)\n",par);
	printf("\n");
	return ;
}


以上是关于HTTPProxy服务器的主要内容,如果未能解决你的问题,请参考以下文章

HTTPProxy服务器

我们如何在 services.AddAzureClients 上配置 HttpProxy

开发技巧-Java通过HttpProxy实现穿越

代码片段 - Golang 实现简单的 Web 服务器

markdown 在Intel Nuc上设置Ubuntu Web服务器,步骤和代码片段

从片段调用 Google Play 游戏服务