欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

WSGI协议

程序员文章站 2022-03-04 10:45:38
...

WSGI协议

Python Web Server Gateway Interface 或简称 WSGI

  • WSGI允许开发者将选择web框架和web服务器分开。可以混合匹配web服务器和web框架,选择一个适合的配对
  • web服务器必须具备WSGI接口,所有的现代Python Web框架都已具备WSGI接口,它让你不对代码作修改就能使服务器和特点的web框架协同工作。
  • WSGI由web服务器支持,而web框架允许你选择适合自己的配对,但它同样对于服务器和框架开发者提供便利使他们可以专注于自己偏爱的领域和专长而不至于相互牵制。

定义WSGI接口(web_frame.py)

WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求

def application(environ, set_response_headers):
    status = '200 OK'
    file_name = environ['PATH_INFO']
    response_headers = [('Content-Type', 'text/html')]
    # 利用函数的引用调用函数传参,返回响应头
    set_response_headers(status, response_headers)
    # 返回值为响应体
    return str(environ) + '==Hello world from a simple WSGI application!--->%s\n' % time.ctime()
  • 上面的application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

    environ:一个包含所有HTTP请求信息的dict对象;

    start_response:一个发送HTTP响应的函数。
    整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,把底层web服务器解析部分和应用程序逻辑部分进行了分离,这样开发者就可以专心做一个领域了

  • 不过,等等,这个application()函数怎么调用?如果我们自己调用,两个参数environstart_response我们没法提供,返回的str也没法发给浏览器。

  • 所以application()函数必须由WSGI服务器来调用。

WSGI服务器(web_server.py)

......

def deal_with_request(self, client_socket):
    environ = dict()
    environ['PATH_INFO'] = file_name
    # 存web返回的数据
    response_body = self.application(environ, self.set_response_headers)

    # 合并header和body
    response_header = "HTTP/1.1 {status}\r\n".format(self.status)
    response_header += "Content-Type: text/html; charset=utf-8\r\n"
    response_header += "Content-Length: %d\r\n" % len(response_body)
    for temp_head in self.headers:
        response_header += "{0}:{1}\r\n".format(*temp_head)

    response = response_header + "\r\n"
    response += response_body

    client_socket.send(response.encode('utf-8'))

def set_response_headers(self, status, headers):
        """这个方法,会在 web框架中被默认调用"""
        response_header_default = [
            ("Data", time.ctime()),
            ("Server", "ItCast-python mini web server")
        ]

        # 将状态码/相应头信息存储起来
        # [字符串, [xxxxx, xxx2]]
        self.status = status
        self.headers = response_header_default + headers

......