V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
cc7756789
V2EX  ›  Python

WSGI 的 environ 是哪里来的

  •  1
     
  •   cc7756789 · 2015-06-14 18:00:22 +08:00 · 3268 次点击
    这是一个创建于 3447 天前的主题,其中的信息可能已经有所发展或是发生改变。
    environ是请求信息,但是environ是哪里来的呢,看了werkzeug的源码,只追溯到Request的基类BaseRequest类中 `self.environ = environ` 不明白这个environ是哪里来的!
    看werkzeug的文档的例子:
    ``` python
    from werkzeug.wrappers import Request, Response
    from werkzeug.serving import run_simple

    class Fish(object):
    def __init__(self, package_name):
    self.package_name = package_name
    self.debug = False

    def dispatch_request(self, request, environ):
    return Response('Hello \n%s!\n%s' % (environ or "World", request))

    def run(self, host="127.0.0.1", port=8000, **options):
    if 'debug' in options:
    self.debug = options.pop('debug')
    options.setdefault('use_reloader', self.debug)
    options.setdefault('use_debugger', self.debug)
    return run_simple(host, port, self, **options)

    def wsgi_app(self, environ, start_response):
    request = Request(environ)
    #start_response('200 OK', [('Content-Type', 'text/html')])
    response = self.dispatch_request(request, environ)
    return response(environ, start_response)

    def __call__(self, environ, start_response):
    return self.wsgi_app(environ, start_response)

    def create_app(package_name=None):
    app = Fish(package_name)
    return app

    if __name__ == '__main__':
    app = Fish(__name__)
    app.run(debug=True)
    ```

    浏览器返回:
    ```
    Hello
    {'wsgi.multiprocess': False, 'HTTP_COOKIE': 'CNZZDATA1254582975=2053663334-1430877964-%7C1430981140; csrftoken=3Tbk7YLoAjrq92l6SYoQQk0sr7Tb7mtz; session=.eJy9j1trgzAAhf-K5Fl07SYMwYeBWIQZcaQtcS2iMV7iJZ2JOFP877Pb2Nvexp7O0_m-c64gKdpUVFQA-_UKNPkVGbBBdjwosvX6OHIcsOjgmZd1rw30baRC0lwr-KCFF9r7rnMClZQXYZvmNE1GyXnZUoPwzkwJ4WMvhckfzTo_AX3td7TL6JB01PHSVlBwXvT_FqNh_CtvR405rTi_WX_RnHWQ1DmwvzUhIpsYNTN0qyZ09xZk0R1GsIl3kQoRfofMf4jZfo7R0-cMIoYikbyh_Q8CKv8eHr0aopcaI2IFW3-tts2KtcIVi5XHAoY3uPMVRgcW7AIVlLdXywf3RaYZ.CF0JVA.a_wB5LdgWoNgbnjdbA6g_WoCDy0', 'SERVER_SOFTWARE': 'Werkzeug/0.10.4', 'SCRIPT_NAME': '', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/saas', 'SERVER_PROTOCOL': 'HTTP/1.1', 'QUERY_STRING': '', 'werkzeug.server.shutdown': <function shutdown_server at 0x7f124c56a578>, 'CONTENT_LENGTH': '', 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36', 'HTTP_CONNECTION': 'keep-alive', 'SERVER_NAME': '127.0.0.1', 'REMOTE_PORT': 57239, 'wsgi.url_scheme': 'http', 'SERVER_PORT': '8000', 'werkzeug.request': <Request 'http://127.0.0.1:8000/saas' [GET]>, 'wsgi.input': <socket._fileobject object at 0x7f124c589650>, 'HTTP_HOST': '127.0.0.1:8000', 'wsgi.multithread': False, 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'HTTP_RA_SID': 'B47161C4-20140503-060942-d9d373-241f9a', 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'HTTP_RA_VER': '2.10.4', 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f124fa781e0>, 'REMOTE_ADDR': '127.0.0.1', 'HTTP_ACCEPT_LANGUAGE': 'en', 'CONTENT_TYPE': '', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, sdch'}!
    <Request 'http://127.0.0.1:8000/saas' [GET]>
    ```

    这个environ是dict对象,但是这些请求信息是从哪里得到的,并且怎么赋给environ的呢?
    6 条回复    2015-06-15 17:27:19 +08:00
    zjxubinbin
        1
    zjxubinbin  
       2015-06-14 18:06:12 +08:00 via Android
    Web服务器创建的。。。
    binux
        2
    binux  
       2015-06-14 20:20:22 +08:00 via Android
    WSGI 的 I 中来的
    zhuangzhuang1988
        3
    zhuangzhuang1988  
       2015-06-14 20:33:41 +08:00
    看werkzeug没用, werkzeug是wsgi工具包, 属于application这一端的
    environment是server端的
    可以看下这个http://ruslanspivak.com/archives.html 或者直接看wsgiref模块中的代码.
    raptium
        4
    raptium  
       2015-06-14 21:03:14 +08:00 via iPhone
    看一下什么是 wsgi 就知道了
    mywaiting
        5
    mywaiting  
       2015-06-14 22:25:47 +08:00
    先看看 pep333 咯,environ 是server 给 application的变量吧。CGI 的python版本

    找个 WSGI server版本的代码see see就立刻明白了。

    附带个tornado的wsgi的代码 https://github.com/tornadoweb/tornado/blob/master/tornado/wsgi.py#L319

    PS:Tornado自己是server,同时也是个 application框架
    julyclyde
        6
    julyclyde  
       2015-06-15 17:27:19 +08:00
    标准库WSGIHandler里有
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3307 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 11:41 · PVG 19:41 · LAX 03:41 · JFK 06:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.