C/C++程序实现通过http代理访问网页内容

公司通过代理上网,C程序直接通过发http请求不能获取网页内容,故实现了下通过代理访问http网页的一个测试程序。

程序很简单,有几个重点

  1. 先通过socket直接连接代理服务器

  2. 向代理服务器发送HTTP的CONNECT标头,格式为CONNECT www.baidu.com:80 HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n

    其中%s处替换为user:passwd的base64编码

  3. 鉴权通过后 send请求就ok,注意此处和不用代理的区别是 GET后面的地址要http://www.baidu.com 而不能是www.baidu.com

  4. 这是个测试程序,目的只是说明实现过程,我测试的可以收到返回报文,也有不完善的地方,比如接收不全。


代码如下:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string>

//以下六个参数改为自己需要的即可
const char *proxyAddr="10.1.1.2";
const int proxyPort = 8080;
const char *user="domain\\name";
const char *passwd="kklklkl";
const char *desthost="www.baidu.com";
const int destport=80;
static void to64frombits(unsigned char *out, const unsigned char *in, int inlen);

int main() {
	int sock_fd;
	struct sockaddr_in addr;
	struct hostent *hptr;
	char str[32];
	
	/*	if((hptr = gethostbyname(proxyAddr)) == NULL)
	    {
	        printf(" gethostbyname error for host:%s\n", proxyAddr);
	        return 0; 
	    }
	*/    
	if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		perror("socket() fail.");
	
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(proxyPort);
	inet_aton(proxyAddr, &addr.sin_addr);
	//memcpy(&addr.sin_addr.s_addr,hptr->h_addr,sizeof(addr.sin_addr.s_addr));
	//printf("proxy ip=%s\n",inet_ntop(hptr->h_addrtype,hptr->h_addr,str,sizeof(str)));
	if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		close(sock_fd);
		perror("connect() fail.");
	}
	printf("-=-=-=-=-=-=-=We have connect the proxy ok!!!!-=-=-=-=-=-=-=\n");
	char tmp[10240+1];
	char authstr[10240+1];
	memset(tmp,0x0,sizeof(tmp));
	memset(authstr,0x0,sizeof(authstr));
	sprintf(tmp,"%s:%s",user,passwd);
	printf("=======%s",tmp);
	to64frombits((unsigned char*)authstr,(unsigned char*)tmp,strlen(tmp));
	printf("--=====%s",authstr);
	snprintf(tmp,sizeof(tmp),"CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n", desthost, destport, authstr);
	send(sock_fd, tmp, strlen(tmp), 0);
	printf("-=-=-=-=-=wait for recv-=-=-=-=-=\n");
	
	memset(tmp,0x0,sizeof(tmp));
	recv(sock_fd, tmp, sizeof(tmp), 0);
	printf("recv=%s",tmp);
	//通过代理get,此处的url一定要是全路径带上http://,否则访问不到
	snprintf(tmp,sizeof(tmp),"GET %s HTTP/1.0\r\n", "http://www.baidu.com/");
	strcpy(tmp+strlen(tmp),"Accept:*/*\r\n");
	strcpy(tmp+strlen(tmp),"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
	strcpy(tmp+strlen(tmp),"Accept-Language:zh-cn\r\n");
	strcpy(tmp+strlen(tmp),"Connection:close\r\n\r\n");
	send(sock_fd, tmp, strlen(tmp), 0);
	memset(tmp,0x0,sizeof(tmp));
	sleep(5);
	recv(sock_fd, tmp, sizeof(tmp), 0);
	printf("recv2=%s",tmp);
	close(sock_fd);
	return 0;
}

//base64编码函数
static void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
{
	const char base64digits[] =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	for (; inlen >= 3; inlen -= 3)
	{
		*out++ = base64digits[in[0] >> 2];
		*out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
		*out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
		*out++ = base64digits[in[2] & 0x3f];
		in += 3;
	}
	if (inlen > 0)
	{
		unsigned char fragment;
		*out++ = base64digits[in[0] >> 2];
		fragment = (in[0] << 4) & 0x30;
		if (inlen > 1)
		fragment |= in[1] >> 4;
		*out++ = base64digits[fragment];
		*out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
		*out++ = '=';
	}
	*out = '\0';
}


测试结果:

测试结果:

[@dev1 myfile]$ ./proxy_test 

-=-=-=-=-=-=-=We have connect the proxy ok!!!!-=-=-=-=-=-=-=

=======test:1111132%--=====YdlsdfdiaDp6YmgyNDI3MDY1JQ==-=-=-=-=-=wait for recv-=-=-=-=-=

recv=HTTP/1.0 200 Connection established


recv2=HTTP/1.1 200 OK

Date: Wed, 06 Nov 2013 10:15:13 GMT

Server: Apache

P3P: CP=" OTI DSP COR IVA OUR IND COM "

P3P: CP=" OTI DSP COR IVA OUR IND COM "

Set-Cookie: BAIDUID=8F0C54DC13B905C0FA9EFD43B9D053C1:FG=1; expires=Thu, 06-Nov-14 10:15:13 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Set-Cookie: BAIDUID=8F0C54DC13B905C09E3548EFD4211EBA:FG=1; expires=Thu, 06-Nov-14 10:15:13 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Last-Modified: Mon, 31 Dec 2012 10:42:36 GMT

ETag: "1cdb-4d223abde3f00"

Accept-Ranges: bytes

Content-Length: 7387

Cache-Control: max-age=1

Expires: Wed, 06 Nov 2013 10:15:14 GMT

Vary: Accept-Encoding,User-Agent

Connection: Close

Content-Type: text/html


<!doctype html><html><head><meta http-equiv="Content-Type" content="text/html;charset=gb2312"><title>百度一下,你就知道      </title><style>html{overflow-y:auto}body{font:12px arial;text-align:center;background:#fff}body,p,form,ul{margin:0;padding:0}body,form,#fm{position:relative}td{text-align:left}img{border:0}a{color:#00c}a:active{color:#f60}#u{padding:7px 10px 3px 0;text-align:right}#m{width:680px;margin:0 auto}#nv{font-size:16px;margin:0 0 4px;text-align:left;text-indent:117px}#nv a,#nv b,.btn,#lk{font-size:14px}#fm{padding-left:90px;text-align:left}#kw{width:404px;height:22px;padding:4px 7px;padding:6px 7px 2px\9;font:16px arial;background:url(http://www.baidu.com/img/i-1.0.0.png) no-repeat -304px 0;_background-attachment:fi[@dev1 myfile]$



展开阅读全文

没有更多推荐了,返回首页