简介
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 function def 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 class class 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 object class 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 line class 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 middleware def 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 programmed def 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 function def 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