最近我用C语言编写了一个程序,用来连接到本地运行的HTTP服务器,从而做出请求。
这对我来说很好。 之后,我尝试了相同的代码连接到networking上的另一台服务器(例如www.google.com),但我无法连接,并从我的networking中的代理服务器获得另一个html响应。
这是我得到的回应:
HTTP/1.1 302 Found Expires: Fri, 10 Feb 2012 12:47:35 GMT Expires: 0 Cache-Control: max-age=180000 Cache-Control: no-store, no-cache, must-revalidate Cache-Control: post-check=0, pre-check=0 Pragma: no-cache Connection: close Location: http://10.0.0.1:8000/index.php?redirurl=http%3A%2F%2F10.0.2.58%2F Content-type: text/html Content-Length: 0 Date: Wed, 08 Feb 2012 10:47:35 GMT Server: lighttpd/1.4.29
我怎样才能绕过这个代理连接到外部服务器?
HTTP/1.1 302 Found Expires: Fri, 10 Feb 2012 13:37:58 GMT Expires: 0 Cache-Control: max-age=180000 Cache-Control: no-store, no-cache, must-revalidate Cache-Control: post-check=0, pre-check=0 Pragma: no-cache Connection: close Location: http://10.0.0.1:8000/index.php?redirurl=http%3A%2F%2F10.0.2.58http%3A%2F%2Fwww.google.com%2F Content-type: text/html Content-Length: 0 Date: Wed, 08 Feb 2012 11:37:58 GMT Server: lighttpd/1.4.29
#include<unistd.h> #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<netdb.h> #include<string.h> #define MAX_BUFFER_SIZE 1024 int main(int argc,char *argv[]) { int clsd,ssd,status; char buffer[1024]; char request[]="GET / HTTP/1.1\r\nHost:10.0.2.58\r\n\r\n"; struct sockaddr_in srvr_addr; struct addrinfo hints,*res; srvr_addr.sin_family=AF_INET; srvr_addr.sin_port=htons(80); srvr_addr.sin_addr.s_addr=inet_addr("10.0.2.58");//Local server clsd =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(clsd<=0) { perror("Socket init failed..\n");return 1; } ssd=connect(clsd,(struct sockaddr *)&srvr_addr,(socklen_t)(sizeof srvr_addr)); if(clsd<=0) { perror("Socket connect failed..\n");return 1; } write(clsd,request,strlen(request)); memset((void *)&request,0x00,strlen(request)); memset(&buffer,0x00,MAX_BUFFER_SIZE); do { status=read(clsd,&buffer,MAX_BUFFER_SIZE); write(1,&buffer,status); memset((void *)&request,0x00,strlen(request)); memset(&buffer,0x00,MAX_BUFFER_SIZE); do { status=read(clsd,&buffer,MAX_BUFFER_SIZE); write(1,&buffer,status); }while(status>0); close(clsd); return 0; }
要通过代理使用连接(或者如果它们是隐式代理服务的话),首先你应该连接到代理服务器,发送一个“连接”消息给目标主机; 代理将建立连接并返回您的数据。
这里是步骤:
你必须指定协议(在我们的例子中是HTTP 1.0,非分块),以换行符结束,所以代理知道如何与终点进行通信。
你可以在http://www.ietf.org/rfc/rfc2817.txt找到关于CONNECT方法的细节
如果您专门试图绕过代理服务器,则应该与管理您的网络的人员进行沟通,以确定是否有可能。 如果您的第一个输出块是尝试连接到Google,那么在我看来,网络上存在某种透明代理,您必须采取特殊的(特定于网络的)步骤才能绕过。
当然,如果你只是有兴趣获取数据,你可以尝试按照重定向…