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)