wsgirf-WSGI功能及参考实现

源码:Lib/wsgiref

Web服务器网关接口(Web Server Gateway Interface, WSGI),是用Python写的一个服务器软件和web应用之间的通用接口。使用通用接口,能够使同一个应用方便的被不同过的web服务器调用。

只有web服务器和软件框架作者需要知道WSGI设计的细节和极端情况。你只需要安装一个WSGI应用或者用现有框架写一个web应用,并不需要知道WSGI的全部细节。

wsgirefWSGI细则的一个参考实现,用于给web服务器和框架提供WSGI支持。它提供了处理WSGI环境变量、response头和WSGI服务器基类的功能,一个服务于WSGI应用的HTTP服务器demo,以及检测WSGI服务器和应用是否和WSGI细则(PEP 3333)是否一致的验证工具。

wsgi官网获取更多信息和相关教程。

wsgiref.util - WSGI环境工具

本模块提供了一些列用于WSGI环境的适用功能。 根据PEP 3333WSGI环境是一个包含HTTP请求变量的字典。所有接受environ参数的函数都预期接受一个兼容于WSGI的字典。详见PEP 3333

wsgiref.util.guess_scheme(environ)

通过检查环境变量中的HTTPS,返回wsgi.url_schemehttp还是https
这个函数用于,创建一个包装CGI或者FastCGI协议的网关。一般来说,提供这些协议的服务器,当使用SSL时,会提供一个值为"1", "yes"或者"on"的HTTPS变量。如果找到了,这个函数返回'https';否则,返回'http'。

wsgiref.util.request_uri(environ, include_query=True)

返回请求的URI,可选参数决定是否返回查询字符串,使用PEP 3333中的"URL Reconstruction"算法。

wsgiref.util.application_uri(environ)

request_uri方法类似,除了忽略PATH_INFO 还有QUERY_STRING变量。返回结果为发起请求的应用对象的基地址(base uri)。

wsgiref.util.shift_pathi_info(environ)

将环境变量中PAHT_INFO移动一个名字到SCRIPT_NAME,并返回。环境变量会被原地修改,如果你要保存原始值,存一个备份 。
如果PAHT_INFO中没有剩余的路径节段,返回None
一般来说,这一例行程序用于处理请求URI的每一部分,例如把路径作为一系列字典键值进行处理。这一例行程序,修改传入的环境变量,使其用于激活目标URI的WSGI应用。比如,在路径/foo上有一个WSGI应用,请求URI为/foo/bar/baz/foo处的WSGI应用调用shift_path_info(),将会得到"bar",环境变量会被更新,使其传向/foo/bar/处的WSGI应用。也就是说SCRIPT_NAME/foo变为/foo/barPATH_INFO/bar/baz变为/baz
当路径仅为"/"时,该例行程序返回空字符串,并在SCRIPT_NAME处添加末尾斜杠。尽管空路径片段一般都被忽略了。但SCRIPT_NAME一般不以斜杠结束。故意这样设计,是为了让应用在做对象遍历时,能够区分/x/x/这两个不同的路径。

# 源码
# https://github.com/python/cpython/blob/master/Lib/wsgiref/util.py#L102
if not name and not script_name.endswith('/'):
script_name += '/'

wsgiref.util.setup_testing_defaults(environ)

为了测试而更新环境变量。

这个例行程序为WSGI添加各种参数,包括HTTP_HOST, SERVER_NAME, SERVER_PORT, REQUESTS_METHOD, SCRIPT_NAME。以及PEP 3333中顶以的所有wsgi.*变量。只提供默认值,不替代现有值。

这个理性城市,是为了建立一个环境,让WSGI和应用的单元测试变得更简单。不应该应用在真实的WSGI服务器上,因为数据都是假的。

from wsgiref.util import setup_testing_defaults
from wsgiref.simple_server import make_server # A relatively simple WSGI application. It's going to print out the
# environment dictionary after being updated by setup_testing_defaults
def simple_app(environ, start_response):
# 创建虚假环境
setup_testing_defaults(environ) status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')] # 发送头部
start_response(status, headers) ret = [("%s: %s\n" % (key, value)).encode("utf-8")
for key, value in environ.items()]
return ret # 这行代码我在3.6.1下运行会出错,make_server不支持上下文管理?
# 把with 语句改成普通的语句好像就没问题了。
with make_server('', 8000, simple_app) as httpd:
print("Serving on port 8000...")
httpd.serve_forever()

除了上述函数,wsgiref.util还提供了其他各种功能。

wsgiref.util.is_hop_by_hop(header_name)

根据[RFC 2616](https://tools.ietf.org/html/rfc2616.html),如果`header_name`是`"Hop-by-Hop"`返回True.

wsgiref.util.FileWrapper(filelike, blksize=8192)

一个把类文件对象转变为成迭代器的包装器。结果支持`__getitem__()`和`__iter__()`。当迭代遍历这个对象时,`blksize`参数会被重复地传给类文件对象地`read()`方法,获取产生的字节。当`read()`产生空字节时,迭代结束。
如果这个类文件对象有`close()`方法,返回的对象也有`close()`方法,当被调用时,会激活类文件对象的`close()`方法。
from io import StringIO
from wsgiref.util import FileWrapper # We're using a StringIO-buffer for as the file-like object
filelike = StringIO("This is an example file-like object"*10)
wrapper = FileWrapper(filelike, blksize=5) for chunk in wrapper:
print(chunk)

wsgi.headers WSGI response 头工具

本模块只提供一个类:Headers。使用(mapping-like interface)映射接口, 方便操作地操作WSGI地响应头。

wsgiref.headers.Headers([headers])

创建一个映射对象包装headersheaders,必须是按照PEP 3333中所规定地键值元组列表。默认值时一个空列表。】

Headers对象支持映射操作,包括__getitem()get(), __setitem()setdefault()__delitem(), 以及__contain__()。key是name,值是该name下的第一个值。

与字典不同,在你试图删除或者get一个不存在key时,Headers对象不会抛出异常。Headers的长度等于它items()的长度,

bytes()函数,返回一个格式化的字符串,用于传输HTTP响应头。每个头占一行,用冒号和控开关白分割。行为时回车+换行。结尾是一个空行

get_all(name)

返回对应name下所有的值

返回顺序为他们在最初的头中的位置,或者他们被添加进实例的顺序。可能会重复。

add_header(name, value, **_params)

添加一个头,通过关键词参数可以添加MIME参数。

在参数名里的下划线会被转换成连接符。因为连接符在python标识符中不合法,但在MIME参数中有很多连接符。

wsgiref.simple_server一个简单的WSGI HTTP服务器

本模块提供了一个简单的基于http.server的,可服务于WSGI应用的HTTP服务器。每一个服务器实例,在一个给定的主机和端口上服务于一个WSGI应用。如果你想在一个主机和端口上,服务于多个应用,你应当创建一个WSGI应用,解析PATH_INFO决定对于每个请求,应该选择哪个应用。

wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer, handle_class=WSGIRequestHandler)

在指定host和port上,创建一个新的WSGI服务器,接受来自app的连接。返回值是传入的server_class的一个实例。并会使用handler_class处理requests。app参数必须是一个符合PEP 3333定义的WSGI应用对象。

wsgirfe.simple_server.demo_app(environ, start_response)

本函数是一个小而完全的WSGI程序,返回一个包含"Hello world!"和环境变量k-v值对的文本页。用于确认WSGI服务器能够争取的处理WSGI程序。

wsgiref.simple_server.WSGIServer(server_address, RequestsHandlerClass)

创建一个WSGISever实例,server_address应当是(host, port)元组,RequestHandlerClass应当是http.server.BasedHTTPRequestHandler的子类,用于处理requests。

你不需要正式调用构造器,因为make_server()函数会帮你处理细节。

WSGIServerhttp.server.HTTPServer的子类,所以继承了其方法,如:serve_forever()handle_request()WSGIServer同时也提供了一些WSGI专有的方法。比如:

set_app(application)

设置一个可调用应用,作为接收requests的WSGI应用。

get_app()

返回目前设置的可调用应用。

一般来说,你不要调用这些额外的方法。 set_app()一般有make_server()调用,get_app()主要是为了requests handler实例而存在。

wsgiref.simple_server.WSGIRequestHandler(reqeust, client_address, server)

对于给定的request(例如,一个socket), client_address (一个(host, port)元组)server,创建一个HTTP handler。

你不需要直接创建这个类的实例,他们会由WSGIServer对象按需创建。单你可以创建一个该类的子类,作为handler_class参数,传给make_server()函数。以下为一些在子类中可能相关的需要重写的函数。

get_environ()

返回一个包含WSGI环境的字典。默认设置返回WSGIServer对象的base_environ字典属性,并加上来自HTTP request的各种头部。每次调用这个方法,都会放回一个新的字典,包含各种PEP 3333中规定的CGI环境变量。

get_stderr()

返回被用作wsgi.errors流的对象。默认设置返回sys.stderr

handle()

处理HTTP请求,默认这是使用wsgiref.hanlder类创建一个handler实例,执行真实的WSGI应用接口。

wsgirref.validate WSGI一致性检查器

当创建新的WSGI应用对象、框架、服务器和中间件时,用wsgiref.validate检查新代码是否可用是非常有用过的。本模块提供了一个能创建WSGI应用对象的函数,使WSGI服务器和WSGI应用对象能够正常通信,检查两侧协议的一致性。

注意这个应用不保证完全符合PEP 3333。这个模块不报错,不意味着肯定没错。但是,如果这个模块报错,就意味着肯定有错误。不是100%兼容。

这个模块基于Python Paste

wsgiref.validate.validator(application)`

包装application并返回一个新的WSGI应用对象,返回的应用将会把所有的请求发送给最初的应用。并且检查这个应用和启动它的服务器是否遵循WSGI规则和RFC 2616

任何检测到的不一致的结果,都会抛出一个AssertionError。但,如何处理这些异常取决于服务器。比如,wsgiref.simple_server和提前基于wsgiref.handlers的服务器,会直接输出错误信息,将回溯信息输出到sys.stderr或者其他错误流中。

这个包装器也可能用warning模块指明那些有问题的,但不完全违反PEP 3333的行为。除非用Python命令行选项或者是warning的api禁止,这些细心会被输出至sys.stderr

wsgirf.handlers 服务器/网管基类

这个模块提供了配置WSGI服务器和网关的基类。这些基类处理了大部分与一个WSGI应用之间的通信,只要给与了他们一个CGI样的环境,以及输入/输出及错误流。

wsgiref.hanlder.CGIHandler

通过sys.stdin, sys.stdout, sys.stderros.environ唤起CGI。当你想要通过一个CGI脚本运行一个WSGI程序时很有用。你可以使用CGIHandler().run(app)

这个类是BaseCGIHandler的子类,并将wsgi.run()=True, wsgi.multithread=False, wsgi.multiprocess=True,并使用sysos获取必要的CGI流和环境。(参见CGI部分和前驱知识)

wsgiref.handler.IISCGIHandler

在微软的IIS服务器上激活CGIHandler

wsgiref.handlers.BaseCGIHandler()

CGIHandler类 类似。

wsgiref.handlers.BaseHandler

一个抽象类。每个实例处理一个HTTP请求。尽管原则上你可以创建一个子类,从而能被多个请求服用。

只有一个方法能被外部调用。

run(app)

通读Python官方文档之wsgiref(未完成)的更多相关文章

  1. 通读Python官方文档之cgi

    cgi 通用网关接口 前驱知识 网关协议学习:CGI.FastCGI.WSGI 简单点说: web服务器接受请求,启动CGI:CGI接受请求,处理,返回给服务器:服务器返回给用户 cgi效率不高,每次 ...

  2. 通读Python官方文档之cgitb

    cgitb CGI脚本异常管理 源代码:Lib/cgitb.py cgitb模块为Python脚本提供了一个特殊的异常管理器.名字有点误导人,它最初设计是为了以HTML格式展示cgi脚本的大量异常信息 ...

  3. 别开心太早,Python 官方文档的翻译差远了

    近几天,很多公众号发布了 Python 官方文档的消息.然而,一个特别奇怪的现象就发生了,让人啼笑皆非. Python 文档的中文翻译工作一直是“默默无闻”,几个月前,我还吐槽过这件事<再聊聊P ...

  4. 阅读Python官方文档心得

    我会每天都阅读一些python的官方文档,并每天更新心得体会. -------------------------------------------------2016.12.08--------- ...

  5. [Python3]Python官方文档-Python Manuals

    简介 一般情况下,初学者都不愿意直接去浏览Python Manuals,即Python自带的官方文档.尤其是只有英文版的情况下,初学者更加不会去使用该官方文档了. 在这里笔者强力推荐初学者经常学会使用 ...

  6. PEP 324 subprocess 新的进程模块 -- Python官方文档译文 [原创]

    PEP 324 -- subprocess 新的进程模块(subprocess - New process module) 英文原文:https://www.python.org/dev/peps/p ...

  7. python官方文档

    Tutorialstart here Library Referencekeep this under your pillow Language Referencedescribes syntax a ...

  8. Python 官方文档解读(2):threading 模块

    使用 Python 可以编写多线程程序,注意,这并不是说程序能在多个 CPU 核上跑.如果你想这么做,可以看看关于 Python 并行计算的,比如官方 Wiki. Python 线程的主要应用场景是一 ...

  9. Python 官方文档解读(1):66 个内置函数

    Python 解释器 (CPython 3.7)内置有 66 个函数,这些函数在任何时刻都是可用的.此文是为了对这 66 个函数进行简单的梳理,便于以后可能用到它们时能想到. 1. abs(x) 返回 ...

随机推荐

  1. (第一章第三部分)TensorFlow框架之会话

    系列博客链接: (一)TensorFlow框架介绍:https://www.cnblogs.com/kongweisi/p/11038395.html (二)TensorFlow框架之图与Tensor ...

  2. (二)目标检测算法之R-CNN

    系列博客链接: (一)目标检测概述 https://www.cnblogs.com/kongweisi/p/10894415.html 概述: 1.目标检测-Overfeat模型 2.目标检测-R-C ...

  3. JZ-058-对称的二叉树

    对称的二叉树 题目描述 请实现一个函数,用来判断一棵二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 题目链接: 对称的二叉树 代码 /** * 标题:对称的二叉树 ...

  4. java的基本类型和类型转化

    1.八种基本数据类型: byte-short--int --long--float--double--char 2.八种基本类型所占字节空间 一.int 整数的直接量为int: 存储范围为:- -21 ...

  5. Net中委托之一

    1.委托的用法 委托是一种特殊的类型 a. 委托可以类外定义,也可以在类里面定义 b. 委托的操作步骤 1.委托的声明 2.委托的实例化 3.委托的调用 2.委托实例 amespace MyDeleg ...

  6. Hibernate学习笔记(一)-->数据库单表操作

    Hibernate框架是一个全ORM映射框架,是一个非常流行的数据库操作框架之一,现在比较流行的还有MyBatis半ORM映射框架 在MyEclipse IDE开发工具中,可以很轻松的搭建Hibern ...

  7. 七天接手react项目 系列 —— react 路由

    其他章节请看: 七天接手react项目 系列 react 路由 本篇首先讲解路由原理,接着以一个基础路由示例为起点讲述路由最基础的知识,然后讲解嵌套路由.路由传参,最后讲解路由组件和一般组件的区别,以 ...

  8. 内网渗透----Linux信息收集整理

    一.基础信息收集 1.查看系统类型 cat /etc/issue cat /etc/*-release cat /etc/lsb-release cat /etc/redhat-release 2.内 ...

  9. [应用软件] VMware Workstation 12.0.0 Pro 正式版下载【附注册机+注册码】

    软件信息 软件名称: VMware Workstation 软件版本: 12 软件大小: 300 MB 软件语言: 简体中文 更新时间: - 软件授权: 免费 软件类别: 安装版 运行环境: WinX ...

  10. 重定向(Redirect)和请求转发(Forward)

    一.调用方式 我们知道,在servlet中调用转发.重定向的语句如下: request.getRequestDispatcher("new.jsp").forward(reques ...