WSGI(动/静)态服务器

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(静态代码)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>为 HTML 添加新元素</title>
<script>
document.createElement("myHero")
</script>
<style>
myHero {
    display: block;
    background-color: #ddd;
    padding: 50px;
    font-size: 30px;
}
</style> 
</head>
 
<body>
 
<h1>我的第一个标题</h1>
 
<p>我的第一个段落</p>
 
<myHero>我的第一个新元素</myHero>
 
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值