mini web框架示例

web框架:

使用web框架专门负责处理用户的动态资源请求,这个web框架其实就是一个为web服务器提供服务的应用程序

什么是路由?

路由就是请求的url到处理函数的映射,也就是说提前把请求的URL和处理函数关联好

管理路由可以使用一个路由列表进行管理

web.py文件:


		importsocket
		importos
		importthreading
		importsys
		importframework
		
		
		#http协议的web服务器类
		classHttpWebServer(object):
		def__init__(self,port):
		#创建tcp服务端套接字
		tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
		#设置端口号复用,程序退出端口号立即释放
		tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
		#绑定端口号
		tcp_server_socket.bind(("",port))
		#设置监听
		tcp_server_socket.listen(128)
		#把tcp服务器的套接字作为web服务器对象的属性
		self.tcp_server_socket=tcp_server_socket
		
		#处理客户端请求
		@staticmethod
		defhandle_client_request(new_socket):
		#接收客户端的请求信息
		recv_data=new_socket.recv(4096)
		#判断接收的数据长度是否为0
		iflen(recv_data)==0:
		new_socket.close()
		return
		
		#对二进制数据进行解码
		recv_content=recv_data.decode("utf-8")
		print(recv_content)
		
		#对数据按照空格进行分割
		request_list=recv_content.split("",maxsplit=2)
		#获取请求的资源路径
		request_path=request_list[1]
		print(request_path)
		
		#判断请求的是否是根目录,如果是根目录设置返回的信息
		ifrequest_path=="/":
		request_path="/index.html"
		
		#判断是否是动态资源请求,以后把后缀是.html的请求任务是动态资源请求
		ifrequest_path.endswith(".html"):
		"""动态资源请求"""
		#动态资源请求找web框架进行处理,需要把请求参数给web框架
		#准备给web框架的参数信息,都要放到字典里面
		env={
		"request_path":request_path,
		#传入请求头信息,额外的参数可以在字典里面在进行添加
		}
		#使用框架处理动态资源请求,
		#1.web框架需要把处理结果返回给web服务器,
		#2.web服务器负责把返回的结果封装成响应报文发送给浏览器
		status,headers,response_body=framework.handle_request(env)
		print(status,headers,response_body)
		#响应行
		response_line="HTTP/1.1%s\r\n"%status
		#响应头
		response_header=""
		forheaderinheaders:
		response_header+="%s:%s\r\n"%header
		
		#响应报文
		response_data=(response_line+
		response_header+
		"\r\n"+
		response_body).encode("utf-8")
		
		#发送响应报文数据给浏览器
		new_socket.send(response_data)
		#关闭连接
		new_socket.close()
		
		else:
		"""静态资源请求"""
		#1.os.path.exits
		#os.path.exists("static/"+request_path)
		#2.try-except
		
		try:
		#打开文件读取文件中的数据,提示:这里使用rb模式,兼容打开图片文件
		withopen("static"+request_path,"rb")asfile:#这里的file表示打开文件的对象
		file_data=file.read()
		#提示:withopen关闭文件这步操作不用程序员来完成,系统帮我们来完成
		exceptExceptionase:
		#代码执行到此,说明没有请求的该文件,返回404状态信息
		#响应行
		response_line="HTTP/1.1404NotFound\r\n"
		#响应头
		response_header="Server:PWS/1.0\r\n"
		#读取404页面数据
		withopen("static/error.html","rb")asfile:
		file_data=file.read()
		
		#响应体
		response_body=file_data
		
		#把数据封装成http响应报文格式的数据
		response=(response_line+
		response_header+
		"\r\n").encode("utf-8")+response_body
		
		#发送给浏览器的响应报文数据
		new_socket.send(response)
		
		else:
		#代码执行到此,说明文件存在,返回200状态信息
		#响应行
		response_line="HTTP/1.1200OK\r\n"
		#响应头
		response_header="Server:PWS/1.0\r\n"
		#响应体
		response_body=file_data
		
		#把数据封装成http响应报文格式的数据
		response=(response_line+
		response_header+
		"\r\n").encode("utf-8")+response_body
		
		#发送给浏览器的响应报文数据
		new_socket.send(response)
		finally:
		#关闭服务于客户端的套接字
		new_socket.close()
		
		#启动服务器的方法
		defstart(self):
		#循环等待接受客户端的连接请求
		whileTrue:
		#等待接受客户端的连接请求
		new_socket,ip_port=self.tcp_server_socket.accept()
		#代码执行到此,说明连接建立成功
		sub_thread=threading.Thread(target=self.handle_client_request,args=(new_socket,))
		#设置成为守护主线程
		sub_thread.setDaemon(True)
		#启动子线程执行对应的任务
		sub_thread.start()
		
		
		defmain():
		
		##获取终端命令行参数
		#params=sys.argv
		#iflen(params)!=2:
		#print("执行的命令格式如下:python3xxx.py9000")
		#return
		##
		###判断第二个参数是否都是由数字组成的字符串
		#ifnotparams[1].isdigit():
		#print("执行的命令格式如下:python3xxx.py9000")
		#return
		##
		###代码执行到此,说明命令行参数的个数一定2个并且第二个参数是由数字组成的字符串
		#port=int(params[1])
		#创建web服务器
		web_server=HttpWebServer(8000)
		#启动服务器
		web_server.start()
		
		#判断是否是主模块的代码
		if__name__=='__main__':
		main()
	framework.py文件:
		"""web框架的职责专门负责处理动态资源请求"""
		importtime
		route_list=[
		
		]
		#定义带有参数的装饰器
		defroute(path):
		defdecorator(func):
		#装饰器执行的时候就需要把路由添加到路由列表里
		route_list.append((path,func))
		definner():
		result=func();
		returnresult
		returninner
		returndecorator
		
		#获取首页数据
		@route("/index.html")
		defindex():
		#状态信息
		status="200OK"
		#响应头信息
		response_header=[("Server","PWS/1.1")]
		#1.打开指定模板文件,读取模板文件中的数据
		withopen("template/index.html","r",encoding='utf-8')asfile:
		file_data=file.read()
		#2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据
		
		#web框架处理后的数据
		#获取当前时间,模拟数据库内容
		data=time.ctime()
		response_body=file_data.replace("{%content%}",data)
		#这里返回的是元组
		returnstatus,response_header,response_body
		
		#获取个人中心数据
		@route("/center.html")
		defcenter():
		#状态信息
		status="200OK"
		#响应头信息
		response_header=[("Server","PWS/1.1")]
		#1.打开指定模板文件,读取模板文件中的数据
		withopen("template/center.html","r",encoding='utf-8')asfile:
		file_data=file.read()
		#2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据
		
		#web框架处理后的数据
		#获取当前时间,模拟数据库内容
		data=time.ctime()
		response_body=file_data.replace("{%content%}",data)
		#这里返回的是元组
		returnstatus,response_header,response_body
		
		#处理没有找到的动态资源
		defnot_found():
		#状态信息
		status="404NotFound"
		#响应头信息
		response_header=[("Server","PWS/1.1")]
		#web框架处理后的数据
		data="notfound"
		
		#这里返回的是元组
		returnstatus,response_header,data
		
		#处理动态资源请求
		defhandle_request(env):
		#获取动态的请求资源路径
		request_path=env["request_path"]
		print("动态资源请求的地址:",request_path)
		#判断请求的动态资源路径,选择指定的函数处理对应的动态资源请求
		forpath,funcinroute_list:
		ifrequest_path==path:
		result=func()
		returnresult
		else:
		result=not_found()
		returnresult
		
		
		#ifrequest_path=="/index.html":
		##获取首页数据
		#result=index()
		##把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用
		#returnresult
		#elifrequest_path=="/center.html":
		##个人中心
		#result=center()
		#returnresult
		#else:
		##没有动态资源数据,返回404状态信息
		#result=not_found()
		##把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用
		#returnresult
		if__name__=="__main__":
		print(route_list)
		
		
		
		

framework.py文件:

"""web框架的职责专门负责处理动态资源请求"""
import time
route_list=[

]
#定义带有参数的装饰器
def route(path):
    def decorator(func):
        #装饰器执行的时候就需要把路由添加到路由列表里
        route_list.append((path, func))
        def inner():
            result=func();
            return result
        return inner
    return decorator

# 获取首页数据
@route("/index.html")
def index():
    # 状态信息
    status = "200 OK"
    # 响应头信息
    response_header = [("Server", "PWS/1.1")]
    # 1.打开指定模板文件,读取模板文件中的数据
    with open("template/index.html","r",encoding='utf-8') as file:
         file_data=file.read()
    # 2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据

    # web框架处理后的数据
    # 获取当前时间,模拟数据库内容
    data = time.ctime()
    response_body=file_data.replace("{%content%}",data)
    # 这里返回的是元组
    return status, response_header, response_body

#获取个人中心数据
@route("/center.html")
def center():
    # 状态信息
    status = "200 OK"
    # 响应头信息
    response_header = [("Server", "PWS/1.1")]
    # 1.打开指定模板文件,读取模板文件中的数据
    with open("template/center.html","r",encoding='utf-8') as file:
         file_data=file.read()
    # 2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据

    # web框架处理后的数据
    # 获取当前时间,模拟数据库内容
    data = time.ctime()
    response_body=file_data.replace("{%content%}",data)
    # 这里返回的是元组
    return status, response_header, response_body

# 处理没有找到的动态资源
def not_found():
    # 状态信息
    status = "404 Not Found"
    # 响应头信息
    response_header = [("Server", "PWS/1.1")]
    # web框架处理后的数据
    data = "not found"

    # 这里返回的是元组
    return status, response_header, data

# 处理动态资源请求
def handle_request(env):
    # 获取动态的请求资源路径
    request_path = env["request_path"]
    print("动态资源请求的地址:", request_path)
    # 判断请求的动态资源路径,选择指定的函数处理对应的动态资源请求
    for path, func in route_list:
        if request_path == path:
            result = func()
            return result
    else:
        result = not_found()
        return result


    # if request_path == "/index.html":
    #     # 获取首页数据
    #     result = index()
    #     # 把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用
    #     return result
    # elif request_path=="/center.html":
    #    #个人中心
    #     result=center()
    #     return result
    # else:
    #     # 没有动态资源数据, 返回404状态信息
    #     result = not_found()
    #     # 把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用
    #     return result
if __name__=="__main__":
    print(route_list)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/712101.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浅谈网络通信(3)

文章目录 一、TCP[!]1.1、TCP协议报文格式1.2、TCP十大机制1.2.1、确认应答机制1.2.2、超时重传机制1.2.3、连接管理机制1.2.3.1、三次握手[其流程至关重要,面试必考]1.2.3.2.1、那为啥要建立连接??建立连接的意义是啥?&#xff1…

数据库管理-第204期 数据库的IO掉速,也许是SSD的锅(20240615)

数据库管理204期 2024-06-15 数据库管理-第204期 数据库的IO掉速,也许是SSD的锅(20240615)1 SSD物理结构2 SSD颗粒类型3 DRAM & SLC Cache3.1 DRAM3.2 SLC Cache3.3 其他方式 4 缓外降速总结 数据库管理-第204期 数据库的IO掉速&#xff…

System-Verilog 实现DE2-115流水灯

文章目录 一、 SystemVerilog1. SystemVerilog简介2. 基本语法和特性 二、实验过程hello.v文件引脚分配 三、实验效果参考 一、 SystemVerilog 1. SystemVerilog简介 SystemVerilog是一种高级的硬件描述语言(HDL),它不仅继承了Verilog语言的…

Qt项目天气预报(2) - 重写事件函数

鼠标右键实现退出界面 知识点QMenu: QMenu 弹出对话框 --> 相对QMessageBox 更加轻量点 QMenu是Qt库中用于创建弹出式菜单的类,它通常出现在应用程序的顶部菜单栏、按钮的右键菜单或自定义上下文菜单中。以下是关于QMenu的详细介绍: 1. 类的基本特…

JUnit 5学习笔记

JUnit 5 学习笔记 1.JUnit5的改变2.JUnit5常用注解及测试2.1 DisplayName/Disabled/BeforeEach/AfterEach/BeforeAll/AfterAll2.2 Timeout2.3 RepeatedTest 3.断言3.1 简单断言3.2 数组断言3.3 组合断言3.4 异常断言3.5 超时断言3.6 快速失败 4.前置条件5.嵌套测试6.参数化测试…

《Fundamentals of Power Electronics》——理想变压器基本公式推导

接下去推导理想变压器的基本公式。理想变压器满足以下三个条件: 1、无铜损。假设原副边线圈均无纯电阻,则不会因在铜导线中产生焦耳热引起能量损耗,另外也不考虑回路中的分布电容。 2、无铁损。忽略通过铁芯的磁通量变化引起的涡流损耗&…

DistilBertModel模型的简单解释

前言 DistilBertModel((embeddings): Embeddings((word\_embeddings): Embedding(30522, 768, padding\_idx0)(position\_embeddings): Embedding(512, 768)(LayerNorm): LayerNorm((768,), eps1e-12, elementwise\_affineTrue)(dropout): Dropout(p\0.1, inplaceFalse))(trans…

解决方案︱视频孪生智慧高速解决方案

系统概述 在交通强国战略的指导下,我国政府高度重视以数字化为核心的智慧高速公路建设与发展。2023年9月,交通运输部印发了《交通运输部关于推进公路数字化转型加快智慧公路建设发展的意见》,强调到2035年,全面实现公路数字化转型…

【多线程】Thread类及其基本用法

🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. Java中多线程编程1.1 操作系统线程与Java线程1.2 简单使用多线程1.2.1 初步创建新线程代码1.2.2 理解每个…

IDEA创建lib目录,导入jar

IDEA创建lib目录,导入jar lib第一种创建方法: 当发现项目没有lib目录时,File>>>Project Structure 打开Artifacts目录 lib第二种创建方法: 按需选择需要的jar包或者全选即可 lib第三种创建方法:

MongoDB使用$addToSet向数组中添加元素

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第66篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…

为什么白昼最长的地方不是在太阳的直射点

因为地球的自传轴相对于地球的公转平面成23.5度的夹角,地球自转一周是24小时,只有白天和黑夜两种状态。白天就可以定义为我们坐在地球上,跟着地球一直转,穿过有光照的地方所花的时间。 假设太阳光正对北回归线(这一天…

2024.ZCPC.M题 计算三角形个数

题目描述: 小蔡有一张三角形的格子纸,上面有一个大三角形。这个边长为 的大三角形, 被分成 个边长为 1 的小三角形(如图一所示)。现在,小蔡选择了一条水平边 删除(如图二所示),请你找出图上剩余…

把FydeOS塞进U盘,即插即用,小白都懂能看懂的Fyde To Go教程

前言 之前小白给各位小伙伴分享过关于Windows塞进U盘的教程: 把Windows系统装进U盘,从此到哪都有属于你自己的电脑系统 如果Windows都能装到U盘里,随身携带。那fydeOS能不能也像Windows一样塞到U盘里,实现FydeOS to Go呢&#…

树的基本概念

树(Tree) "树"这种数据很像现实生活中的“树”, 这里的每个元素我们叫做“节点” 用来连线相邻节点之间的关系,我们叫做“父子关系” A节点就是B节点的父节点,B节点是A节点的‘子节点’B,C,D这三个节点的…

Java基础语法Ⅰ【注释、关键字、字面量、变量】

Java基础语法① 注释关键字与标识符数据类型字面量和常量变量转义字符 注释 注释是在写代码时,对代码作出的一些解释说明,比如某一个函数的作用(功能)、函数接收的参数以及函数返回什么东西等等。 这些解释说明没有任何功能&…

C# Winform DPI自适应方案

Winform窗体随着屏幕的DPI缩放,会引起窗体变形及字体变形。 1.设置窗体和自定义用户控件的AutoScaleMode为None 实现目标:禁止窗体因为字体大小缩放变形 因为显示的高分屏,然后操作系统的设置了字体缩放引起的。窗体默认的AutoScaleMode = Font,控件会因为高分屏自动缩放…

遇到的状态308问题

前端用的vue.config.js做的代理,请求后端的地址https://n6118lr7-10010.usw3.devtunnels.ms 在请求的时候会308 是因为本地是http而请求地址是https 前端代理允许https接口代理即可

python pandas处理股票量化数据:笔记2

有一个同学用我的推荐链接注册了tushare社区帐号https://tushare.pro/register?reg671815,现在有了170分积分。目前使用数据的频率受限制。不过可以在调试期间通过python控制台获取数据,将数据保存在本地以后使用不用高频率访问tushare数据接口&#xf…

【Spring】Spring事务相关源码分析

目录: 1.讲述事务的一些基础概念。 2.讲述事务的生命周期源码 3.配置事务,以及事务注解的源码 1.前言 具体事务中Spring是怎么管理事务,怎么去管理、创建、销毁等操作的呢?这一次来分解一下。 2.事务概述(复习&a…