深入WSGI,并按样例实现一个
感觉WSGI确实和SERVLET相似,为PYTHON提供了运行和管理环境。WSGI服务器和PYTHON的WEB框架一起,实现WEB响应。
步骤:
- 首先,服务器启动并加载一个由Web框架/应用提供的可调用的’application’
- 然后,服务器读取请求
- 然后,服务器解析它
- 然后,服务器使用请求的数据创建了一个’environ’字典
- 然后,服务器使用’environ’字典和’start_response’做为参数调用’application’,并拿到返回的响应体。
- 然后,服务器使用调用’application’返回的数据,由’start_response’设置的状态和响应头,来构造HTTP响应。
- 最终,服务器把HTTP响应传回给户端。
代码(别小看它,启动DJANGO的APP都可以的,但DJANGO必须提供一个WSGI供它调用APP):
# Tested
import socket
import StringIO
import sys
class WSGIServer(object):
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
request_queue_size = 1
def __init__(self, server_address):
# Create a listening socket
self.listen_socket = listen_socket = socket.socket(
self.address_family,
self.socket_type
)
# Allow to reuse the same address
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind
listen_socket.bind(server_address)
# Activate
listen_socket.listen(self.request_queue_size)
# Get server host name and port
host, port = self.listen_socket.getsockname()[:2]
self.server_name = socket.getfqdn(host)
self.server_port = port
# Return headers set by Web framework/Web application
self.headers_set = []
def set_app(self, application):
self.application = application
def serve_forever(self):
listen_socket = self.listen_socket
while True:
# New client connection
self.client_connection, client_address = listen_socket.accept()
# Handle one request and close the client connection. Then
# loop over to wait for another client connection
self.handle_one_request()
def handle_one_request(self):
self.request_data = request_data = self.client_connection.recv(1024)
# Print formatted request data a la 'curl -v'
print(''.join(
'> {line}n'.format(line=line)
for line in request_data.splitlines()
))
self.parse_request(request_data)
# Construct environment dictionary using request data
env = self.get_environ()
# It's time to call our application callable and get
# back a result that will become HTTP response body
result = self.application(env, self.start_response)
# Construct a response and send it back to the client
self.finish_response(result)
def parse_request(self, text):
request_line = text.splitlines()[0]
request_line = request_line.rstrip('rn')
# Break down the request line into components
(self.request_method, # GET
self.path, # /hello
self.request_version # HTTP/1.1
) = request_line.split()
def get_environ(self):
env = {}
# The following code snippet does not follow PEP8 conventions
# but it's formatted the way it is for demonstration purposes
# to emphasize the required variables and their values
#
# Required WSGI variables
env['wsgi.version'] = (1, 0)
env['wsgi.url_scheme'] = 'http'
env['wsgi.input'] = StringIO.StringIO(self.request_data)
env['wsgi.errors'] = sys.stderr
env['wsgi.multithread'] = False
env['wsgi.multiprocess'] = False
env['wsgi.run_once'] = False
# Required CGI variables
env['REQUEST_METHOD'] = self.request_method # GET
env['PATH_INFO'] = self.path # /hello
env['SERVER_NAME'] = self.server_name # localhost
env[
return env
def start_response(self, status, response_headers, exc_info=None):
# Add necessary server headers
server_headers = [
('Date', 'Tue, 31 Mar 2015 12:54:48 GMT'),
('Server', 'WSGIServer 0.2'),
]
self.headers_set = [status, response_headers + server_headers]
# To adhere to WSGI specification the start_response must return
# a 'write' callable. We simplicity's sake we'll ignore that detail
# for now.
# return self.finish_response
def finish_response(self, result):
try:
status, response_headers = self.headers_set
response = 'HTTP/1.1 {status}rn'.format(status=status)
for header in response_headers:
response += '{0}: {1}rn'.format(*header)
response += 'rn'
for data in result:
response += data
# Print formatted response data a la 'curl -v'
print(''.join(
'> {line}n'.format(line=line)
for line in response.splitlines()
))
self.client_connection.sendall(response)
finally:
self.client_connection.close()
SERVER_ADDRESS = (HOST, PORT) = '', 8888
def make_server(server_address, application):
server = WSGIServer(server_address)
server.set_app(application)
return server
if __name__ == '__main__':
if len(sys.argv) < 2:
sys.exit('Provide a WSGI application object as module:callable')
app_path = sys.argv[1]
module, application = app_path.split(':')
module = __import__(module)
application = getattr(module, application)
httpd = make_server(SERVER_ADDRESS, application)
print('WSGIServer: Serving HTTP on port {port} ...n'.format(port=PORT))
httpd.serve_forever()
def app(environ, start_response):
status = '200 OK'
response_headers = [('Content-Type', 'text/plain')]
start_response(status, response_headers)
return ['Hello world from a simple WSGI application!n']
截图:


深入WSGI,并按样例实现一个的更多相关文章
- Lambda 表达式的演示样例-来源(MSDN)
本文演示怎样在你的程序中使用 lambda 表达式. 有关 lambda 表达式的概述.请參阅 C++ 中的 Lambda 表达式. 有关 lambda 表达式结构的具体信息,请參阅 Lambda 表 ...
- 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门演示样例
一. 工作区域具体解释 1. Scence视图 (场景设计面板) scence视图简单介绍 : 展示创建的游戏对象, 能够对全部的游戏对象进行 移动, 操作 和 放置; -- 演示样例 : 创建一个球 ...
- 基于Spring-SpringMVC-Mybatis的简单样例
复习下 好久没搞过撸过代码了! 这个样例包括一个完整的增删改查! 源代码地址http://download.csdn.net/detail/wangdianyong/8909903
- 《MySQL必知必会》学习笔记——附录B 样例表
附录B 样例表 本附录简要描述本书中所用的表及它们的用途. 编写SQL语句需要对基础数据库的设计有良好的理解.不知道什么信息存储在什么表中,表之间如何关联以及行内数据如何分解,是不可能编写出高效的SQ ...
- Swift - 自动布局库SnapKit的使用详解4(样例1:实现一个登录页面)
前面的几篇文章讲解了自动布局库SnapKit的使用方法.本文通过一个完整的样例(登录页面)来演示在实际项目中如何使用SnapKit来实现自动化布局的.1,效果图如下
- socket编程——一个简单的样例
从一个简单的使用TCP样例開始socket编程,其基本过程例如以下: server client ++ ...
- JBoss 系列九十六:JBoss MSC - 简介及一个简单演示样例
什么是 JBoss MSC JBoss MSC 即 JBoss Modular Service Container,是第三代 JBoss 产品 JBoss 7和WildFfly的内核,JBoss MS ...
- VB.net数据库编程(03):一个SQLserver连接查询的简单样例
这个样例,因为在ADO.net入门已经专门学了,再次进行复习 一下. 主要掌握连接字串的情况. 过程就是: 1.引用System.Data.SqlClient.而Access中引用 的是System. ...
- PHP初学者如何搭建环境,并在本地服务器(or云端服务器)运行自己的第一个PHP样例
页面底部有PHP代码样例供测试使用. 1.PHP开发,你需要什么? 1)开发代码的工具,可以用IDE名字叫做phpDesigner.当然也可以临时用记事本代替,记得文件扩展名为.php 2)服务器(本 ...
随机推荐
- highcharts 去掉右下角链接
去掉右下角的highcharts.com链接需要加入以下代码: credits: { enabled:false }, 如果不设置,那么默认为显示.
- 初步接触html心得
接触HTML大概有七天,做一下小总结,过过记忆. html大致可分为三部分:Dtd头.Head.Body三大部分. Dtd头:是用于浏览器编辑的,也就是俗话说的给电脑看的的东西. Head:内细分下大 ...
- 【高级JEE技术】JMX
JMX即Java Manager Extentin(java 管理扩展)一种动态改变javabean属性值的技术,具体应用场景可以有很多.比如使用JMX作为线上应用的开关,在做一些新老系统改造的时候 ...
- ASP实现随机提取数据库记录例
<% "一个从数据库中随机读取纪录的例子 Set Rs1=server.CreateObject ("adodb.recordset") Set Rs=server ...
- GIT学习(二)
学习地址: http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 常用git命令: 1. ...
- C#开发微信门户及应用-使用地理位置扩展相关应用
C#开发微信门户及应用-使用地理位置扩展相关应用 我们知道,地理位置信息可以用来做很多相关的应用,除了我们可以知道用户所在的位置,还可以关联出一些地理位置的应用,如天气,热映影片,附近景点,附近影院, ...
- SQL Server(函数) 关键字的使用 三
三, 函数关键字 -- 使用介绍 28, Function的使用(Function的内建 SQL函数)? 内建 SQL 函数的语法是: SELECT function(列) FROM 表) 29, a ...
- 如何入侵Linux操作系统
我发现了一个网站,于是常规入侵.很好,它的FINGER开着,于是我编了一个SHELL,aaa帐号试到zzz(by the way,这是我发现的一个网上规律,那就是帐号的长度与口令的强度成正比, 如果一 ...
- html-----020----事件
html事件 <body> <a href="http://www.cctv.com" accesskey="k" target=" ...
- CSS高度塌陷
问题描述:当父元素只包含浮动的元素的时候,且父元素没有设置高度,如果父元素设置了边框border,那么看起来子元素不在父元素之内. 比如这样: html: <div id="paren ...