Skip to content

Latest commit

 

History

History
296 lines (244 loc) · 8.12 KB

57.Mini-WEb框架实现1.md

File metadata and controls

296 lines (244 loc) · 8.12 KB

mini-web框架实现

一.mini web框架-文件结构

1.文件结构

├── dynamic ---存放py模块
│   └── my_web.py
├── templates ---存放模板文件
│   ├── center.html
│   ├── index.html
│   ├── location.html
│   └── update.html
├── static ---存放静态的资源文件
│   ├── css
│   │   ├── bootstrap.min.css
│   │   ├── main.css
│   │   └── swiper.min.css
│   └── js
│       ├── a.js
│       ├── bootstrap.min.js
│       ├── jquery-1.12.4.js
│       ├── jquery-1.12.4.min.js
│       ├── jquery.animate-colors.js
│       ├── jquery.animate-colors-min.js
│       ├── jquery.cookie.js
│       ├── jquery-ui.min.js
│       ├── server.js
│       ├── swiper.jquery.min.js
│       ├── swiper.min.js
│       └── zepto.min.js
└── web_server.py ---mini web服务器

2.my_web.py

# -*- coding:utf-8 -*-
def application(environ, start_response):
    """
    :param environ: http给我们的mini框架传数据
    :param start_response: 这个给http传数据
    :return:
    """
    start_response('200 ok', [('Content-Type', 'text/html')])
    # 这里更具不同的地址(url)地址去进行相应的处理
    url = environ['file_name']

    if url == '/index.py':
        return 'index.py is show'
    elif url == 'center.py':
        return 'center.py is show'
    else:
        return "not page is find!"

3.web_server.py

# -*- coding:utf-8 -*-
import re
import socket
import multiprocessing
from dynamic import my_web


class WsgiServer(object):
    def __init__(self, address):
        self.status = None
        self.params = None
        # 1.创建套接字
        self.server_soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 2.设置socket为自动释放
        self.server_soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 3.绑定地址
        self.server_soc.bind(address)
        # 4.变成监听套接字
        self.server_soc.listen(128)

    def run_server(self):
        """运行服务器"""
        while True:
            # 等待客户端连接
            new_soc, client_addr = self.server_soc.accept()
            # 创建进程启动服务
            p = multiprocessing.Process(target=self.service_client, args=(new_soc,))
            p.start()
            new_soc.close()

    def service_client(self, sock):
        """服务端处理接收的请求"""
        try:
            request_data = sock.recv(1024).decode('utf-8')
        except Exception as e:
            print(e)
            print("数据编码错误")
        else:
            # 判断消息是否有数据
            if not request_data:  # 没有消息
                print("client is disconnected。。。。")
            else:
                self.deal_data(request_data, sock)

            sock.close()

    def deal_data(self, data, sock):
        """处理数据"""
        # 切割请求头
        request_header_lines = data.splitlines()

        # 打印测试
        for request_header_line in request_header_lines:
            print(request_header_line)

        # 获取请求行行信息:因为它包含请求的资源
        http_request_line = request_header_lines[0]

        # 正则切割出请求资源的文件名,eg:GET / HTTP/1.1
        request_file_name = re.match(r'[^/]+(/[^ ]*)', http_request_line).group(1)

        print("请求的文件名为:%s" % request_file_name)

        #  判断是静态还是动态
        if request_file_name.endswith(".py"):
            environ = dict()
            environ['file_name'] = request_file_name
            body = my_web.application(environ, self.set_head_params)

            header = "HTTP/1.1 %s\r\n" % self.status

            # 去拼接我们的头部
            for temp in self.params:
                header += "%s:%s\r\n" % (temp[0], temp[1])
            content = header + '\r\n' + body
            sock.send(content.encode('utf-8'))
        else:
            # 从静态返回数据
            try:
                f = open("./static" + request_file_name, "rb")
            except:
                response = "HTTP/1.1 404 NOT FOUND\r\n"
                response += "\r\n"
                response += "------file not found-----"
                sock.send(response.encode("utf-8"))
            else:
                html_content = f.read()
                f.close()
                # 2.1 准备发送给浏览器的数据---header
                response = "HTTP/1.1 200 OK\r\n"
                response += "\r\n"
                # 2.2 准备发送给浏览器的数据---boy
                # response += "hahahhah"

                # 将response header发送给浏览器
                sock.send(response.encode("utf-8"))
                # 将response body发送给浏览器
                sock.send(html_content)
        sock.close()

    def set_head_params(self, status, params):
        """回调返回状态码和头部信息"""
        print(status, params)
        self.status = status
        self.params = params


def main():
    addr = ("", 8080)
    web_server = WsgiServer(addr)
    web_server.run_server()


if __name__ == '__main__':
    main()

二.mini web框架-显示页面

1.dynamic/my_web.py (更新)

# -*- coding:utf-8 -*-
template_root = "./templates"


def index(file_name):
    """返回index.py需要的页面内容"""
    try:
        file_name = file_name.replace(".py", ".html")
        f = open(template_root + file_name)
    except Exception as ret:
        return "%s" % ret
    else:
        content = f.read()
        f.close()
        return content


def center(file_name):
    """返回center.py需要的页面内容"""
    try:
        file_name = file_name.replace(".py", ".html")
        f = open(template_root + file_name)
    except Exception as ret:
        return "%s" % ret
    else:
        content = f.read()
        f.close()
        return content


def application(environ, start_response):
    """
    :param environ: http给我们的mini框架传数据
    :param start_response: 这个给http传数据
    :return:
    """

    start_response('200 ok', [('Content-Type', 'text/html')])
    # 这里更具不同的地址(url)地址去进行相应的处理
    url = environ['file_name']
    print("获得的url地址是:%s" % url)

    if url == '/index.py':
        return index(url)
    elif url == '/center.py':
        return center(url)
    else:
        return "not page is find!"

三.mini web框架-替换模板

1.dynamic/my_web.py

# -*- coding:utf-8 -*-
import re

template_root = "./templates"


def index(file_name):
    """返回index.py需要的页面内容"""
    try:
        file_name = file_name.replace(".py", ".html")
        f = open(template_root + file_name)
    except Exception as ret:
        return "%s" % ret
    else:
        content = f.read()
        f.close()
        # --------更新-------
        data_from_mysql = "数据还没有敬请期待...."
        content = re.sub(r"\{%content%\}", data_from_mysql, content)
        return content


def center(file_name):
    """返回center.py需要的页面内容"""
    try:
        file_name = file_name.replace(".py", ".html")
        f = open(template_root + file_name)
    except Exception as ret:
        return "%s" % ret
    else:
        content = f.read()
        f.close()
        # --------更新-------
        data_from_mysql = "暂时没有数据,,,,~~~~(>_<)~~~~ "
        content = re.sub(r"\{%content%\}", data_from_mysql, content)

        return content


def application(environ, start_response):
    """
    :param environ: http给我们的mini框架传数据
    :param start_response: 这个给http传数据
    :return:
    """

    start_response('200 ok', [('Content-Type', 'text/html')])
    # 这里更具不同的地址(url)地址去进行相应的处理
    url = environ['file_name']
    print("获得的url地址是:%s" % url)

    if url == '/index.py':
        return index(url)
    elif url == '/center.py':
        return center(url)
    else:
        return "not page is find!"