Python 我是否正确解析此HTTP POST请求?
首先让我说,我使用的是Python 我是否正确解析此HTTP POST请求?,python,http,parsing,file-upload,twisted.web,Python,Http,Parsing,File Upload,Twisted.web,首先让我说,我使用的是twisted.web框架Twisted.web的文件上传没有按我所希望的那样工作(它只包括文件数据,而不包括任何其他信息),cgi.parse\u multipart没有按我所希望的那样工作(同样,Twisted.web使用此功能),cgi.FieldStorage没有工作(因为我是通过twisted而不是CGI接口获取POST数据的——据我所知,FieldStorage试图通过stdin获取请求)和twisted.web2对我不起作用,因为使用Deferred让我感到困
twisted.web
框架Twisted.web
的文件上传没有按我所希望的那样工作(它只包括文件数据,而不包括任何其他信息),cgi.parse\u multipart
没有按我所希望的那样工作(同样,Twisted.web
使用此功能),cgi.FieldStorage
没有工作(因为我是通过twisted而不是CGI接口获取POST数据的——据我所知,FieldStorage
试图通过stdin获取请求)和twisted.web2
对我不起作用,因为使用Deferred
让我感到困惑和愤怒(对于我想要的东西来说太复杂了)
话虽如此,我还是决定自己尝试解析HTTP请求
使用Chrome,HTTP请求的格式如下:
------WebKitFormBoundary7fouZ8mEjlCe92pq
Content-Disposition: form-data; name="upload_file_nonce"
11b03b61-9252-11df-a357-00266c608adb
------WebKitFormBoundary7fouZ8mEjlCe92pq
Content-Disposition: form-data; name="file"; filename="login.html"
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
...
------WebKitFormBoundary7fouZ8mEjlCe92pq
Content-Disposition: form-data; name="file"; filename=""
------WebKitFormBoundary7fouZ8mEjlCe92pq--
你可以看到我开始了一个新的“文件”每当到达一个边界时,就记录。我将in_header
设置为True
,表示我正在解析标题。当我到达一个空行时,我将其切换为False
——但在检查是否为该表单值设置了内容类型之前——如果没有,我将设置为忽略当前_文件,因为我只是在查找文件上传
我知道我应该使用一个库,但我已经厌倦了阅读文档,尝试在我的项目中使用不同的解决方案,并且仍然让代码看起来合理。我只想通过这一部分——如果用文件上传解析HTTP帖子这么简单,那么我将坚持下去
注意:这段代码目前运行得很好,我只是想知道它是否会阻塞来自某些浏览器的请求。内容处理头没有定义字段顺序,而且它可能包含的字段比文件名多。因此,文件名匹配可能会失败-甚至可能没有文件名
请参阅(编辑邮件,请参阅,对于http,可能还有更多)
此外,我还建议在此类regexp中,将每个空格替换为\s*,并且不要依赖字符大小写。您试图避免阅读文档,但我认为最好的建议是实际阅读:
- rfc 2388
- RFC1867
以确保您不会错过任何案例。更简单的方法可能是使用库。我解决此问题的方法是使用cgi.FieldStorage解析内容,如:
class Root(Resource):
def render_POST(self, request):
self.headers = request.getAllHeaders()
# For the parsing part look at [PyMOTW by Doug Hellmann][1]
img = cgi.FieldStorage(
fp = request.content,
headers = self.headers,
environ = {'REQUEST_METHOD':'POST',
'CONTENT_TYPE': self.headers['content-type'],
}
)
print img["upl_file"].name, img["upl_file"].filename,
print img["upl_file"].type, img["upl_file"].type
out = open(img["upl_file"].filename, 'wb')
out.write(img["upl_file"].value)
out.close()
request.redirect('/tests')
return ''
这并不是我试图避免文档,而是我要么找不到足够的文档,要么它导致了一条死胡同(不做我想做的事情)。我一定会仔细阅读的。明白了,我误读了这一点。肯定会阅读RFC,因为它们是关于这些东西的官方词汇,但你会正确地质疑在野外实际的浏览器实现是否有黑暗的角落。而且,海报似乎只用于创建HTTP请求——我在该文档中看不到任何内容关于解码的解释。它也能解码吗?我的意思是更容易测试您自己的实现(而不是考虑您可能缺少的情况…)。不确定服务器端库,但wsgi/pylons代码库中可能有一些内容。这是真的。感谢您的帮助这些都指定了邮件或附件,我主要查找的是表单数据内容配置。但它们看起来相同,我可能会查看所有的示例,我认为它们依赖于确切的rfc字段的可用性/不可用性和精确顺序不是很明智。即使filename
是目前唯一的字段,将来可能会添加更多字段,而您的代码会中断。即使我使用twisted和klein作为web服务器,这对我来说确实有效。延迟实际上是一种方式,因为异步魔法就是这样发生的。
class Root(Resource):
def render_POST(self, request):
self.headers = request.getAllHeaders()
# For the parsing part look at [PyMOTW by Doug Hellmann][1]
img = cgi.FieldStorage(
fp = request.content,
headers = self.headers,
environ = {'REQUEST_METHOD':'POST',
'CONTENT_TYPE': self.headers['content-type'],
}
)
print img["upl_file"].name, img["upl_file"].filename,
print img["upl_file"].type, img["upl_file"].type
out = open(img["upl_file"].filename, 'wb')
out.write(img["upl_file"].value)
out.close()
request.redirect('/tests')
return ''