解析嵌套的多部分表单

开箱即用,Falcon不提供解析嵌套多部分表单的官方支持(即,使用嵌套的方法传输单个字段的多个文件 multipart/mixed 部分)。

注解

根据 living HTML5 standardRFC 7578, Section 4.3 .

但是,如果您的应用程序需要这样做,则可以使用与表单中嵌入的任何其他部分相同的方式来处理嵌套表单,方法是安装适当的媒体处理程序。

让我们扩展多部分表单解析器 media handlers 递归地解析 multipart/mixed 内容类型:

import falcon
import falcon.media

parser = falcon.media.MultipartFormHandler()
parser.parse_options.media_handlers['multipart/mixed'] = (
    falcon.media.MultipartFormHandler())

注解

这里我们为嵌套部分创建了一个新的解析器(带有默认选项),有效地禁止了进一步的递归。

如果需要深入到更深层的多部分表单层次结构,我们可以重用相同的解析器。

现在让我们在应用程序中使用支持嵌套的解析器:

import falcon
import falcon.media

class Forms:
    def on_post(self, req, resp):
        example = {}
        for part in req.media:
            if part.content_type.startswith('multipart/mixed'):
                for nested in part.media:
                    example[nested.filename] = nested.text

        resp.media = example


parser = falcon.media.MultipartFormHandler()
parser.parse_options.media_handlers['multipart/mixed'] = (
    falcon.media.MultipartFormHandler())

app = falcon.App()
app.req_options.media_handlers[falcon.MEDIA_MULTIPART] = parser
app.add_route('/forms', Forms())

我们现在应该能够使用一个包含嵌套 multipart/mixed 部分(示例是根据现在过时的 RFC 1867 ):

--AaB03x
Content-Disposition: form-data; name="field1"

Joe Blow
--AaB03x
Content-Disposition: form-data; name="docs"
Content-Type: multipart/mixed; boundary=BbC04y

--BbC04y
Content-Disposition: attachment; filename="file1.txt"

This is file1.

--BbC04y
Content-Disposition: attachment; filename="file2.txt"

Hello, World!

--BbC04y--

--AaB03x--

请注意,上述表格中的所有行尾都假定为CRLF。

表格应该是 POST ed和 Content-Type 标题集 multipart/form-data; boundary=AaB03x .