wsgi
1、简述:
WSGI,是Web Server Gateway Interfae的简称,wsgi是web 服务器与python 应用程序或者框架之间的一个web组件,WSGI更像是一种协议,可以应用在任何一种服务器上面,因此可移植性较强。
WSGI 有两方面含义:其一是服务器或者网关,另外一种含义是应用程序或者框架。(注:有时候也分为三类,作为web中间件)
2、wsgi作为应用程序或者框架
应用程序对象只是一个接受两个参数的 callable 对象而已. 别把术语 “对象” 误解为真的需要一个实例对象: 一个函数, 方法, 类, 所有实现了 call 方法的实例对象都可以用来作为应用程序对象. 应用程序对象必须能够被重复调用, 因为实际上所有 服务器(除了CGI) 都会发出这样的重复的请求.(注意: 虽然我们把它说成是一个 “应用程序” 对象, 但也别误解为应用程序开发者会把 WSGI 当一个 web编程API 来用! 我们假定应用程序开发者仍然使用现有的,高层的框架服务来开发他们的应用程序. WSGI 是一个给框架和服务器开发者用的工具, 并且不会提供对应用程序开发者的直接支持.)这里有两个应用程序对象的例子。
函数形式:
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"]
类形式
类形式
class AppClass:
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!\n"
上面分别用函数和类的形式,都可以输出”hello world”
3、wsgi 作为服务器
服务器 或 getway 每次收到 http客户端 发出的请求都会调用一次相应的 应用程序callable . 举例来说, 这里有一个简单的 CGI getway, 以一个接受一个应用程序对象作为参数的函数来实现的. 值得注意的是这个简单的例子还拥有有限的错误处理功能, 因为未捕捉的异常默认会写到 sys.error 里并被web服务器记录下来.
4、规范细节
应用程序对象必须接受两个固定参数,为了方便说明我们不妨把他们命名为 environ 和 start_response ,但并非必须取这个名字。服务器或gateway必须使用这两个参数来调用应用程序对象 ( 就象上面展示的那样, 像这样调用 result=application(environ,start_response) )
environ 参数是个字典,其中包含的是 CGI 风格的环境变量。这个对象必须是一个 python 内置的字典对象 (不能是其子类、UserDict或其他对字典对象的模仿) ,应用程序可以任意修改这个字典, environ 还应该包含一些 WSGI 需要的特定变量 (在后面的节里还会描述) ,还可以包含一些依据一定的命名规范的服务器特定的扩展变量, 命名规范在后面还会有描述。关于environ 这个字典,其主要的keys值,这里不在赘述。
附:以这个请求为例:http://127.0.0.1/api/test/spur?Name=spur
{
'mod_wsgi.listener_port': '80',
'SERVER_SOFTWARE': 'Apache/2.2.15(CentOS)',
'SCRIPT_NAME': '/api/test/spur',
'mod_wsgi.enable_sendfile': '0',
'mod_wsgi.handler_script': '',
'SERVER_SIGNATURE': '<address>Apache/2.2.15(CentOS)Serverat127.0.0.1Port80</address>\n',
'REQUEST_METHOD': 'GET',
'PATH_INFO': '',
'SERVER_PROTOCOL': 'HTTP/1.1',
'QUERY_STRING': 'Name=spur',
'wsgi.errors': <mod_wsgi.Logobjectat0x7f57243a6d20>,
'CONTENT_LENGTH': '0',
'HTTP_USER_AGENT': 'Python-urllib/2.6',
'HTTP_CONNECTION': 'close',
'SERVER_NAME': '127.0.0.1',
'REMOTE_ADDR': '127.0.0.1',
'mod_wsgi.request_handler': 'wsgi-script',
'apache.version': (2,
2,
15),
'wsgi.url_scheme': 'http',
'mod_wsgi.callable_object': 'application',
'SERVER_PORT': '80',
'wsgi.multiprocess': True,
'SERVER_ADDR': '127.0.0.1',
'DOCUMENT_ROOT': '/var/www/spurtest',
'HTTP_TIMESTRAP': '1515479544',
'mod_wsgi.process_group': '',
'HTTP_CLIENTNAME': 'admin',
'SCRIPT_FILENAME': '/var/www/spur/api/test/index.py',
'HTTP_SIGN': 'd6TDgMFAqMHs0DB4JMpsNse5Tsc=',
'wsgi.input': <mod_wsgi.Inputobjectat0x7f57223b6760>,
'HTTP_HOST': '127.0.0.1',
'wsgi.multithread': False,
'REQUEST_URI': '/api/test/spur?Name=spur',
'mod_wsgi.path_info': '',
'wsgi.file_wrapper': <type'mod_wsgi.FileWrapper'>,
'wsgi.version': (1,
0),
'GATEWAY_INTERFACE': 'CGI/1.1',
'wsgi.run_once': False,
'mod_wsgi.script_name': '/api/test/spur',
'REMOTE_PORT': '39868',
'mod_wsgi.listener_host': '',
'mod_wsgi.version': (4,
4,
13),
'mod_wsgi.script_start': '1515479544403161',
'CONTENT_TYPE': 'application/json;charset=utf-8',
'mod_wsgi.script_reloading': '1',
'mod_wsgi.request_start': '1515479544400407',
'HTTP_ACCEPT_ENCODING': 'identity'
}
参数 start_response 是一个接受两个必需的固定参数和一个可选参数的 callable 对象. 为便于说明, 我们把这三个参数分别命名为: status, response_headers, 和 exc_info, 当然你也可以给他们起其他名字. 应用程序必需使用固定参数调用 start_response (比如: start_response(status,response_headers))
参数 status 是一个形如 “999 Message here” 的表示状态的字符串。而 response_headers 参数是一个描述 http 响应头的列表, 其中每一个元素都是像 (header_name,header_value) 这样的元组。可选的 exc_info 参数会在后面的 start_response() callable 和 错误处理 两节中进行描述,该参数只有在应用程序产生了错误并希望在浏览器上显示错误信息的时候才用得上。
start_response callable 必须返回一个 write(body_data) callable,该 callable 接受一个可选参数:一个将会被作为 http body 一部分输出的字符串. (注意:提供 write() callable 只是为了支持几个现有框架急需的输出API,新的应用程序或框架应尽量避免使用,详细情况请看 Buffering and Streaming 一节。)
当被服务器调用的时候, 应用程序对象必须返回一个能产生零或多个字符串的 iterable , 这可以有好几种实现方法, 比如返回一个字符串的列表,或者应用程序本身就是一个产生字符串的生成器, 或者应用程序本身是一个类 而他的实例是 iterable . 不管它是怎么实现,应用程序对象总是必须返回一个能产生零或多个字符串的 iterable 。
上一篇: SQL注入攻击实例
下一篇: 记录实现Vue带参数调转页面