公司通过代理上网,C程序直接通过发http请求不能获取网页内容,故实现了下通过代理访问http网页的一个测试程序。
程序很简单,有几个重点
-
先通过socket直接连接代理服务器
-
向代理服务器发送HTTP的CONNECT标头,格式为CONNECT www.baidu.com:80 HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n
其中%s处替换为user:passwd的base64编码
-
鉴权通过后 send请求就ok,注意此处和不用代理的区别是 GET后面的地址要http://www.baidu.com 而不能是www.baidu.com
-
这是个测试程序,目的只是说明实现过程,我测试的可以收到返回报文,也有不完善的地方,比如接收不全。
代码如下:
- #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 ((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);
-
-
- 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);
-
- 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;
- }
-
-
- 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]$