python - Squid 代理在 python 发出的 GET 请求上给出 501 但不 curl

标签 python sockets http curl squid

所以我有一个程序可以使用裸套接字下载网页。我必须使用裸套接字,不能使用请求或 urllib 等任何东西。我在 Squid 代理后面的网络上,所以我的 python 程序只是 connect 到代理服务器并使GET 请求我从 HAR 文件中获取的对象。我使用 curl like 测试了请求

curl https://apis.google.com/_/scs/abc-static/_/js/k=gapi.gapi.en.wgbKiK972Ko.O/m=gapi_iframes,googleapis_client,plusone/rt=j/sv=1/d=1/ed=1/rs=AItRSTOlX0YCaQmKijyj5lpKQ5AVm7UE6A/cb=gapi.loaded_0 -o out_file

然后我将输出作为正确的整个文件。我检查了响应的 header ,它们是

HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Type: text/javascript; charset=UTF-8
Last-Modified: Thu, 11 Dec 2014 20:44:59 GMT
Date: Fri, 12 Dec 2014 03:38:46 GMT
Expires: Sat, 12 Dec 2015 03:38:46 GMT
X-Content-Type-Options: nosniff
Server: sffe
X-XSS-Protection: 1; mode=block
Cache-Control: public, max-age=31536000
Age: 1065247
Alternate-Protocol: 443:quic,p=0.02
Transfer-Encoding: chunked

现在我尝试使用 python 中的套接字编程来做同样的事情:

    HOST = 'proxy.address.of.squid.proxy'
    PORT = 3128
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    url = 'https://apis.google.com/_/scs/abc-static/_/js/k=gapi.gapi.en.wgbKiK972Ko.O/m=gapi_iframes,googleapis_client,plusone/rt=j/sv=1/d=1/ed=1/rs=AItRSTOlX0YCaQmKijyj5lpKQ5AVm7UE6A/cb=gapi.loaded_0'
    httpVrsn = 'HTTP/1.1'
    domain = 'apis.google.com'
    objReq = 'GET '+url+' '+httpVrsn+'\r\nHost: '+domain+'\r\n\r\n';
    s.send(objReq);
    data = '';
    try:
        data = s.recv(1024);
        print data
    # other non-relevant stuff

我得到的输出是

HTTP/1.0 501 Not Implemented
Server: squid/3.1.19
Mime-Version: 1.0
Date: Wed, 24 Dec 2014 10:25:42 GMT
Content-Type: text/html
Content-Length: 3576
X-Squid-Error: ERR_UNSUP_REQ 0
Vary: Accept-Language
Content-Language: en
X-Cache: MISS from localhost
X-Cache-Lookup: NONE from localhost:3128
Via: 1.0 localhost (squid/3.1.19)
Connection: close

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>ERROR: The requested URL could not be retrieved</title>
<style type="text/css"><!-- 
 /*
 Stylesheet for Squid Error pages
 Adapted from design by Free CSS Templates
 http://www.freecsstemplates.org
 Released for free under a Creative Commons Attribution 2.5 License
*/

/* Page basics */
* {
  font-family: verdana, sans-serif;
}

html body {
  margin: 0;
  padding: 0;
  background: #efefef;
  font-size: 12px;
  color: #1e1e1e;
}

所以我查看了this这解释了我的 Squid 代理 3.1 不支持 Transfer-Encoding: chunked 但它说 POST 请求就是这种情况,我不确定它是否也适用于 GET 请求。我还检查了Unable to test HTTP PUT-based file upload via Squid Proxy .我不明白 curl 甚至我的浏览器如何能够在同一代理后面的同一网络上请求时获取内容,但通过 python 我无法成功获取响应?

那么有什么方法可以让我的 python 程序在不调整 Squid 代理的情况下工作,因为我无法控制代理。

最佳答案

Curl 使用 CONNECT 方法,这是一种隧道方法。代理仅在 TCP 级别连接到远程端,curl 执行所有通信,包括 TLS 握手。所有 TCP/IP 数据包都由代理来回“铲除”。但请注意,在某些条件下(例如,当管理员/公司将他自己的 CA 证书放入您的证书池时),代理的静默拦截 (MITM) 是可能的。

您的 Python 脚本所做的是要求代理与远程端通信。不知何故,您的代理无法进行 TLS 连接(在构建期间未配置或禁用,或者根本无法进行其他操作)。

要配置 Squid,请参阅 http://wiki.squid-cache.org/Features/HTTPS

关于python - Squid 代理在 python 发出的 GET 请求上给出 501 但不 curl ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636360/

相关文章:

objective-c - 如何使用 CFNetwork 从套接字获取字节数组?

java - 用Java用Socket链接两台计算机

sockets - 在git bash中杀死一个进程

python - Django 中意外的日期时间格式

python - 如何使用 Python 对原始信号应用 FFT

python - 为什么我的 request.user 在 Django 中没有组?

python - 带有 mechanicalsoup 的表单请求未显示预期结果

http - 用户登录时不显示上次修改的缓存

java - 响应未设置状态 400 Jersey

c# - 如何使用 C# 连接到路由器 "panel"