【问题标题】:Python socket module. Connecting to an HTTP proxy then performing a GET request on an external resourcePython 套接字模块。连接到 HTTP 代理,然后对外部资源执行 GET 请求
【发布时间】:2015-12-23 21:15:06
【问题描述】:

首先,我知道还有其他模块(例如 Requests)更适合且更易于使用,但我想使用 socket 模块来更好地理解 HTTP。

我有一个执行以下操作的简单脚本:

客户端 ---> HTTP 代理 ---> 外部资源 (GET Google.com)

我可以连接到 HTTP 代理,但是当我将 google.com 的 GET 请求标头发送到代理时,它根本没有为我提供任何响应。

#!/usr/bin/python
import socket
import sys



headers = """GET / HTTP/1.1\r\n
Host: google.com\r\n\r\n"""



socket = socket

host = "165.139.179.225" #proxy server IP
port = 8080              #proxy server port

try:
    s = socket.socket()
    s.connect((host,port))
    s.send(("CONNECT {0}:{1} HTTP/1.1\r\n" + "Host: {2}:    {3}\r\n\r\n").format(socket.gethostbyname(socket.gethostname()),1000,port,host))
    print s.recv(1096)
    s.send(headers)
    response = s.recv(1096)
   print response
   s.close()
except socket.error,m:
   print str(m)
   s.close()
   sys.exit(1)

【问题讨论】:

    标签: python sockets http networking proxy


    【解决方案1】:

    要向代理发出 HTTP 请求,请打开与代理服务器的连接,然后发送 HTTP 代理请求。该请求与普通 HTTP 请求基本相同,但包含绝对 URL 而不是相对 URL,例如

     > GET http://www.google.com HTTP/1.1
     > Host: www.google.com
     > ...
    
     < HTTP response
    

    要使 HTTPS 请求使用 CONNECT 方法打开隧道,然后在该隧道内正常进行,即进行 SSL 握手,然后在隧道内进行正常的非代理请求,例如

     > CONNECT www.google.com:443 HTTP/1.1
     >
     < .. read response to CONNECT request, must be 200 ...
    
     .. establish the TLS connection inside the tunnel
    
     > GET / HTTP/1.1
     > Host: www.google.com
    

    【讨论】:

      【解决方案2】:

      Python 3 要求对请求进行编码。因此,扩展 David 的原始代码,结合 Steffens 的回答,这里是为 Python 3 编写的解决方案:

      def connectThroughProxy():
          headers = """GET http://www.example.org HTTP/1.1
                      Host: www.example.org\r\n\r\n"""
      
          host = "192.97.215.348" #proxy server IP
          port = 8080              #proxy server port
      
          try:
              s = socket.socket()
              s.connect((host,port))
              s.send(headers.encode('utf-8'))
              response = s.recv(3000)
              print (response)
              s.close()
          except socket.error as m:
             print (str(m))
             s.close()
             sys.exit(1) 
      

      这允许我通过我的公司代理连接到 example.org 主机(至少对于非 SSL/TLS 连接)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-23
        • 1970-01-01
        • 2018-01-27
        • 2015-12-29
        相关资源
        最近更新 更多