Python- Web服务器–支持多个遵循WSGI的web框架
代码仅供参考!
模块在使用时注意需要引入,具体怎么引入我就不在这说了,毕竟每个人使用的工具不同
服务端
MyWebServer
from socket import *
import re
from multiprocessing import Process
import sys
class HttpWebServer(object):
HTML_ROOT_DTR = './html'
WSGI_ROOT_DIR = './wsgi'
def handle_ok(self,new_socket,response_body):
response_start = 'HTTP/1.1 200 OK \r\n'
response_headers = 'Content-Type: text/html;charset=utf-8\r\n'
response_blank = '\r\n'
response_body = response_body
response_data = response_start + response_headers + response_blank + response_body
print('response_data==',response_data)
new_socket.send(response_data.encode('utf-8'))
new_socket.close()
def __init__(self,app):
self.app = app
# 创建套接字
self.http_server = socket(AF_INET,SOCK_STREAM)
# 设置端口复用
self.http_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
# 绑定端口
def bind(self,port):
self.http_server.bind(('',port))
def start_response(self,status,headers):
# status = "200 OK"
# headers = [("Content-Type", "text/html;charset=utf-8")]
#组装响应行
self.response_start = 'HTTP/1.1 '+status+'\r\n'
start_response_headers = ''
for header in headers:
start_response_headers += '%s: %s\r\n'%header
#组装响应头
self.response_headers = start_response_headers
def handle_client(self,new_socket,new_address):
#按照http的协议,封装相应数据格式返回给浏览器:响应行,响应头,空白行,响应体(数在这里)
recv_data = new_socket.recv(1024)
#'GET /index.html HTTP/1.1'
#'GET / HTTP/1.1'
#'GET /test.html HTTP/1.1'
request_start = recv_data.splitlines()[0]
#解码
request_start = request_start.decode("utf-8")
print("request_start=", request_start)
file_name = re.match(r"\w+ +(/.*) ",request_start).group(1)
print("file_name==",file_name)
#/ctime.py
file_name = file_name[1:-3]
# # 引入模块
# m = __import__(file_name)
result1 = re.match(r'(\w+) +(/.*) ',request_start)
method = result1.group(1)
path_info = result1.group(2)
print('method===',method)
print('path_info===',path_info)
env = {
'PATH_INFO':path_info,
'METHOD':method
}
response_body = self.app(env,self.start_response)
#数据拼装
response_data = self.response_start + self.response_headers + '\r\n' + response_body
# 将数据发送给浏览器(客户端)
new_socket.send(response_data.encode('utf-8'))
# 关闭套接字
new_socket.close()
def start(self):
# 设置监听
self.http_server.listen(128)
try:
while True:
new_socket,new_address = self.http_server.accept()
print('[%s:%s]已上线',new_address)
#设置并发,支持对进程
Process(target=self.handle_client,args=(new_socket,new_address)).start()
# 关闭new_socket
new_socket.close()
finally:
print('关闭最外层套接字')
self.http_server.close()
if __name__ == '__main__':
# 把/wsgi添加到路径中
sys.path.insert(0,HttpWebServer.WSGI_ROOT_DIR)
path = sys.path
if len(sys.argv) < 2:
print('请配置模块,已经退出程序')
exit()
parms = sys.argv[1]
result = re.split(r':',parms)
modul_name = result[0]
app_name = result[1]
# 加载模块
m = __import__(modul_name)
app = getattr(m,app_name)
http_web_server = HttpWebServer(app)
http_web_server.bind(8888)
http_web_server.start()
框架
MyWebFramwork
import time
import sys
from MyWebServer import HttpWebServer
HTML_ROOT_DIR = './html'
WSGI_ROOT_DIR = './wsgi'
class Application(object):
def __init__(self,urls):
self.urls = urls
def __call__(self, env, start_response):
# 得到webserver的请求路径
path_info = env.get('PATH_INFO')
if path_info.__contains__('static'):
try:
path_info = path_info[7:]
print('path_info==',path_info)
f = open(HTML_ROOT_DIR + path_info,'rb')
except Exception as result:
print(result)
return handle_error(env,start_response)
else:
status = '200 OK'
headers = [('Content-Type', 'text/html;charset=utf-8')]
start_response(status, headers)
response_body = f.read().decode('utf-8')
f.close()
return response_body
if path_info.endswith('.py'):
modul_name = path_info[1:-3]
m = __import__(modul_name)
response_body = m.application(env,start_response)
return response_body
for path,func in self.urls:
if path == path_info:
response_body = func(env,start_response)
return response_body
return handle_error(env,start_response)
def get_hello(env,start_response):
status = '200 OK'
headers = [('Content-Type','text/html;charset=utf-8')]
start_response(status,headers)
return 'hello,你调用时框架' \
'(MyWebFramework.py)的get_hello函数”'
def get_info(env,start_response):
status = '200 OK'
headers = [('Content-Type', 'text/html;charset=utf-8')]
start_response(status, headers)
f = open('./html/index.html', 'rb')
response_body = f.read().decode('utf-8')
return response_body
# def get_info(env, start_response):
# status = '200 OK'
# headers = [('Content-Type', 'text/html;charset=utf-8')]
# start_response(status, headers)
#
# return
def handle_error(env, start_response):
status = '404 Not Found'
headers = [('Content-Type', 'text/html;charset=utf-8')]
start_response(status, headers)
f = open('./html/404.html','rb')
response_body = f.read().decode('utf-8')
# 返回响应体的内容
return response_body
#得到系统的时间
def get_ctime(env,start_response):
status = '200 OK'
headers = [('Content-Type', 'text/html;charset=utf-8')]
start_response(status, headers)
return time.ctime()
def application(env, start_response):
status = '200 OK'
headers = [('Content-Type', 'text/html;charset=utf-8')]
start_response(status, headers)
return get_hello(env,start_response)
urls = [
('/',get_info),
('/hello',get_hello),
('/info',get_info),
('/error',handle_error),
('/ctime',get_ctime)
]
app = Application(urls)