Web服务器--支持多个遵循WSGI的web框架

本文介绍了一个Web服务器,它能够支持多个遵循WSGI标准的Web框架,如Django和自定义框架MyWebFramework。通过示例代码DjangoWeb.py和两个MyWebFramework.py的实现,展示了如何集成和运行这些框架。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

完整代码

DjangoWeb.py代码

# coding:utf-8
import time
#from MyWebServer import HttpServer
import re
#常量名字要大写
HTML_ROOT_DIR = "./html"
#得到当前系统时间
def get_time(env,start_response):
    #调用传入进来的start_response函数,
    #并且调用的时候把当运行状态的相关状态给服务器
    status = "200 OK"
    headers = [
        ("Content-Type","Text/plain")
 
    ]
    start_response(status,headers)
    #返回前系统时间
    return "Django_"+time.ctime()
 
#得到字符串hello atguigu
def get_hello(env,start_response):
    #调用传入进来的start_response函数,
    #并且调用的时候把当运行状态的相关状态给服务器
    status = "200 OK"
    headers = [
        ("Content-Type","Text/plain")
    ]
    start_response(status,headers)
    #返回Django_hello atguigu
    return "Django_hello atguigu"
 
#得到字符串I love you!
def say_love(env,start_response):
    #调用传入进来的start_response函数,
    #并且调用的时候把当运行状态的相关状态给服务器
    status = "200 OK"
    headers = [
        ("Content-Type","Text/plain")
    ]
    start_response(status,headers)
    #返回hello atguigu
    return "Django_I love you!"
 
 
class Application(object):
        """框架的核心部分,也是框架的主体程序,框架是通用的"""
        def __init__(self,urls):
               #接收路由信息
               self.urls = urls
        def __call__(self, env, start_response):
               #得到要执行的函数(路径)
               #可能得到/ctime或者/hello
                path = env.get("PATH_INFO","/")
               #/static/index.html
               if path.startswith("/static"):
                       # /static/index.html-->/index.html
                       file_name = path[7:]
                       try:
                               # 打开文件读取/html/index.html文件内容,以二进制方式
                               f = open(HTML_ROOT_DIR + file_name, "rb")
                       except:  # 文件没有找到返回404
                               # 1.响应状态
                               statu = "HTTP/1.1 404 Not Found"
                               # 2.响应头信息
                               headers = [
                                      ("Content-Type", "Text/plain")
 
                               ]
                               # 生成响应头
                               start_response(statu, headers)
                               # 返回响应体内容
                               return "Not Found,Sorry!"
                       else:
                               # 文件存在,正常处理
                               file_data = f.read()
                               # 关闭文件
                               f.close()
                               # 1.响应状态
                               statu = "200 OK"
                               # 2.响应头信息
                               headers = []
                               # 生成响应头
                               start_response(statu, headers)
                               # 返回响应体内容
                               return file_data.decode("utf-8")
 
               for url,function in self.urls:
                       #("/ctime", get_time)
                       #url对应的是/ctime;function对应的是get_time
                       if path == url:#判断是否是调用的函数
                               #返回的是响应体的内容
                               response_body = function(env,start_response)
                               print("response_body:",response_body)
                               #之间返回
                               return response_body
               #拼接错误处理:响应头和响应体-----
               #1.响应状态
               statu = "404 Not Found"
               #2.响应头信息
               headers = [
                       ("Content-Type", "Text/plain")
 
               ]
               #生成响应头
               start_response(statu,headers)
               #返回响应体内容
               return "Django_Not Found,Sorry!"
 
#路由信息
urls = [
               # 当http://192.168.1.27:7788/ctime就是调用get_time方法
               ("/", get_time),
               ("/ctime", get_time),
               ("/hello", get_hello),
               ("/love", say_love)
        ]
#django_app变成了DjangoWeb.py模块中的属性
django_app = Application(urls)
 
'''
if __name__ == "__main__":
        #路由信息
        urls = [
               # 当http://192.168.1.27:7788/ctime就是调用get_time方法
               ("/", get_time),
               ("/ctime", get_time),
               ("/hello", get_hello),
               ("/love", say_love)
        ]
 
        app = Application(urls)
 
        # 创建MyWebServer模块中的HttpServer类
        http_server = HttpServer(app)
        http_server.bind(7788)
        http_server.start()
'''

 

MyWebFramework.py代码

#coding=utf-8
import  socket
from multiprocessing import Process
import re
import  sys
from MyWebFramework import Application
#常量名字要大写
HTML_ROOT_DIR = "./html"
WSGI_ROOT_DIR = "./wsgi"
 
class HttpServer(object):
        def __init__(self,application):
               self.app = application
               # 创建TCP服务端
               self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
               # 服务端口可以重复启动,不会被占用
               self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 
        def bind(self,port):
               # 绑定端口
               self.server.bind(("", port))
        def start(self):
               # 设置监听
               self.server.listen(128)
 
               while True:
                       client_socket, client_address = self.server.accept()
                       # print("[%s %s]客户已经链接上了"%(client_address[0],client_address[1]))
                       print("[%s %s]客户已经链接上了" % client_address)
                       client = Process(target=self.handle_client, args=(client_socket,))
                       client.start()
                       # 在主进程中关闭链接
                       client_socket.close()
 
        #根据运行python程序的情况,组织响应给浏览器的头对应信息
        def start_response(self,status,headers):
               """status = "200 OK"
                headers = [
                        ("Content-Type","Text/plain")
                ]
        """
               response_headers = "HTTP/1.1 " + status + "\r\n"
               for header in headers:
                       response_headers += "%s: %s"%header+"\r\n"
               #这样赋值给实例对象的response_header,其他地方就能使用了
               self.response_header = response_headers
 
        def handle_client(self,client_socket):
               # 获取客户端请求的数据
               request_data = client_socket.recv(1024)
               request_lines = request_data.splitlines()
               for line in request_lines:
                       print(line)
               # 从b'GET /index.html HTTP/1.1或者b'GET / HTTP/1.1
               request_start_line = request_lines[0].decode("utf-8")
               # 使用正则表达式,得到请求路径/或者/index.html
               file_path = re.match(r"\w+ +(/[^ ]*)", request_start_line)
               file_name = file_path.group(1)
               ## 从b'GET /index.html HTTP/1.1或者b'GET / HTTP/1.1
               # 得到请求方法GET或者POST等
               method = re.match(r"(\w+) +/[^ ]*", request_start_line).group(1)
 
               env = {"PATH_INFO":file_name,
                          "METHOD":method
                       }
               response_body = self.app(env, self.start_response)
               # 组织响应数据response = 响应头 + 响应体
               response = self.response_header + "\r\n" + response_body
               print("file_name:", file_name)
 
               print("response data:", response)
               #client_socket.send(bytes(response,"utf-8"))
               client_socket.send(response.encode("utf-8"))
               client_socket.close()
 
 
def main():
        sys.path.insert(1,WSGI_ROOT_DIR)
        if len(sys.argv) < 2:
               sys.exit("您还没有配置:python3 MyWebServer.py Module:app")
        #python3 MyWebServer.py MyWebFramework:app
        #得到MyWebFramework:app
        argvs = sys.argv[1]
        #拆分成:
        #module_name = "MyWebFramework"
        #app_name = "app"
        module_name,app_name = argvs.split(":")
        #导入模块
        m = __import__(module_name)
        #使用getattr(模块,要加载模块的属性或者类)
        #app就是Application类 实例化好的对象,并且传入了路由信息
        app = getattr(m,app_name)
        #实例化MyWebFramework.py中的Application类
        #app = Application(urls)
 
        http_server = HttpServer(app)
        http_server.bind(7788)
        http_server.start()
 
 
if __name__ == "__main__":
        main()

 

MyWebFramework.py代码

# coding:utf-8
import time
#from MyWebServer import HttpServer
import re
#常量名字要大写
HTML_ROOT_DIR = "./html"
#得到当前系统时间
def get_time(env,start_response):
    #调用传入进来的start_response函数,
    #并且调用的时候把当运行状态的相关状态给服务器
    status = "200 OK"
    headers = [
        ("Content-Type","Text/plain")
 
    ]
    start_response(status,headers)
    #返回前系统时间
    return time.ctime()
 
#得到字符串hello atguigu
def get_hello(env,start_response):
    #调用传入进来的start_response函数,
    #并且调用的时候把当运行状态的相关状态给服务器
    status = "200 OK"
    headers = [
        ("Content-Type","Text/plain")
    ]
    start_response(status,headers)
    #返回hello atguigu
    return "hello atguigu"
 
#得到字符串I love you!
def say_love(env,start_response):
    #调用传入进来的start_response函数,
    #并且调用的时候把当运行状态的相关状态给服务器
    status = "200 OK"
    headers = [
        ("Content-Type","Text/plain")
    ]
    start_response(status,headers)
    #返回hello atguigu
    return "I love you!"
 
 
class Application(object):
        """框架的核心部分,也是框架的主体程序,框架是通用的"""
        def __init__(self,urls):
               #接收路由信息
               self.urls = urls
        def __call__(self, env, start_response):
               #得到要执行的函数(路径)
               #可能得到/ctime或者/hello
               path = env.get("PATH_INFO","/")
               #/static/index.html
               if path.startswith("/static"):
                       # /static/index.html-->/index.html
                       file_name = path[7:]
                       try:
                               # 打开文件读取/html/index.html文件内容,以二进制方式
                               f = open(HTML_ROOT_DIR + file_name, "rb")
                       except:  # 文件没有找到返回404
                               # 1.响应状态
                               statu = "HTTP/1.1 404 Not Found"
                               # 2.响应头信息
                               headers = [
                                      ("Content-Type", "Text/plain")
 
                               ]
                               # 生成响应头
                               start_response(statu, headers)
                               # 返回响应体内容
                               return "Not Found,Sorry!"
                       else:
                               # 文件存在,正常处理
                               file_data = f.read()
                               # 关闭文件
                               f.close()
                               # 1.响应状态
                               statu = "200 OK"
                               # 2.响应头信息
                               headers = []
                               # 生成响应头
                               start_response(statu, headers)
                               # 返回响应体内容
                               return file_data.decode("utf-8")
 
               for url,function in self.urls:
                       #("/ctime", get_time)
                       #url对应的是/ctime;function对应的是get_time
                       if path == url:#判断是否是调用的函数
                               #返回的是响应体的内容
                               response_body = function(env,start_response)
                               print("response_body:",response_body)
                               #之间返回
                               return response_body
               #拼接错误处理:响应头和响应体-----
               #1.响应状态
               statu = "404 Not Found"
               #2.响应头信息
               headers = [
                       ("Content-Type", "Text/plain")
 
               ]
               #生成响应头
               start_response(statu,headers)
               #返回响应体内容
               return "Not Found,Sorry!"
 
#路由信息
urls = [
               # 当http://192.168.1.27:7788/ctime就是调用get_time方法
               ("/", get_time),
               ("/ctime", get_time),
               ("/hello", get_hello),
               ("/love", say_love)
        ]
#app变成了MyWebFramework.py模块中的属性
app = Application(urls)
 
'''
if __name__ == "__main__":
        #路由信息
        urls = [
               # 当http://192.168.1.27:7788/ctime就是调用get_time方法
               ("/", get_time),
               ("/ctime", get_time),
               ("/hello", get_hello),
               ("/love", say_love)
        ]
 
        app = Application(urls)
 
        # 创建MyWebServer模块中的HttpServer类
        http_server = HttpServer(app)
        http_server.bind(7788)
        http_server.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值