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报头来填充 name
和 filename
request.body或部件上的属性。
定制处理器¶
您可以为任何特定或主要的MIME类型添加您自己的处理器。只需将其添加到 processors
在以以下速度运行的钩子/工具中插入凹槽 on_start_resource
或 before_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_body
和before_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
如果它是文件的话就是它本身。(在这种情况下,它将具有file
和filename
属性,或者可能是一个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。
- default_content_type = 'application/x-www-form-urlencoded'¶
这定义了一个默认值
Content-Type
在未提供Content-Type标头的情况下使用。空字符串用于RequestBody,这会导致根本不读取或解析请求正文。这是故意的;遗失了Content-Type
HTTP请求实体中的头往好了说是一个错误,往坏了说是一个安全漏洞。但是,对于多部分部件,MIME规范声明没有Content-Type的部件缺省为“Text/Plain”(请参见Part
)。
- filename = None¶
这个
Content-Disposition.filename
标题(如果可用)。
- fp = None¶
可读套接字文件对象。
- headers = None¶
请求/多部分报头名称和值的字典。
这是一份
request.headers
对于request.body
;对于多部分分块,它是该分块的报头集。
- length = None¶
的价值
Content-Length
标头(如果提供)。
- make_file()[源代码]¶
返回一个类似文件的对象,请求正文将被读取到该对象中。
默认情况下,这将返回一个TemporaryFile。根据需要覆盖。另请参阅
cherrypy._cpreqbody.Part.maxrambytes
。
- name = None¶
属性的“name”参数
Content-Disposition
标题(如果有)。
- 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)
- parts = None¶
部件实例列表,如果
Content-Type
主要类型为“多部件”。
- processors = {'application/x-www-form-urlencoded': <function process_urlencoded>, 'multipart': <function process_multipart>, 'multipart/form-data': <function process_multipart_form_data>}¶
处理器方法的内容类型名称字典。
- class cherrypy._cpreqbody.Part(fp, headers, boundary)[源代码]¶
-
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的部件默认为“文本/纯文本”。
- class cherrypy._cpreqbody.RequestBody(fp, headers, params=None, request_params=None)[源代码]¶
-
HTTP请求的实体。
- bufsize = 8192¶
读取套接字时使用的缓冲区大小。
- default_content_type = ''¶
这定义了一个默认值
Content-Type
在未提供Content-Type标头的情况下使用。空字符串用于RequestBody,这会导致根本不读取或解析请求正文。这是故意的;遗失了Content-Type
HTTP请求实体中的头往好了说是一个错误,往坏了说是一个安全漏洞。但是,对于多部分部件,MIME规范声明没有Content-Type的部件缺省为“Text/Plain”(请参见Part
)。
- maxbytes = None¶
加薪
MaxSizeExceeded
如果从套接字读取的字节数超过此值,则。
- class cherrypy._cpreqbody.SizedReader(fp, length, maxbytes, bufsize=8192, has_trailers=False)[源代码]¶
基类:
object
- 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。
- cherrypy._cpreqbody.process_multipart_form_data(entity)[源代码]¶
将所有多部分/表单数据部分读取到entity.part或entity.params中。