WSGI 协议
在Python Web开发时经常会遇到WSGI,所以WSGI到底是什么呢?本文我们一起来揭开WSGI神秘的面纱!
先来看一下WSGI的介绍:
全称Python Web Server Gateway Interface,指定了web服务器和Python web应用或web框架之间的标准接口,以提高web应用在一系列web服务器间的移植性。
从以上介绍我们可以看出:
WSGI是一套接口标准协议/规范;
通信(作用)区间是Web服务器和Python Web应用程序之间;
目的是制定标准,以保证不同Web服务器可以和不同的Python程序之间相互通信
你可能会问,为什么需要WSGI?
首先,我们明确一下web应用处理请求的具体流程:
用户操作操作浏览器发送请求;
请求转发至对应的web服务器
web服务器将请求转交给web应用程序,web应用程序处理请求
web应用将请求结果返回给web服务器,由web服务器返回用户响应结果
浏览器收到响应,向用户展示
可以看到,请求时Web服务器需要和web应用程序进行通信,但是web服务器有很多种啊,Python web应用开发框架也对应多种啊,所以WSGI应运而生,定义了一套通信标准。试想一下,如果不统一标准的话,就会存在Web框架和Web服务器数据无法匹配的情况,那么开发就会受到限制,这显然不合理的。
既然定义了标准,那么WSGI的标准或规范是?
web服务器在将请求转交给web应用程序之前,需要先将http报文转换为WSGI规定的格式。
WSGI规定,Web程序必须有一个可调用对象,且该可调用对象接收两个参数,返回一个可迭代对象:
environ:字典,包含请求的所有信息
start_response:在可调用对象中调用的函数,用来发起响应,参数包括状态码,headers等
通过以上学习,一起实现一个简单WSGI服务吧
首先我们编写一个符合WSGI协议标准的http处理函数
def application(env, start_response):
start_response("200 OK", [("Content-Type", "text/html;charset=utf-8")])
file_name = env["PATH_INFO"]
if file_name == "/index.py":
return "这是主页"
elif file_name == "/login.py":
return "这个是登录页"
else:
return "Hello World"
Web服务器
import socket
import mini_frame
class WSGIServer(object):
def service_client(self, new_socket):
# 接受浏览器发送过来的请求
# get / http/1.1
request = new_socket.recv(1024).decode("utf-8")
req_lines = request.splitlines()
print("")
print(">" * 20)
print(req_lines)
ret = re.match(r"[^/]+(/[^ ]*)", req_lines[0])
file_name = ret.group(1)
env = dict()
env["PATH_INFO"] = file_name
body = self.application(env, self.set_response_header)
header = "HTTP/1.1 %s\r\n" % self.status
for temp in self.headers:
header += "%s:%s\r\n" % (temp[0], temp[1])
header += "\r\n"
response = header + body
new_socket.send(response.encode("utf-8"))
new_socket.close()
def set_response_header(self, starts, headers):
self.status = starts
self.headers = [("Server","mini_web v8.8")]
self.headers += headers
def main():
# 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
# 绑定
tcp_server_socket.bind(("",7890))
# 变为监听套接字
tcp_server_socket.listen(128)
while True:
# 等待新的客户端连接
new_socket, client_addr = tcp_server_socket.accept()
# 为这个客户端服务
wsgi_server = WSGIServer()
wsgi_server.service_client(new_socket)
# 关闭监听套接字
tcp_server_socket.close()
if __name__ == '__main__':
main()
上一篇: 用友U8 采购订单列表的SQL 语句
下一篇: WSGI协议