python - 我是否正确解析了这个 HTTP POST 请求?

标签 python http parsing file-upload twisted.web

首先让我说,我正在使用 twisted.web 框架。 Twisted.web 的文件上传没有像我想要的那样工作(它只包含文件数据,没有任何其他信息),cgi.parse_multipart 没有没有像我想要的那样工作(同样,twisted.web 使用这个函数),cgi.FieldStorage 没有工作(因为我正在获取 POST 数据通过扭曲,而不是 CGI 接口(interface)——据我所知,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--

它总是这样形成的吗?我正在用正则表达式解析它,就像这样(请原谅代码墙):

(请注意,我删除了大部分代码以仅显示我认为相关的内容(正则表达式(是的,嵌套括号)),这是一个 __init__ 方法(目前唯一的方法) 在我构建的 Uploads 类中。完整的代码可以在修订历史中看到(我希望我没有匹配任何括号)

if line == "--{0}--".format(boundary):
    finished = True

if in_header == True and not line:
    in_header = False
    if 'type' not in current_file:
        ignore_current_file = True

if in_header == True:
    m = re.match(
        "Content-Disposition: form-data; name=\"(.*?)\"; filename=\"(.*?)\"$", line)
    if m:
        input_name, current_file['filename'] = m.group(1), m.group(2)

    m = re.match("Content-Type: (.*)$", line)
    if m:
        current_file['type'] = m.group(1)

    else:
        if 'data' not in current_file:
            current_file['data'] = line
        else:
            current_file['data'] += line

你可以看到,每当达到边界时,我都会开始一个新的"file"字典。我将 in_header 设置为 True 表示我正在解析 header 。当我到达一个空白行时,我将其切换为 False - 但在检查是否为该表单值设置了 Content-Type 之前 - 如果没有,我设置ignore_current_file 因为我只是在寻找文件上传。

我知道我应该使用一个库,但我厌倦了阅读文档,尝试让不同的解决方案在我的项目中工作,并且仍然让代码看起来合理。我只想跳过这一部分——如果解析带有文件上传的 HTTP POST 这么简单,那么我会坚持下去。

注意:这段代码目前运行良好,我只是想知道它是否会阻塞/吐出来自某些浏览器的请求。

最佳答案

我对这个问题的解决方案是使用 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 ''

关于python - 我是否正确解析了这个 HTTP POST 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3275081/

相关文章:

java - 在Java中解析一个固定宽度的格式化文件

python - 将两个字符串与备用字符合并为输出

wordpress - 只有主页适用于 Wordpress https

java - Java HTTP 连接池是否有驱逐时间?可以设置吗?

c++ - 如何将字符串形式的日期 ("Dec 25, 2012") 转换为一组整数 (12/25/12)?

xml - 如何在flex中访问xml节点

python - 如何使 Python selenium 的点击速度更快?

python - 寻求一个快速的 filter() 与删除

python - 进行类别不平衡正则化的正确位置(数据级别或批处理级别)

java - 将 http 请求转发到将使用 java servlet 响应原始请求者的其他服务器