Python 套接字 - 无法读取 HTTP POST 请求 body
Python socket - Couldn't read HTTP POST request body
我正在尝试通过基于套接字的 HTTP 代理来实现整个 HTTP 1.1
POST 请求,但无法在读取 body 后立即读取请求的 body =54=]s.
处理POST请求处理的主要代码是:
import socket
...
# request_buffer is initialized with the request's first line (with the method, uri and status).
request_buffer = http_status_line
socket_file = client_socket.makefile()
raw_headers = recv_headers(socket_file)
socket_file.close()
request_buffer += raw_headers
headers = dict_headers(raw_headers)
body_len = int(headers['Content-Length'][0])
print(repr(request_buffer))
raw_request = recv_body(client_socket, body_len)
request_buffer += raw_request
print(repr(raw_request))
server_socket.send(request_buffer)
而辅助函数的源码是:
def recv_headers(socket_file):
raw_headers = ''
while True:
header = socket_file.readline()
raw_headers += header
if len(header) == 2: # if header == '\r\n'
break
return raw_headers
def recv_body(conn_socket, body_len):
request_body = ''
bytes_read = 0
body_chunk = conn_socket.recv(body_len - bytes_read)
while len(body_chunk) > 0:
request_body += body_chunk
bytes_read += len(body_chunk)
body_chunk = conn_socket.recv(body_len - bytes_read)
return request_body
注意:我省略了dict_headers()
的源代码,因为它运行良好,为了您的方便,我想尽量减少代码量。
此外,我已经确保 body_len
具有正确的值(Content-Length
header 中的值)。
打印结果:
如您所见,raw_request
(请求 body)根本没有被打印出来。
通过代理转发的原始POST请求:
原始请求确实有一个 body 即:log=test&pwd=test
.
我们将不胜感激任何帮助
socket_file = client_socket.makefile()
raw_headers = recv_headers(socket_file)
...
raw_request = recv_body(client_socket, body_len)
对于 makefile
,您在 recv_headers
中使用缓冲 I/O。 recv_body
中后来的 recv
与原始套接字 object 一起工作,因此没有缓冲 I/O。混合缓冲和非缓冲 I/O 是麻烦的收据。
问题是初始缓冲 I/O 可能会在内部从底层套接字中检索比读取 headers 实际需要的数据更多的数据。这些额外的数据保存在 socket_file
的内部缓冲区中,可供 socket_file.read
使用。它们不再可用于 client_socket.recv
,因为它们已经从底层套接字中检索到。
因此,切勿混用缓冲和非缓冲 I/O。一旦你切换到缓冲 I/O 坚持下去。
我正在尝试通过基于套接字的 HTTP 代理来实现整个 HTTP 1.1
POST 请求,但无法在读取 body 后立即读取请求的 body =54=]s.
处理POST请求处理的主要代码是:
import socket
...
# request_buffer is initialized with the request's first line (with the method, uri and status).
request_buffer = http_status_line
socket_file = client_socket.makefile()
raw_headers = recv_headers(socket_file)
socket_file.close()
request_buffer += raw_headers
headers = dict_headers(raw_headers)
body_len = int(headers['Content-Length'][0])
print(repr(request_buffer))
raw_request = recv_body(client_socket, body_len)
request_buffer += raw_request
print(repr(raw_request))
server_socket.send(request_buffer)
而辅助函数的源码是:
def recv_headers(socket_file):
raw_headers = ''
while True:
header = socket_file.readline()
raw_headers += header
if len(header) == 2: # if header == '\r\n'
break
return raw_headers
def recv_body(conn_socket, body_len):
request_body = ''
bytes_read = 0
body_chunk = conn_socket.recv(body_len - bytes_read)
while len(body_chunk) > 0:
request_body += body_chunk
bytes_read += len(body_chunk)
body_chunk = conn_socket.recv(body_len - bytes_read)
return request_body
注意:我省略了dict_headers()
的源代码,因为它运行良好,为了您的方便,我想尽量减少代码量。
此外,我已经确保 body_len
具有正确的值(Content-Length
header 中的值)。
打印结果:
如您所见,raw_request
(请求 body)根本没有被打印出来。
通过代理转发的原始POST请求:
原始请求确实有一个 body 即:log=test&pwd=test
.
我们将不胜感激任何帮助
socket_file = client_socket.makefile()
raw_headers = recv_headers(socket_file)
...
raw_request = recv_body(client_socket, body_len)
对于 makefile
,您在 recv_headers
中使用缓冲 I/O。 recv_body
中后来的 recv
与原始套接字 object 一起工作,因此没有缓冲 I/O。混合缓冲和非缓冲 I/O 是麻烦的收据。
问题是初始缓冲 I/O 可能会在内部从底层套接字中检索比读取 headers 实际需要的数据更多的数据。这些额外的数据保存在 socket_file
的内部缓冲区中,可供 socket_file.read
使用。它们不再可用于 client_socket.recv
,因为它们已经从底层套接字中检索到。
因此,切勿混用缓冲和非缓冲 I/O。一旦你切换到缓冲 I/O 坚持下去。