webServer.py
import select, time, re, socket, sys, multiprocessing
class WSGIServer(object):
def __init__(self, docRoot, app):
# 创建服务端连接
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 地址复用
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定地址和端口
self.s.bind(("", 8080))
# 主动连接改为被动监听
self.s.listen(128)
# 设置根目录
self.docRoot = docRoot
# 把创建来的app变为对象的app
self.app = app
# 运行服务器
def runServer(self):
while True:
# 接收客户端的请求
newS, _ = self.s.accept()
# newS.settimeout(3)
# 创建新进程,处理客户端请求
newProcess = multiprocessing.Process(target=self.dealWithRequest, args=(newS,))
# 启动子进程
newProcess.start()
# 设置动态数据的请求头
def setResponse(self, status, headers):
# 设置默认请求头的数据
responseHeaderDefault = [
("Data", time.ctime()),
("Server", "LINUX-python mini web server")
]
# 拼接响应头部数据
self.headers = [status, responseHeaderDefault + headers]
# 设置定义处理客户端请求的函数
def dealWithRequest(self, newS):
while True:
try:
# 接受客户端的数据
request = newS.recv(1024).decode("utf-8")
# 捕获异常
except Exception as ret:
print("========>", ret)
newS.close()
return
# 判断客户端是不是要关闭连接
if not request:
# 没数据关闭连接
newS.close()
return
# 处理数据,进行行切片
requestLines = request.splitlines()
# 获取网站的请求路径
ret = re.match("[^/]+(/[^ ]*)", requestLines[0])
# 判断请求的路径
if ret.group(1) == "/":
# 如果是根路径,让他获取index页面
pathName = ret.group(1) + "index.html"
else:
# 如果不是根路径,返回原有路径赋值
pathName = ret.group(1)
# 处理静态请求
if not pathName.endswith(".py"):
# 异常处理
try:
f = open(self.docRoot + pathName, "r")
# 没有读取数据,捕获异常
except Exception as ret:
# 返回异常的响应头和响应体
responseBady = "file not found, Please input right url"
responseHeader = "HTTP/1.1 404 not found\r\n"
responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
responseHeader += "Content-Length: %d\r\n" % (len(responseBady))
responseHeader += "\r\n"
# 拼接异常响应数据
response = responseHeader + responseBady
# 没有异常
else:
# 读取文件数据
content = f.read()
# 返回响应头和响应体
responseBody = content
responseHeader = "HTTP/1.1 200 OK\r\n"
responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
responseHeader += "Content-Length: %d\r\n" % (len(responseBody))
responseHeader += "\r\n"
# 拼接响应数据
response = responseHeader + responseBody
# 将响应数据发送给客户端
newS.send(response.encode("utf-8"))
# 处理动态请求
else:
# 存储所有需要处理的请求的kv
requestDict = {}
# 通过myWeb下的app函数处理动态请求,获取响应数据
responseBody = self.app(requestDict, self.setResponse)
# 设置响应头
responseHeader = "HTTP/1.1 {status}\r\n".format(status=self.headers[0])
responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
responseHeader += "Content-Length: %d\r\n" % len(responseBody)
# 设置响应头
for tempHead in self.headers[1]:
responseHeader += "{0}:{1}\r\n".format(*tempHead)
# 拼接响应数据
response = responseHeader + "\r\n" + responseBody
# 发送给客户端
newS.send(response.encode("utf-8"))
# 设置静态资源访问的路径
gStaticDocumentRoot = "./html"
# 设置动态资源访问的路径
gDynamicDocumentRoot = "./web"
# 定义服务器的入口
def main():
# 判断程序参数符不符合要求
if len(sys.argv) == 2:
# 获取程序的参数,获取要执行的函数名
webModuleAppName = sys.argv[1]
else:
print("Please input like 'python fileName modelName:applicationName'")
# 导入程序传参模块名以及应用名
ret = re.match(r"([^:]*):(.*)", webModuleAppName)
# 获取模块以及模块名
modelName = ret.group(1)
appName = ret.group(2)
# 添加模块路径到代码环境变量中
sys.path.append(gDynamicDocumentRoot)
# 导入模块名
model = __import__(modelName)
# 将模块内的app应用变成可用的对象或者函数
app = getattr(model, appName)
# 初始化对象并运行服务器
http = WSGIServer(gDynamicDocumentRoot, app)
http.runServer()
if __name__ == "__main__":
main()
web/myWeb.py(动态代码)
import time
def app(requestDict, setResponse):
# 定义状态码
status = 200
# 定义响应头
responseHeader = [('Content-Type', 'text/html')]
# 设置返回的响应头
setResponse(status, responseHeader)
# 返回处理结果
return str(requestDict) + '==Hello world from a simple WSGI application!--->%s\n' % time.ctime()
html/index.html(静态代码)
为 HTML 添加新元素
我的第一个标题
我的第一个段落
我的第一个新元素