使用 `socket` 模块的 Python 代理服务器的奇怪响应正文
Weird Response's Body Of A Python Proxy Server Using `socket` Module
问题
我正在开发具有 Python3 套接字的基本代理服务器。它有效,但不如它应有的那样有效。响应头很好,但正文不行。
如下所示,响应正文看起来很奇怪 "Just Bytes 'x1f\x8b\x08\x00\x00...etc' ",但是当将它重定向到浏览器时,它会正确呈现它。
使用套接字接收到的响应
b"HTTP/1.1 200 OK
Vary: Accept-Encoding\r\n
Content-Encoding: gzip\r\n
Content-Length: 156\r\n
Keep-Alive: timeout=5, max=100\r\n
Connection: Keep-Alive\r\n
Content-Type: text/html\r\n\
r\n\
x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03-\x8e\xcb\x0e\x83 \x14D\xf7|\x05\xb2.\xd5e\xa3\xe8\xda?p\x8d@\x81\xf4\xea5p\xfb\xf0\xef\x8b\xc6\xd5$'\x939\x03h4\x04\xcc\xa4\x02-00\x15\x9c\xb6%(\x12\xb8\x81\x8d\x0e\x00o|\xc2\x04\xb6b\xaa\xbe\xb0\xaa\xaf\xda\x8cv\xe7\xb37\x08\x98z1\x836/Q\xb0\x8d\x1f\x9ei\x07\xd7\x8bE'\x1f\xd7V\xbf\t\xbbo\xb4\x14\xdaG\xd3l\xbf\xae\xd4\xc6\xc8T%\xa5\x8a\x8b\xe79\x99^\x84\xe7}[\xbd\x18\xa4<\x14e\xe4\x88Cq\x1a\xcf\x7f\x7f\x10\x07P@\xb0\x00\x00\x00"
响应代码是:
def receive(sock):
sock.settimeout(3)
data=b""
try:
while 1:
rcvd=sock.recv(4096)
if not rcvd:
break
data+=rcvd
except:
pass
return data
然后我用Burp Suite
得到了同样的响应,响应的正文是正常的。
与 Burp 相同的响应
HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Length: 176
Connection: close
Content-Type: text/html
localhost<html>
<head>
<title>
Hello, World!
</title>
</head>
<body bgcolor="black">
<div style="margin:auto;width:800px;">
Hi
</div>
</body>
</html>
如果 localhost
个站点存在,但如果请求的站点不存在,就会出现此问题 404 not found
响应正常,正文清晰正常。
所以,我想弄清楚问题是什么以及如何解决它。
It Works, But Not As It Should Work. The Response Headers Are Fine, But The Body Is Not. As It's Shown Below, The Response Body Looks Weird "Just Bytes 'x1f\x8b\x08\x00\x00...etc' ",
body完全没问题,只是你不明白没问题:
b"HTTP/1.1 200 OK
...
Content-Encoding: gzip\r\n
...
x1f\x8b\x08\x00\x00\x0...
从响应中可以看出 header 内容是用 gzip 压缩的。要按预期查看 "real" body,您需要使用 gzip 对其进行解压缩。如果您不想这样做,请不要在您的请求 header 中发送 Accept-Encoding: gzip ...
或类似字段,因为这明确表示您愿意接受 gzip
压缩内容。
总的来说:HTTP 比您通过查看几个示例可能想到的要复杂。除了压缩之外,还有其他通常意想不到的事情,例如分块传输编码和同一 TCP 连接中的多个请求和响应。请研究 HTTP 标准以获取更多信息,而不仅仅是 "assuming" - 这正是这些标准的实际用途。
问题
我正在开发具有 Python3 套接字的基本代理服务器。它有效,但不如它应有的那样有效。响应头很好,但正文不行。 如下所示,响应正文看起来很奇怪 "Just Bytes 'x1f\x8b\x08\x00\x00...etc' ",但是当将它重定向到浏览器时,它会正确呈现它。
使用套接字接收到的响应
b"HTTP/1.1 200 OK
Vary: Accept-Encoding\r\n
Content-Encoding: gzip\r\n
Content-Length: 156\r\n
Keep-Alive: timeout=5, max=100\r\n
Connection: Keep-Alive\r\n
Content-Type: text/html\r\n\
r\n\
x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03-\x8e\xcb\x0e\x83 \x14D\xf7|\x05\xb2.\xd5e\xa3\xe8\xda?p\x8d@\x81\xf4\xea5p\xfb\xf0\xef\x8b\xc6\xd5$'\x939\x03h4\x04\xcc\xa4\x02-00\x15\x9c\xb6%(\x12\xb8\x81\x8d\x0e\x00o|\xc2\x04\xb6b\xaa\xbe\xb0\xaa\xaf\xda\x8cv\xe7\xb37\x08\x98z1\x836/Q\xb0\x8d\x1f\x9ei\x07\xd7\x8bE'\x1f\xd7V\xbf\t\xbbo\xb4\x14\xdaG\xd3l\xbf\xae\xd4\xc6\xc8T%\xa5\x8a\x8b\xe79\x99^\x84\xe7}[\xbd\x18\xa4<\x14e\xe4\x88Cq\x1a\xcf\x7f\x7f\x10\x07P@\xb0\x00\x00\x00"
响应代码是:
def receive(sock):
sock.settimeout(3)
data=b""
try:
while 1:
rcvd=sock.recv(4096)
if not rcvd:
break
data+=rcvd
except:
pass
return data
然后我用Burp Suite
得到了同样的响应,响应的正文是正常的。
与 Burp 相同的响应
HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Length: 176
Connection: close
Content-Type: text/html
localhost<html>
<head>
<title>
Hello, World!
</title>
</head>
<body bgcolor="black">
<div style="margin:auto;width:800px;">
Hi
</div>
</body>
</html>
如果 localhost
个站点存在,但如果请求的站点不存在,就会出现此问题 404 not found
响应正常,正文清晰正常。
所以,我想弄清楚问题是什么以及如何解决它。
It Works, But Not As It Should Work. The Response Headers Are Fine, But The Body Is Not. As It's Shown Below, The Response Body Looks Weird "Just Bytes 'x1f\x8b\x08\x00\x00...etc' ",
body完全没问题,只是你不明白没问题:
b"HTTP/1.1 200 OK
...
Content-Encoding: gzip\r\n
...
x1f\x8b\x08\x00\x00\x0...
从响应中可以看出 header 内容是用 gzip 压缩的。要按预期查看 "real" body,您需要使用 gzip 对其进行解压缩。如果您不想这样做,请不要在您的请求 header 中发送 Accept-Encoding: gzip ...
或类似字段,因为这明确表示您愿意接受 gzip
压缩内容。
总的来说:HTTP 比您通过查看几个示例可能想到的要复杂。除了压缩之外,还有其他通常意想不到的事情,例如分块传输编码和同一 TCP 连接中的多个请求和响应。请研究 HTTP 标准以获取更多信息,而不仅仅是 "assuming" - 这正是这些标准的实际用途。