猫型エンジニアのブログ

プログラム/ネットワーク系の技術関連をまとめたページです 

WSGIServerの実行例

 wsgiの実装例としてLib/wsgiref/simple_server.pyからソースコードを抜粋しました。

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import urllib, sys
from wsgiref.handlers import SimpleHandler

__version__ = "0.1"
__all__ = ['WSGIServer', 'WSGIRequestHandler', 'demo_app', 'make_server']


server_version = "WSGIServer/" + __version__
sys_version = "Python/" + sys.version.split()[0]
software_version = server_version + ' ' + sys_version


class ServerHandler(SimpleHandler):

    server_software = software_version

    def close(self):
        try:
            self.request_handler.log_request(
                self.status.split(' ',1)[0], self.bytes_sent
            )
        finally:
            SimpleHandler.close(self)

class WSGIServer(HTTPServer):

    """BaseHTTPServer that implements the Python WSGI protocol"""

    application = None

    def server_bind(self):
        """Override server_bind to store the server name."""
        HTTPServer.server_bind(self)
        self.setup_environ()

    def setup_environ(self):
        # Set up base environment
        env = self.base_environ = {}
        env['SERVER_NAME'] = self.server_name
        env['GATEWAY_INTERFACE'] = 'CGI/1.1'
        env['SERVER_PORT'] = str(self.server_port)
        env['REMOTE_HOST']=''
        env['CONTENT_LENGTH']=''
        env['SCRIPT_NAME'] = ''

    def get_app(self):
        return self.application

    def set_app(self,application):
        self.application = application

class WSGIRequestHandler(BaseHTTPRequestHandler):

    server_version = "WSGIServer/" + __version__

    def get_environ(self):
        env = self.server.base_environ.copy()
        env['SERVER_PROTOCOL'] = self.request_version
        env['REQUEST_METHOD'] = self.command
        if '?' in self.path:
            path,query = self.path.split('?',1)
        else:
            path,query = self.path,''

        env['PATH_INFO'] = urllib.unquote(path)
        env['QUERY_STRING'] = query

        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]

        if self.headers.typeheader is None:
            env['CONTENT_TYPE'] = self.headers.type
        else:
            env['CONTENT_TYPE'] = self.headers.typeheader

        length = self.headers.getheader('content-length')
        if length:
            env['CONTENT_LENGTH'] = length

        for h in self.headers.headers:
            k,v = h.split(':',1)
            k=k.replace('-','_').upper(); v=v.strip()
            if k in env:
                continue                    # skip content length, type,etc.
            if 'HTTP_'+k in env:
                env['HTTP_'+k] += ','+v     # comma-separate multiple headers
            else:
                env['HTTP_'+k] = v
        return env

    def get_stderr(self):
        return sys.stderr

    def handle(self):
        """Handle a single HTTP request"""

        self.raw_requestline = self.rfile.readline()
        if not self.parse_request(): # An error code has been sent, just exit
            return

        handler = ServerHandler(
            self.rfile, self.wfile, self.get_stderr(), self.get_environ()
        )
        handler.request_handler = self      # backpointer for logging
        handler.run(self.server.get_app())

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()]


def make_server(
    host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
):
    """Create a new WSGI server listening on `host` and `port` for `app`"""
    server = server_class((host, port), handler_class)
    server.set_app(app)
    return server


if __name__ == '__main__':
    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()  

実際に実行して8000番ポートにブラウザからアクセスすると、以下のような大量の情報がブラウザ上に表示されます。

[root@localhost wsgiref]# cd /usr/lib64/python2.6/wsgiref/
[root@localhost wsgiref]# python simple_server.py
Serving HTTP on 0.0.0.0 port 8000 ...
Hello world!

COLORTERM = 'gnome-terminal'
CONTENT_LENGTH = ''
CONTENT_TYPE = 'text/plain'
CVS_RSH = 'ssh'
DBUS_SESSION_BUS_ADDRESS = 'unix:abstract=/tmp/dbus-Q75qSg2XCm,guid=97f398c334189eba2aefb1970000010b'
DESKTOP_SESSION = 'gnome'
DISPLAY = ':0.0'
GATEWAY_INTERFACE = 'CGI/1.1'
GDMSESSION = 'gnome'
GDM_KEYBOARD_LAYOUT = 'us'
GDM_LANG = 'en_US.UTF-8'
GNOME_DESKTOP_SESSION_ID = 'this-is-deprecated'
GNOME_KEYRING_PID = '1947'
GNOME_KEYRING_SOCKET = '/tmp/keyring-sRQNbb/socket'
GTK_RC_FILES = '/etc/gtk/gtkrc:/root/.gtkrc-1.2-gnome2'
G_BROKEN_FILENAMES = '1'
HISTCONTROL = 'ignoredups'
HISTSIZE = '1000'
HOME = '/root'
HOSTNAME = 'localhost.localdomain'
HTTP_ACCEPT = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
HTTP_ACCEPT_ENCODING = 'gzip, deflate'
HTTP_ACCEPT_LANGUAGE = 'ja,en-us;q=0.7,en;q=0.3'
HTTP_CONNECTION = 'keep-alive'
HTTP_DNT = '1'
HTTP_HOST = '10.0.1.7:8000'
HTTP_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:34.0) Gecko/20100101 Firefox/34.0'
IMSETTINGS_INTEGRATE_DESKTOP = 'yes'
IMSETTINGS_MODULE = 'none'
LANG = 'en_US.UTF-8'
LESSOPEN = '|/usr/bin/lesspipe.sh %s'
LOGNAME = 'root'
LS_COLORS = 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:'
MAIL = '/var/spool/mail/root'
OLDPWD = '/lib64'
ORBIT_SOCKETDIR = '/tmp/orbit-root'
PATH = '/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/root/bin'
PATH_INFO = '/'
PWD = '/usr/lib64/python2.6/wsgiref'
QTDIR = '/usr/lib64/qt-3.3'
QTINC = '/usr/lib64/qt-3.3/include'
QTLIB = '/usr/lib64/qt-3.3/lib'
QT_IM_MODULE = 'xim'
QUERY_STRING = ''
REMOTE_ADDR = '10.0.1.2'
REMOTE_HOST = ''
REQUEST_METHOD = 'GET'
SCRIPT_NAME = ''
SERVER_NAME = 'localhost.localdomain'
SERVER_PORT = '8000'
SERVER_PROTOCOL = 'HTTP/1.1'
SERVER_SOFTWARE = 'WSGIServer/0.1 Python/2.6.6'
SESSION_MANAGER = 'local/unix:@/tmp/.ICE-unix/1957,unix/unix:/tmp/.ICE-unix/1957'
SHELL = '/bin/bash'
SHLVL = '2'
SSH_ASKPASS = '/usr/libexec/openssh/gnome-ssh-askpass'
SSH_AUTH_SOCK = '/tmp/keyring-sRQNbb/socket.ssh'
TERM = 'xterm'
USER = 'root'
USERNAME = 'root'
WINDOWID = '33554436'
WINDOWPATH = '1'
XAUTHORITY = '/var/run/gdm/auth-for-root-SCBTZQ/database'
XDG_SESSION_COOKIE = '2780697f3861dd2134f1b9110000000a-1418913605.305328-632139448'
XMODIFIERS = '@im=none'
_ = '/usr/bin/python'
wsgi.errors = <open file '<stderr>', mode 'w' at 0x7f582d2f91e0>
wsgi.file_wrapper = <class wsgiref.util.FileWrapper at 0x7f58256af650>
wsgi.input = <socket._fileobject object at 0x7f58256aa650>
wsgi.multiprocess = False
wsgi.multithread = True
wsgi.run_once = False
wsgi.url_scheme = 'http'
wsgi.version = (1, 0)