wsgi协议

今天来探讨下wsgi协议的用法。
def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return 'Hello World!'
这是一段wsgi协议,application 是这个函数的函数名,这个是不可变的,environ是服务器给框架传数据,使用的是字典(因为要传多个字段),start_response是框架给服务器传的响应头,return是框架给服务器传的响应体。下面来看看wsgi函数的用法。
import socket
import re
import multiprocessing
import mini_06

# 相关的函数的集合
class WebServer(object):
	def service_client(self, new_socket):
		"""为这个客户端返回数据"""

		# 1. 接收浏览器发送过来的请求 ,即http请求
		# GET / HTTP/1.1
		# .....
		request = new_socket.recv(1024).decode("utf-8")
		# print(">>>"*50)
		# print(request)

		request_lines = request.splitlines()
		print("")
		print(">" * 20)
		print(request_lines)

		# GET /index.html HTTP/1.1
		# get post put del
		file_name = ""
		ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
		if ret:
			file_name = ret.group(1)
			# print("*"*50, file_name)
			if file_name == "/":
				file_name = "/index.html"

		# 2. 返回http格式的数据,给浏览器

		# 如果你的路径后缀是.py那么我们代码去返回数据
		if file_name.endswith(".py"):  # 这个就是.py结尾
			# 我们代码去返回数据
			head = "HTTP/1.1 200 OK \r\n"
			# body = "page is show!"
			# content = head + "\r\n" + body

			# 根据不同的路径返回不同的内容
			body = mini_06.application(file_name,self.head_params)

			content = head + "\r\n" + body
			# 发送数据
			new_socket.send(content.encode("utf-8"))
		else:
			# 直接 打开文件
			try:
				f = open("./html" + file_name, "rb")
			except:
				response = "HTTP/1.1 404 NOT FOUND\r\n"
				response += "\r\n"
				response += "------file not found-----"
				new_socket.send(response.encode("utf-8"))
			else:
				html_content = f.read()
				f.close()
				# 2.1 准备发送给浏览器的数据---header
				response = "HTTP/1.1 200 OK\r\n"
				response += "\r\n"
				# 2.2 准备发送给浏览器的数据---boy
				# response += "hahahhah"

				# 将response header发送给浏览器
				new_socket.send(response.encode("utf-8"))
				# 将response body发送给浏览器
				new_socket.send(html_content)

		# 关闭套接
		new_socket.close()

	def run_server(self):
		while True:
			# 4. 等待新客户端的链接
			new_socket, client_addr = self.tcp_server_socket.accept()

			# 5. 为这个客户端服务
			p = multiprocessing.Process(target=self.service_client, args=(new_socket,))
			p.start()

			new_socket.close()

		# 关闭监听套接字
		tcp_server_socket.close()

	def __init__(self):
		# 1. 创建套接字
		self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		# 2. 绑定
		self.tcp_server_socket.bind(("", 7890))
		# 3. 变为监听套接字
		self.tcp_server_socket.listen(128)

	def head_params(self,status,params):
		self.status = status
		self.params = params


def main():
	server = WebServer()
	server.run_server()


if __name__ == "__main__":
	main()

这是一个简单的服务器

def head_params(self,status,params):
		self.status = status
		self.params = params
这段函数就是用来接收start_response框架给服务器传的响应头,函数在哪里定义那么对应的参数就会传过来。
'200 OK', [('Content-Type', 'text/html')]

接收的就是这段代码,当然你需要将body = mini_05.application(file_name)这段调用wsgi协议的代码改为body = mini_06.application(file_name,self.head_params),因为他要接收head_params传过来的值。

                 if file_name.endswith(".py"):  # 这个就是.py结尾
			# 我们代码去返回数据
			# body = "page is show!"
			# content = head + "\r\n" + body

			# 定义传送数据的字典
			service_dict = dict()
			service_dict['file_name'] = file_name

			# 根据不同的路径返回不同的内容
			body = mini_02.application(service_dict, self.head_params)
			head = "HTTP/1.1 %s \r\n" % self.status  # 这个一定要在我们wsgi调之后再去拼接
			# 把响应头进行拼接
			for temp in self.params:
				head += "%s:%s\r\n" % (temp[0], temp[1])
			# head += "%s:%s\r\n"%(temp) 可以去试一下

			content = head + "\r\n" + body
			# 发送数据
			new_socket.send(content.encode("utf-8"))
上面这个是environ是服务器给框架传数据的,一开始先定义一个字典,要将原来file_name装进字典里,再将file_name替换成我们的字典,这个时候要注意的一点是一定要把上面响应头的head = "HTTP/1.1 200 OK \r\n"移到我们application下面,然后把200 OK替换成self.status,因为这个值已经被self.status传过来了,然后我们去拼接响应头,通过遍历我们得到self.params,记住%s:%s\r\n % (temp[0],temp[1])是一个固定格式也可以写成%s:%s\r\n % (temp)当然后者有限定,传过来的值必须和%s的数目相同,然后在application协议上加一个charset=utf-8,这样他就可以输入中文了。这个列表是随你添加东西的,比如加入("class", "python11"),但是这个浏览器不认识,那就会原样不动的放在那。
def application(environ, start_response):
	start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8'), ("class", "python11")])

	file_name = environ['file_name']  # 
下面,我来给大家梳理一下wsgi协议实现的思路,下面是整个流程图:

首先浏览器将地址传送给服务器,服务器获取地址,我们定义一个字典,定义一个函数通过调用mini_application(字典,self.head_params)把字典和函数引用传送给wsgi协议。然后wsgi协议通过def application(environ,start_respose)收到这两个数据。执行了application方法后,等于执行了start_response这个函数的引用,等于反向给服务器发送了一个响应头,服务器通过self.head_params去接收这个响应头。然后再由return去返回一个响应体,服务器通过body去接收,然后服务器再把响应头+空行+响应体组成我们的HTTP协议返回给我们浏览器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值