cherrypy._cpreqbody模块

请求CherryPy的正文处理。

3.2 新版功能.

应用程序作者完全控制HTTP请求实体的解析。总之, cherrypy.request.body 现在始终设置为 RequestBody ,以及 that 类是的子类 Entity

当HTTP请求包括实体主体时,通常需要以原始字节以外的形式向应用程序提供该信息。不同的内容类型需要不同的方法。示例:

  • 对于GIF文件,我们需要流中的原始字节。

  • HTML表单更适合解析为其组件字段,每个文本字段从字节解码为Unicode。

  • JSON正文应该反序列化为Python字典或列表。

当请求包含Content-Type标头时,媒体类型用作在 request.body.processors 迪克特。如果没有找到完整的媒体类型,则尝试主要类型;例如,如果没有找到用于‘image/jpeg’类型的处理器,那么我们将查找用于‘image’类型的处理器。如果完整类型和主要类型都没有匹配的处理器,则使用默认处理器 (default_proc )。对于大多数类型,这意味着不进行任何处理,主体将作为原始字节流保留为未读。处理器可以在“on_start_resource”挂钩中配置。

一些处理器,特别是那些用于“文本”类型的处理器,试图将字节解码为Unicode。如果Content-Type请求头包含‘charset’参数,则该参数用于解码实体。否则,可能会尝试一个或多个默认字符集,尽管此决定取决于每个处理器。如果处理器成功解码实体或部件,则应将 charset 属性设置为成功字符集的名称,以便应用程序可以根据需要轻松地重新编码或转码值。

如果请求实体的Content-Type是主要类型‘Multipart’,则对每个部分执行上述解析过程,并且可能还执行解码过程。

对于完整实体和多部分部分,可以使用Content-Disposition报头来填充 namefilename request.body或部件上的属性。

定制处理器

您可以为任何特定或主要的MIME类型添加您自己的处理器。只需将其添加到 processors 在以以下速度运行的钩子/工具中插入凹槽 on_start_resourcebefore_request_body 。以下是示例的内置JSON工具::

def json_in(force=True, debug=False):
    request = cherrypy.serving.request
    def json_processor(entity):
        '''Read application/json data into request.json.'''
        if not entity.headers.get("Content-Length", ""):
            raise cherrypy.HTTPError(411)

        body = entity.fp.read()
        try:
            request.json = json_decode(body)
        except ValueError:
            raise cherrypy.HTTPError(400, 'Invalid JSON document')
    if force:
        request.body.processors.clear()
        request.body.default_proc = cherrypy.HTTPError(
            415, 'Expected an application/json content type')
    request.body.processors['application/json'] = json_processor

我们首先定义一个新的 json_processor 函数插入到 processors 字典。所有处理器函数都采用单个参数,即 Entity 它们要处理的实例。只要接收到请求(对于打开工具的那些URI),就会调用它,该请求具有 Content-Type “application/json”。

首先,它检查有效的 Content-Length (如果无效则引发411),然后读取套接字上的剩余字节。这个 fp 对象知道自己的长度,因此它不会挂起等待从未到达的数据。它将在读取完所有数据后返回。然后,我们使用Python的内置代码对这些字节进行解码 json 模块,并将解码结果粘贴到 request.json 。如果它不能被解码,我们就筹集400美元。

如果“force”参数为True(默认值),则 Tool 清除 processors 以使其他被请求实体 Content-Types 根本不会被解析。由于没有那些无效MIME类型的条目,因此 default_proc 一种方法 cherrypy.request.body 被称为。但这在默认情况下什么也不做(通常是为页面处理程序提供处理它的机会)。但在我们的情况下,我们想筹集415,所以我们更换 request.body.default_proc 带着错误 (HTTPError 实例在被调用时会自动引发)。

如果我们正在定义一个自定义处理器,我们可以这样做,而不需要创建 Tool 。只需添加配置项::

request.body.processors = {'application/json': json_processor}

请注意,您只能替换 processors 以这种方式批发词典,而不是更新现有的词典。

class cherrypy._cpreqbody.Entity(fp, headers, params=None, parts=None)[源代码]

基类:object

HTTP请求正文或MIME多部分正文。

此类收集有关HTTP请求实体的信息。当给定的实体是MIME类型“multipart”时,每个部分都被解析成它自己的实体实例,并且这组部分存储在 entity.parts

在这两个人之间 before_request_bodybefore_handler 工具时,CherryPy尝试通过调用 request.body.process 。它使用 content_type 要在其中查找合适的处理器的实体的 Entity.processors ,判决书。如果找不到完整Content-Type的匹配处理器,它将使用主要类型重试。例如,如果具有类型为“image/jpeg”的实体的请求到达,但是找不到用于该完整类型的处理器,则会为主要类型“image”寻找一个处理器。如果仍未找到处理器,则 default_proc 方法被调用(默认情况下不执行任何操作;您也可以重写此操作)。

CherryPy包括用于“application/x-www-form-urlencode”类型、“multipart/form-data”类型和“multipart”主要类型的处理器。CherryPy 3.2处理这些类型几乎与旧版本完全相同。将部件作为参数传递给页面处理程序,使用 Content-Disposition.name 如果给定,则在泛型“part”参数中返回。每个这样的部分要么是字符串,要么是 Part 如果它是文件的话就是它本身。(在这种情况下,它将具有 filefilename 属性,或者可能是一个 value 属性)。每个部分本身都是Entity的子类,并且都有自己的子类 process 方法和方法 processors 迪克特。

对于“multipart”主类型,有一个单独的处理器,它更灵活,只需将所有多部分存储在 request.body.parts 。您可以使用以下命令启用它:

cherrypy.request.body.processors['multipart'] =             _cpreqbody.process_multipart

在一个 on_start_resource 工具。

attempt_charsets = ['utf-8']

字符串列表,每个字符串都应该是一种已知的编码。

当请求主体的Content-Type保证它时,将按顺序尝试每种给定的编码。第一个在不引发错误的情况下成功解码实体的代码存储为 entity.charset 。此默认值为 ['utf-8'] (根据要求,“文本/*”类型加上‘ISO-8859-1 HTTP/1.1 ),但是 ['us-ascii', 'utf-8'] 用于多部件零件。

charset = None

成功解码;请参阅上面的“ATTEMPATE_CHARSETS”。

content_type = None

Content-Type请求标头的值。

如果实体是多部分有效负载的一部分,则这将是此部分的MIME标头中给定的Content-Type。

decode_entity(value)[源代码]

以字符串形式返回给定的字节编码值

default_content_type = 'application/x-www-form-urlencoded'

这定义了一个默认值 Content-Type 在未提供Content-Type标头的情况下使用。空字符串用于RequestBody,这会导致根本不读取或解析请求正文。这是故意的;遗失了 Content-Type HTTP请求实体中的头往好了说是一个错误,往坏了说是一个安全漏洞。但是,对于多部分部件,MIME规范声明没有Content-Type的部件缺省为“Text/Plain”(请参见 Part )。

default_proc()[源代码]

如果找不到更具体的处理器,则调用 Content-Type

filename = None

这个 Content-Disposition.filename 标题(如果可用)。

fp = None

可读套接字文件对象。

fullvalue()[源代码]

将此实体作为字符串返回,无论是否存储在文件中。

headers = None

请求/多部分报头名称和值的字典。

这是一份 request.headers 对于 request.body ;对于多部分分块,它是该分块的报头集。

length = None

的价值 Content-Length 标头(如果提供)。

make_file()[源代码]

返回一个类似文件的对象,请求正文将被读取到该对象中。

默认情况下,这将返回一个TemporaryFile。根据需要覆盖。另请参阅 cherrypy._cpreqbody.Part.maxrambytes

name = None

属性的“name”参数 Content-Disposition 标题(如果有)。

next()[源代码]
params = None

如果请求Content-Type是‘application/x-www-form-urlencode’或multipart,这将是从实体主体拉出的params的判定;也就是说,它将是来自消息体的request.params部分(有时称为“post params”,尽管它们可以使用各种HTTP方法谓词发送)。此值在‘BEFORE_REQUEST_BODY’和‘BEFORE_HANDLER’挂钩之间设置(假设PROCESS_REQUEST_BODY为True)

part_class

用于多部分零件的类。

您可以将其替换为自定义子类,以更改多部分零件的处理。

:py:class:`cherrypy._cpreqbody.Part`的别名

parts = None

部件实例列表,如果 Content-Type 主要类型为“多部件”。

process()[源代码]

为给定的媒体类型执行最佳匹配处理器。

processors = {'application/x-www-form-urlencoded': <function process_urlencoded>, 'multipart': <function process_multipart>, 'multipart/form-data': <function process_multipart_form_data>}

处理器方法的内容类型名称字典。

read(size=None, fp_out=None)[源代码]
read_into_file(fp_out=None)[源代码]

将请求正文读入fp_out(如果没有,则读入make_file())。

返回fp_out。

readline(size=None)[源代码]
readlines(sizehint=None)[源代码]
class cherrypy._cpreqbody.Part(fp, headers, boundary)[源代码]

基类:cherrypy._cpreqbody.Entity

MIME部分实体,多部分实体的一部分。

attempt_charsets = ['us-ascii', 'utf-8']

字符串列表,每个字符串都应该是一种已知的编码。

当请求主体的Content-Type保证它时,将按顺序尝试每种给定的编码。第一个在不引发错误的情况下成功解码实体的代码存储为 entity.charset 。此默认值为 ['utf-8'] (根据要求,“文本/*”类型加上‘ISO-8859-1 HTTP/1.1 ),但是 ['us-ascii', 'utf-8'] 用于多部件零件。

boundary = None

MIME多部分边界。

default_content_type = 'text/plain'

这定义了一个默认值 Content-Type 在未提供Content-Type标头的情况下使用。空字符串用于RequestBody,这会导致根本不读取或解析请求正文。这是故意的;遗失了 Content-Type HTTP请求实体中的头往好了说是一个错误,往坏了说是一个安全漏洞。然而,对于多部分部件(此类),MIME规范声明没有Content-Type的部件默认为“文本/纯文本”。

default_proc()[源代码]

如果找不到更具体的处理器,则调用 Content-Type

classmethod from_fp(fp, boundary)[源代码]
maxrambytes = 1000

字节阈值,超过该阈值后, Part 将其数据存储在文件中(由生成 make_file )而不是字符串。默认设置为1000,就像 cgi Python标准库中的模块。

classmethod read_headers(fp)[源代码]
read_into_file(fp_out=None)[源代码]

将请求正文读入fp_out(如果没有,则读入make_file())。

返回fp_out。

read_lines_to_boundary(fp_out=None)[源代码]

从self.fp读取字节并将其返回或写入文件。

如果‘fp_out’参数为NONE(默认值),则在单个字节字符串中返回读取的所有字节。

如果‘fp_out’参数不是NONE,则它必须是支持‘write’方法的类似文件的对象;所有读取的字节都将写入fp,并返回该fp。

class cherrypy._cpreqbody.RequestBody(fp, headers, params=None, request_params=None)[源代码]

基类:cherrypy._cpreqbody.Entity

HTTP请求的实体。

bufsize = 8192

读取套接字时使用的缓冲区大小。

default_content_type = ''

这定义了一个默认值 Content-Type 在未提供Content-Type标头的情况下使用。空字符串用于RequestBody,这会导致根本不读取或解析请求正文。这是故意的;遗失了 Content-Type HTTP请求实体中的头往好了说是一个错误,往坏了说是一个安全漏洞。但是,对于多部分部件,MIME规范声明没有Content-Type的部件缺省为“Text/Plain”(请参见 Part )。

maxbytes = None

加薪 MaxSizeExceeded 如果从套接字读取的字节数超过此值,则。

process()[源代码]

根据请求实体的Content-Type处理请求实体。

class cherrypy._cpreqbody.SizedReader(fp, length, maxbytes, bufsize=8192, has_trailers=False)[源代码]

基类:object

finish()[源代码]
read(size=None, fp_out=None)[源代码]

从请求正文读取字节,并将其返回或写入文件。

从套接字读取小于或等于‘size’参数的字节数。在self.bytes_read中跟踪读取的实际字节数。当1)客户端发送的字节较少,2)“Content-Length”请求报头指定的字节少于请求的字节,或3)读取的字节数超过self.maxbytes(在这种情况下,引发413)时,该数字可以小于“size”。

如果‘fp_out’参数为NONE(默认值),则在单个字节字符串中返回读取的所有字节。

如果‘fp_out’参数不是NONE,则它必须是支持‘WRITE’方法的类似文件的对象;所有读取的字节都将写入FP,并且不返回NONE。

readline(size=None)[源代码]

从请求正文中读取一行并返回它。

readlines(sizehint=None)[源代码]

从请求正文中读取行并返回它们。

cherrypy._cpreqbody._old_process_multipart(entity)[源代码]

3.2及更低版本的行为。已弃用,将在3.3中进行更改。

cherrypy._cpreqbody.process_multipart(entity)[源代码]

将所有多部分读取为实体.part。

cherrypy._cpreqbody.process_multipart_form_data(entity)[源代码]

将所有多部分/表单数据部分读取到entity.part或entity.params中。

cherrypy._cpreqbody.process_urlencoded(entity)[源代码]

将application/x-www-form-urlencode数据读取到entity.params中。

cherrypy._cpreqbody.unquote_plus(bs)[源代码]

urllib.parse.unQUOTE_PLUS的字节版本。