2024年5月31日发(作者:)

socks5代理可以看rfc 1928

socks5的用户名口令认证方法看rfc 1929

http代理可以看 rfc2616

socks5代理可以支持tcp和udp 而http只支持tcp

所以这个代理转换器只支持tcp

写作原因

很多软件都有socks5认证方法 但是它们不支持http认证方法

而从原理上可以使用http认证方法(因为它们没有使用udp)

所以写这个软件可以方便的使其它程序可以使用http代理

如联众 或是foxmail

CODE

#include

#include

#include

#define

INIT_SOCKET(){WSADATA wsadata;WSAStartup(MAKEWORD(2,2),&wsadata

);}

#define CLOSESOCKET(x) closesocket(x)

#define CLEAN_SOCKET() {WSACleanup();}

// http.c 实现http代理功能

#define PROTO_EXCHANGE_TIMEOUT 15

#define PROTO_RECVRESP_TIMEOUT 75

#define PROTO_SENDRESP_TIMEOUT 10

#define WAIT_AND_RECV(sd,buf,len,waittime,recvflags) do{

struct fd_set sset;

struct timeval waited;

_sec = waittime;_usec = 0;

FD_ZERO(&sset);FD_SET(sd,&sset);

if(select(sd+1,&sset,NULL,NULL,&waited) != 1 || (len = recv(sd,buf,len,recvflags))

== -1 )

len = -1;

}while(0);

#define DEBUG_DUMP printf

static int httpproxy_connect(const char*proxyaddr,int proxyport,

const char*dstaddr,int dstport)

{

int proxysd = -1;

char buf[2048];

int len;

char *ptoken;

int status;

struct sockaddr_in inaddr;

if( !proxyaddr || !proxyaddr[0] || proxyport < 1

||!dstaddr || !dstaddr[0] )

return -1;

DEBUG_DUMP("代理:%s:%d,目

标:%s:%dn",proxyaddr,proxyport,dstaddr,dstport);

len = sizeof(inaddr);

memset(&inaddr,0,len);

if( (_addr.s_addr = inet_addr(proxyaddr) ) == INADDR_NONE )

return -1;

_family = AF_INET;

_port = htons(proxyport);

// connect to proxy

if((proxysd = socket(AF_INET,SOCK_STREAM,0)) == -1 )

return -1;

if( connect(proxysd,(struct sockaddr*)&inaddr,len))

goto errorparse;

// 发送connect请求并判断返回,根据HTTP协议说明,详细内容请看RFC2616

// HTTP代理使用CONNECT指令实现,CONNECT时指定选端的地址与端

口号,

// 当代理服务器返回成功后(状态值是2xx),后面的代理服务器不再对此连接

的数据

// 进行HTTP协议处理

if( dstport > 0 )

len = sprintf(buf,"CONNECT %s:%d HTTP/1.1rnrn",dstaddr,dstport);

else

len = sprintf(buf,"CONNECT %s HTTP/1.1rnrn",dstaddr);

if( send(proxysd,buf,len,0) != len ){

DEBUG_DUMP("发送CONNECT请求失败:包内容:%sn",buf);

goto errorparse;

}

len = sizeof(buf)-1;

WAIT_AND_RECV(proxysd,buf,len,PROTO_RECVRESP_TIMEOUT,MSG_PE

EK);

if( len == -1){

DEBUG_DUMP("接收CONNECT响应失败n");

goto errorparse;

}

buf[len] = 0;

DEBUG_DUMP("CONNECT响应为:%s|n",buf);

if( strnicmp(buf,"HTTP/1.",7)

|| (!strstr(buf,"rnrn") && !strstr(buf,"nn")))

goto errorparse;

ptoken = buf;