Python Web开发中的WSGI协议简介(2)

首先是CGI规范中要求的变量:
  - REQUEST_METHOD: HTTP请求方法,'GET', 'POST'等,不能为空
  - SCRIPT_NAME: HTTP请求path中的初始部分,用来确定对应哪一个application,当application对应于服务器的根,可以为空
  - PATH_INFO: path中剩余的部分,application要处理的部分,可以为空
  - QUERY_STRING: HTTP请求中的查询字符串,URL中?后面的内容
  - CONTENT_TYPE: HTTP headers中的Content-Type内容
  - CONTENT_LENGTH: HTTP headers中的Content-Length内容
  - SERVER_NAMESERVER_PORT: 服务器域名和端口,这两个值和前面的SCRIPT_NAME, PATH_INFO拼起来可以得到完整的URL路径
  - SERVER_PROTOCOL: HTTP协议版本,'HTTP/1.0'或'HTTP/1.1'
  - HTTP_Variables: 和HTTP请求中的headers对应,比如'User-Agent'写成'HTTP_USER_AGENT'的格式

WSGI规范中还要求environ包含下列成员:
  - wsgi.version:一个元组(1, 0),表示WSGI版本1.0
  - wsgi.url_scheme:http或者https
  - wsgi.input:一个类文件的输入流,application可以通过这个获取HTTP请求的body
  - wsgi.errors:一个输出流,当应用程序出错时,可以将错误信息写入这里
  - wsgi.multithread:当application对象可能被多个线程同时调用时,这个值需要为True
  - wsgi.multiprocess:当application对象可能被多个进程同时调用时,这个值需要为True
  - wsgi.run_once:当server期望application对象在进程的生命周期内只被调用一次时,该值为True

我们可以使用python官方库wsgiref实现的server看一下environ的具体内容:

def demo_app(environ, start_response):

    from StringIO import StringIO

    stdout = StringIO()

    print >>stdout, "Hello world!"

    print >>stdout

    h = environ.items()

    h.sort()

    for k,v in h:

        print >>stdout, k,'=', repr(v)

    start_response("200 OK", [('Content-Type','text/plain')])

    return [stdout.getvalue()]

 

if __name__ == '__main__':

    from wsgiref.simple_server import make_server

    httpd = make_server('', 8000, demo_app)

    sa = httpd.socket.getsockname()

    print "Serving HTTP on", sa[0], "port", sa[1], "..."

    import webbrowser

    webbrowser.open('http://localhost:8000/xyz?abc')

    httpd.handle_request()  # serve one request, then exit

    httpd.server_close()

打开的网页会输出environ的具体内容。

使用environ组装请求URL地址:

from urllib.parse import quote

url = environ['wsgi.url_scheme']+'://'

 

if environ.get('HTTP_HOST'):

    url += environ['HTTP_HOST']

else:

    url += environ['SERVER_NAME']

 

    if environ['wsgi.url_scheme'] == 'https':

        if environ['SERVER_PORT'] != '443':

           url += ':' + environ['SERVER_PORT']

    else:

        if environ['SERVER_PORT'] != '80':

           url += ':' + environ['SERVER_PORT']

 

url += quote(environ.get('SCRIPT_NAME', ''))

url += quote(environ.get('PATH_INFO', ''))

if environ.get('QUERY_STRING'):

    url += '?' + environ['QUERY_STRING']

start_resposne

start_response是一个可调用对象,接收两个必选参数和一个可选参数:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5a18f0a52638df07849bb2b45c5090b7.html