werkzeug源码解析 Request Response
datastructures
- datastructures.py单元定义了基本类型
- 为了实现不可修改,定义了一系列Immutable类,通过覆盖默认的魔术方法(__delitem__,__setitem__等)使修改时抛异常
Request
- 继承关系werkzeug.wrappers.request.Request–>werkzeug.sansio.request.Request
werkzeug.sansio.request.Request
-
方法基本是对wsgi中environ进行解析,使用时更方便(url,access_route,cookies,host,mimetype,user_agent,args等)
# werkzeug.wrappers.request.Request初始化__init__调用super(werkzeug.sansio.request.Request)时入参 def __init__( self, environ: "WSGIEnvironment", populate_request: bool = True, shallow: bool = False, ) -> None: super().__init__( method=environ.get("REQUEST_METHOD", "GET"), scheme=environ.get("wsgi.url_scheme", "http"), server=_get_server(environ), root_path=_wsgi_decoding_dance( environ.get("SCRIPT_NAME") or "", self.charset, self.encoding_errors ), path=_wsgi_decoding_dance( environ.get("PATH_INFO") or "", self.charset, self.encoding_errors ), query_string=environ.get("QUERY_STRING", "").encode("latin1"), headers=EnvironHeaders(environ), remote_addr=environ.get("REMOTE_ADDR"), ) ...
-
方法大多返回不可修改对象ImmutableMultiDict或ImmutableList
werkzeug.wrappers.request.Request
-
根据content-type解析http/https的body(environ[“wsgi.input”])
from werkzeug.wrappers import Request, Response from werkzeug.test import create_environ environ = create_environ(path='/foo', base_url='http://localhost:8080/', query_string="id=22&name=aaa", content_type="application/json", json={ 'param1': '666', 'param2': 'kkk'}) request = Request(environ) for key in list(request.__dict__.keys()): print(key, getattr(request, key))
Response
- 继承关系werkzeug.wrappers.response.Response–>werkzeug.sansio.response.Response
werkzeug.sansio.response.Response
- 和werkzeug.sansio.request.Request对应,封装http协议响应控制,status,headers(主要处理mimetype,content_type)
- 属性status和status_code是同步的,存储在_status, _status_code
werkzeug.sansio.response.Response
- 根据headers的content_type处理返回http内容body,存储在response
- Response是由业务绝对内容的,所以header和body必须在__init__中自己指定,不能像Request从environ解析且不可修改,至于get_wsgi_headers,get_app_iter等environ是用来确定Location等内容
Request和Response配合封装wsgi
- werkzeug.wrappers.request.Request.application和werkzeu