【问题标题】:How to connect a socket to an http server through proxy?如何通过代理将套接字连接到 http 服务器?
【发布时间】:2012-02-29 19:14:54
【问题描述】:

最近我用 C 语言编写了一个使用套接字的程序,用于连接到本地运行的 HTTP 服务器,从而向它发出请求。

这对我来说很好。之后,我尝试使用相同的代码连接到网络上的另一台服务器(例如 www.google.com),但我无法连接并从我的网络中的代理服务器获得另一个 html 响应。

  • 我的本地IP是:10.0.2.58
  • 代理IP为:10.0.0.1

这是我得到的回复:

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

如何绕过此代理连接到外部服务器?


尝试使用 CONNECT 时得到响应

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

连接到我的本地 apache 的工作代码

#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;
}

【问题讨论】:

  • 人们如何在帖子末尾出现许多随机换行符?乱七八糟的乱七八糟>.

标签: c++ c linux proxy network-programming


【解决方案1】:

要通过代理使用连接(或者如果它们是隐式代理的),首先您应该连接到代理,向目标主机发送“CONNECT”消息;代理将建立连接并返回数据。

这里是步骤:

  1. 打开代理主机的套接字
  2. 发送'CONNECT http://www.google.com:80 HTTP/1.0\r\n\r\n'字符串
  3. 等待接收

您必须指定带有结束换行符的协议(在我们的例子中是 HTTP 1.0,非分块),以便代理知道如何与端点通信。

您可以在http://www.ietf.org/rfc/rfc2817.txt找到有关 CONNECT 方法的详细信息

【讨论】:

  • 好 :) 现在您必须重定向。 “HTTP/1.1 302 Found”是来自服务器的响应,它指示您从响应中读取“位置:”部分,然后转到它。
  • 但是当我复制重定向网址并在浏览器中尝试时,它会将我重定向到代理管理员页面
  • 嗯...在我看到一些代码之前有点难以猜测。你试过telnet吗?检查这个:anta.net/misc/telnet-troubleshooting/http-proxy.shtml,除了端口 25,你应该使用 80。
  • dennis,代理是透明的,所以没有收到 telnet 响应,总是显示正在尝试连接
  • 好吧,如果代理是透明的,那么所有包都必须通过它,在没有发件人知识的情况下,与 google.com 的连接应该没有问题。我检查了你的代码(假设你知道你没有连接到谷歌,而是连接到一些内部机器)并且它应该可以工作(在填充缺失的代码后由于不完整的粘贴)。
【解决方案2】:

如果您专门尝试绕过代理,您应该与管理您的网络的人交谈,以了解这是否可能。如果您的第一个输出块是尝试连接到 Google,那么在我看来,您的网络上有某种透明代理,您必须采取特殊(和特定于网络)步骤才能绕过。

当然,如果您只是对获取数据感兴趣,您可以尝试按照重定向...

【讨论】:

  • 是的,网络中的代理是透明的,我猜是这样.. 我怎样才能绕过它?我可以使用 firefox 和 all 来获取页面,这样我如何使用我自己的代码来获取页面?
  • 如果代理正在捕获端口 80 上的所有传出流量(可能更多),那么您需要与运行代理的人交谈 - 他们将能够告诉您 (1) 如果你可以绕过它(2)你怎么能绕过它(3)如果你不能,你应该怎么做。
猜你喜欢
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 2015-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多