Python的BaseRequestHandler rfile.read()方法是如何工作的?

3
我正在通过POST将一个包含Python脚本中字符串的文本文件发送到我的服务器:
fo = open('data.txt','a')
fo.write("hi, this is my testing data")
fo.close()

with open('data.txt', 'rb') as f:
    r = requests.post("http://XXX.XX.X.X", data = {'data.txt':f})
    f.close()

在我的服务器处理程序脚本中接收并处理它,该脚本是基于在线示例构建的:

def do_POST(self):
    data = self.rfile.read(int(self.headers.getheader('Content-Length')))
    empty = [data]
    with open('processing.txt', 'wb') as file:
        for item in empty:
            file.write("%s\n" % item)
                
    file.close()
    self._set_headers()
    self.wfile.write("<html><body><h1>POST!</h1></body></html>")

我想问的是,这个怎么实现:

self.rfile.read(int(self.headers.getheader('Content-Length')))

获取我的数据长度(一个整数,以字节/字符为单位),然后读取我的文件?我不明白它如何知道我的数据包含什么。HTTP背后发生了什么?

它输出data.txt=hi%2C+this+is+my+testing+data

到我的processing.txt,但我期望得到"hi this is my testing data"

我尝试过查找rfile.read()的文档,但没有成功,如果找到答案就可以解决我的问题,我会删除这个问题。

1个回答

2

您的客户端代码片段从文件data.txt中读取内容,并将其作为键值对结构化的数据进行POST请求发送到您的服务器。在这种情况下,发送到服务器的数据是一个键data.txt,相应的值是文件的内容。

您的服务器代码片段会读取整个HTTP请求体并将其转储到文件中。从客户端发送的键值对结构化数据可以通过Python的内置库urlparse进行解码。

以下是可能有效的解决方案:

def do_POST(self):
    length = int(self.headers.get('content-length'))
    field_data = self.rfile.read(length)
    fields = urlparse.parse_qs(field_data)

这段代码的来源是:https://dev59.com/73E95IYBdhLWcg3wCJTj#31363982
如果您想要提取文本文件的内容,可以在上述代码中添加以下行来帮助实现:
data_file = fields["data.txt"]

要了解有关HTTP目的的信息如何进行编码,请阅读更多内容:https://en.wikipedia.org/wiki/Percent-encoding

我明白了,我认为我懂了。但是,您能澄清一下'rfile'是什么吗?我知道read()是Python内置的函数。 - kasool
2
你可以在这里阅读更多相关信息:https://docs.python.org/2/library/basehttpserver.html#BaseHTTPServer.BaseHTTPRequestHandler.rfile。基本上,它是一个包含请求正文中所有内容的流。当你的函数被调用时,通常由Python内置的`BaseHTTPRequestHandler`或其派生类为你设置,以便你访问。 - Axe
2
为什么会感到羞耻?你应该毫不羞愧地正确署名这个想法。 - WestCoastProjects
在Python 3中,这将导致一个“AttributeError:'HTTPMessage'对象没有属性'getheader'”。要修复,请用“get()”替换“getheader()”调用。 - Henrik Heimbuerger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接