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 坚持下去。