1.接收浏览器的请求报文
self.request = socket_con.recv(4096).decode()
if self.request: # 如果收到
# 将请求报文这整个字符串,截取成一行一行的字符串,存储到request_lines这个列表中
request_lines = self.request.split("\r\n")# 获取请求报文中的请求行
requeset_line = request_lines[0] # ['GET /center.html HTTP/1.1', 'Host: 127.0.0.1:22222'.........]
# 获取请求行中的请求资源路径
self.res = re.match(r"\w+\s+(\S+)", requeset_line)
# 服务器处理浏览器发送过来的空请求
self.path = self.res.group(1) # 取第一个分组,此时res='center.html'
self.path = urllib.parse.unquote(self.path) # 将路径解码,因为浏览器对中文进行了URL(%)编码
self.path = os.getcwd() + self.path
# 拼接服务器完整路径 C:\Users\fenghua\Desktop\www3/index.html
2.之后进行静态查找
def handle_static(self, path, socket_con):
if not os.path.exists(path): # 判断文件是否存在,注意语法
return Falseelse:
if os.path.isfile(path): # 判断路径是否是文件,是则读取,返回响应报文,不是则判断是否是文件夹
else:
if not path.endswith("/"): # 判断文件夹是否以/结尾,不是则返回指定路径
response_line = "HTTP/1.1 302 Found\r\n"
response_head = "Server: laozhao v3.0\r\n"
response_head += "Content-Type:text/html;charset=utf-8\r\n"
response_body = "您的路径被制定到" + path + "/"
response = response_line + response_head + "\r\n" + response_body
socket_con.send(response.encode())
socket_con.close()
return True
else:
#若是以/结尾,两种处理方式:
#1.进行路径拼接,path+index/path + default,进行响应报文返回
#2.自己重写html文件,返回响应报文
if os.path.exists(path + "index.html"): # 判断文件存在
返回响应报文
elif os.path.exists(path + "default.html"):
返回响应报文
3.根据静态处理函数的返回值进行数据动态处理
def handle_sport(self, socket_con): # 动态请求处理函数
self.request = socket_con.recv(4096).decode()
if self.request:
# 将请求报文这整个字符串,截取成一行一行的字符串,存储到request_lines这个列表中
request_lines = self.request.split("\r\n")
# 获取请求报文中的请求行
requeset_line = request_lines[0]
# 获取请求行中的请求资源路径
self.res = re.match(r"\w+\s+(\S+)", requeset_line)
# 服务器处理浏览器发送过来的空请求
if self.res:
self.path = self.res.group(1)
self.path = urllib.parse.unquote(self.path)
self.path = os.getcwd() + self.path
# 服务器处理静态请求
result = self.handle_static(self.path, socket_con)
if result == False:
# 以下不用判断是否以什么结尾了,都是动态请求
# /Users/zhaojianyu/Desktop/WSIG/www3/index.py
file_name = re.match(r'\S+www3/(\S+)', self.path).group(1)
env = {
"PATH_INFO": file_name # 文件名获取
}
response_body = dynamic.mini_web_frame_2.application(env, self.start_response)
# 此处调用application函数 获取响应体
此函数定义在web应用程序中,在服务器调用,该函数实现web应用的函数调用,并返回相应的html文件内容或者自己定义的文字等
参数为1.文件名,注意必须以WISG协议规定格式,eg:env 进行传递
2.函数stat_response的引用,进行报文拼接
socket_con.send(response.encode())
socket_con.close()
return
# WISG协议的对调函数start_response,在web应用中调用用于生成回复报文
参数1.状态码 200 OK
参数2.一个响应头列表,里边是一个元组
[("Content-type", "text/html;charset= utf-8")]
# 拼接响应行和响应头
self.response_header = "HTTP/1.1 %s\r\n" % status # HTTP/1.1 200 OK
for k, v in response_head:
self.response_header += "%s: %s\r\n" % (k, v)
4.web应用程序
主要用于处理动态请求,定义相应的处理函数,在application函数中进行调用
def application(environ, start_response):
# 获取请求名
file_name = environ["PATH_INFO"]
try:
#遍历定义好的字典,将传进来的动态请求(文件名)与字典中的文件名进行匹配
if re.match(URL, file_name):
start_response("200 OK", [("Content-type", "text/html;charset= utf-8")])
return FUNC(file_name)
except Exception as e:
start_response("404 error", [("Content-type", "text/html;charset= utf-8")])
return '啥也没有,我的网站满足不了了你!!'
路由:在字典中添加元素----文件名:函数名
def route(filename):
def outer(func):
URL_DIRC[filename] = func
def inner():
return func()
return inner
return outer
几个处理函数
@route()工厂函数的作用:将函数名传进去,再调用里边的装饰器outer
outer作用:
1、调用/执行outer函数2、将@outer下的函数的引用作为参数传递给outer
3、将内函数的引用重新赋值给center等函数
@route('center.html') # center = outer(center)
def center(file_name):
@route('index.html')
def index(file_name):
@route('add/\d+\.html')
def add(file_name):
@route('del/\d+\.html')
def delete(file_name):
@route(r"update/\w+\.html")
def update(file_name):
#/update/股票名/fdsfdsfsdfsdfds.html
@route("update/\w+/.*\.html")
def update_info(file_name):
以上几个处理函数就是对定义好的路由表进行字典内容的填充。此时字典内容为
{'center.html': <function center at 0x000001B0E14B7A60>, 'index.html': <function index at 0x000001B0E14B7B70>, 'add/\\d+\\.html': <function add at 0x000001B0E14B7C80>, 'del/\\d+\\.html': <function delete at 0x000001B0E14B7D90>, 'update/\\w+\\.html': <function update at 0x000001B0E14B7EA0>, 'update/\\w+/.*\\.html': <function update_info at 0x000001B0E14BA048>}
路由内部的装饰器
def outer(func): # center = outer(center)
URL_DIRC[filename] = func
def inner():
return func()
return inner
@route('center.html')
def center(file_name):
# 对html文件的操作
with open("./templates/center.html", "rb") as f:
content1 = f.read()
#对数据库的操作
database='选股系统', charset='utf8')
cursors = con.cursor()
sql = "select a.code,a.short,a.chg,a.turnover,a.price,a.highs,b.note_info from info as a inner join focus as b on a.id = b.info_id"
cursors.execute(sql) # 执行sql语句
# str = "模拟:这是从mysql中查询到的数据"
# {%content%}
str1 = """
<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<a type="button" class="btn btn-defalut btn-xs" href="/update/%s.html"><span class="glyphicon glyphicon
-star" aria="" -="" hidden="true"></span>修改</a>
</td>
<td>
<input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
</td>
</tr>
"""
html = ''
for i in cursors.fetchall(): # 读取所有内容,遍历进行每行的内容显示
html += str1 % (i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[1], i[0]) # 最后两个是更新的 股票名字,删除指定 股票代码
content = re.sub(r"\{%content%\}", html, content1.decode())
# re.sub()在content1.decode()中匹配\{%content%\},把\{%content%\}用html替代
con.close()
return content
用到的正则:
1.code = re.match(r"update/(\w+)\.html", file_name).group(1)
#将匹配的分组1的值赋值给code
2.content = re.sub(r"\{%content%\}", html, content1.decode())
# re.sub()在content1.decode()中匹配\{%content%\},把\{%content%\}用html替代,
\代表起始结束位置