简介

WSGI具体是什么?
WSGI-应用程序
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
HELLO_WORLD = b"Hello world!\n"# callable functiondef simple_app(environ, start_response): """Simplest possible application object""" status = ‘200 OK‘ response_headers = [(‘Content-type‘, ‘text/plain‘)] start_response(status, response_headers) return [HELLO_WORLD]# callable classclass AppClass: """Produce the same output, but using a class (Note: ‘AppClass‘ is the "application" here, so calling it returns an instance of ‘AppClass‘, which is then the iterable return value of the "application callable" as required by the spec. If we wanted to use *instances* of ‘AppClass‘ as application objects instead, we would have to implement a ‘__call__‘ method, which would be invoked to execute the application, and we would need to create an instance for use by the server or gateway. """ def __init__(self, environ, start_response): self.environ = environ self.start = start_response def __iter__(self): status = ‘200 OK‘ response_headers = [(‘Content-type‘, ‘text/plain‘)] self.start(status, response_headers) yield HELLO_WORLD# callable objectclass ApplicationObj(object): def __call__(self, environ, start_response): return [HELL_WORLD] |
|
1
2
3
|
class Index(View): def get(self): return ‘Hello world‘ |
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# lib/python3.7/site-packages/django/core/handlers/wsgi.py 146 lineclass WSGIHandler(base.BaseHandler): request_class = WSGIRequest def __init__(self, *args, **kwargs): super(WSGIHandler, self).__init__(*args, **kwargs) self.load_middleware() def __call__(self, environ, start_response): set_script_prefix(get_script_name(environ)) signals.request_started.send(sender=self.__class__, environ=environ) request = self.request_class(environ) response = self.get_response(request) response._handler_class = self.__class__ status = ‘%d %s‘ % (response.status_code, response.reason_phrase) response_headers = [(str(k), str(v)) for k, v in response.items()] for c in response.cookies.values(): response_headers.append((str(‘Set-Cookie‘), str(c.output(header=‘‘)))) start_response(force_str(status), response_headers) if getattr(response, ‘file_to_stream‘, None) is not None and environ.get(‘wsgi.file_wrapper‘): response = environ[‘wsgi.file_wrapper‘](response.file_to_stream) return response |
WSGI-服务器程序
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
# 具体见PEP333规范def run_with_cgi(application): environ = {} def write(data): pass def start_response(status, response_headers, exc_info=None): pass # 调用应用程序 result = application(environ, start_response) try: for data in result: if data: # don‘t send headers until body appears write(data) if not headers_sent: write(‘‘) # send headers now if body was empty finally: if hasattr(result, ‘close‘): result.close() |
WSGI-Middleware
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
# URL Routing middlewaredef urlrouting(url_app_mapping): def midware_app(environ, start_response): url = environ[‘PATH_INFO‘] app = url_app_mapping[url] result = app(environ, start_response) return result return midware_app‘‘‘中间件作用说明:服务器拿到了客户端请求的URL, 不同的URL需要交由不同的函数处理,这个功能叫做 URL Routing,这个功能就可以放在二者中间实现,这个中间层就是 middleware。‘‘‘ |
WSGI-详解
应用程序
2个参数名称不是固定的,可以随便起,不过为了表达清楚所以一般都叫 environ和 start_response
服务器程序
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
# server programmeddef run(application): environ = {} # set environ def write(data): pass def start_response(status, response_headers, exc_info=None): return write try: result = application(environ, start_response) finally: if hasattr(result, ‘close‘): result.close() if hasattr(result, ‘__len__‘): # result must be accumulated pass for data in result: write(data)HELLO_WORLD = b"Hello world!\n" # callable functiondef application(environ, start_response): status = ‘200 OK‘ response_headers = [(‘Content-type‘, ‘text/plain‘)] start_response(status, response_headers) return [HELLO_WORLD] |
environ变量
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
REQUEST_METHOD = ‘GET‘SCRIPT_NAME = ‘‘PATH_INFO = ‘/xyz‘QUERY_STRING = ‘abc‘CONTENT_TYPE = ‘text/plain‘CONTENT_LENGTH = ‘‘SERVER_NAME = ‘minix-ubuntu-desktop‘SERVER_PORT = ‘8000‘SERVER_PROTOCOL = ‘HTTP/1.1‘ HTTP_ACCEPT = ‘text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8‘HTTP_ACCEPT_ENCODING = ‘gzip,deflate,sdch‘HTTP_ACCEPT_LANGUAGE = ‘en-US,en;q=0.8,zh;q=0.6,zh-CN;q=0.4,zh-TW;q=0.2‘HTTP_CONNECTION = ‘keep-alive‘HTTP_HOST = ‘localhost:8000‘HTTP_USER_AGENT = ‘Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36‘ |
Unicode
原文:https://www.cnblogs.com/heimaguangzhou/p/11790402.html