Skip to content

Commit

Permalink
Made the handler a bit more robust. And added some comments in the code.
Browse files Browse the repository at this point in the history
  • Loading branch information
berry committed Aug 7, 2010
1 parent 4fdfe19 commit d4ef192
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 20 deletions.
2 changes: 1 addition & 1 deletion config.py
Expand Up @@ -9,7 +9,7 @@
chroot = "./",
pid_file = "/run/mongrel2-wsgi.pid",
default_host = HOST,
port = 6767
port = 80
)

handler_wsgi = Handler(send_spec = 'tcp://127.0.0.1:9997',
Expand Down
2 changes: 1 addition & 1 deletion run/mongrel2-wsgi.pid
@@ -1 +1 @@
953
1184
4 changes: 2 additions & 2 deletions test_wsgi_app.py
Expand Up @@ -61,7 +61,7 @@ def application(environ, start_response):
""" The WSGI test application """
# emit status / headers
status = "200 OK"
headers = [('Content-Type', 'text/html'), ]
headers = [('Content-Type', 'text/html;charset=utf-8'), ]
start_response(status, headers)

# assemble and return content
Expand All @@ -71,7 +71,7 @@ def application(environ, start_response):
'abs_path': os.path.abspath('.'),
'filename': __file__,
'python_path': repr(sys.path),
'wsgi_env': '\n'.join([row_template % item for item in environ.items()]),
'wsgi_env': '\n'.join([row_template % item for item in sorted(environ.items())]),
}
return [content.encode('utf-8')]

Expand Down
46 changes: 30 additions & 16 deletions wsgi-handler.py
Expand Up @@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-

import os, sys
from uuid import uuid4

from mongrel2 import handler
import json
Expand All @@ -12,12 +13,14 @@
except:
import StringIO

DEBUG = True
DEBUG = False

sender_id = "BA73C5F4-5ADA-4946-8980-1D255EB9A765"

conn = handler.Connection(sender_id, "tcp://127.0.0.1:9997",
"tcp://127.0.0.1:9996")
# setup connection handler
# sender_id is automatically generated
# so that each handler instance is uniquely identified
conn = handler.Connection(str(uuid4()),
"tcp://127.0.0.1:9997",
"tcp://127.0.0.1:9996")

def simple_app(environ, start_response):
"""Simplest possible WSGI application object"""
Expand All @@ -31,7 +34,7 @@ def encode_response(data, encoding='utf-8'):
return [d.encode(encoding) for d in data]

def simple_app_utf8(environ, start_response):
"""Simplest possible WSGI application object"""
"""Simplest possible WSGI application object with UTF-8"""
status = '200 OK'
response_headers = [('Content-type','text/plain; charset=utf-8')]
start_response(status, response_headers)
Expand All @@ -44,50 +47,60 @@ def wsgi_server(application):
Any encoding must be handled by the WSGI application itself.
'''

# TODO - this wsgi handler executes the application and renders a page
# in memory completely before returning it as a response to the client.
# Thus, it does not "stream" the result back to the client. It should be
# possible though. The SimpleHandler accepts file-like stream objects. So,
# it should be just a matter of connecting 0MQ requests/response streams to
# the SimpleHandler requests and response streams. However, the Python API
# for Mongrel2 doesn't seem to support file-like stream objects for requests
# and responses. Unless I have missed something.

while True:
if DEBUG: print "WAITING FOR REQUEST"

# receive a request
req = conn.recv()

if DEBUG: print "REQUEST BODY: %r\n" % req.body

if req.is_disconnect():
if DEBUG: print "DISCONNECT"
continue #effectively ignore the disconnect from the client

# Set a couple of environment attributes a.k.a. header attributes
# that are a must according to PEP 333
environ = req.headers
# Set a couple of environment attributes that are a must according to PEP 333
environ['SERVER_PROTOCOL'] = u'HTTP/1.1' # SimpleHandler expects a server_protocol
environ['SERVER_PROTOCOL'] = 'HTTP/1.1' # SimpleHandler expects a server_protocol, lets assume it is HTTP 1.1
environ['REQUEST_METHOD'] = environ['METHOD']
if ':' in environ['Host']:
environ['SERVER_NAME'] = environ['Host'].split(':')[0]
environ['SERVER_PORT'] = environ['Host'].split(':')[1]
else:
environ['SERVER_NAME'] = environ['Host']
environ['SERVER_PORT'] = '80'
environ['SERVER_PORT'] = ''
environ['SCRIPT_NAME'] = '' # empty for now
environ['PATH_INFO'] = environ['PATH']
if '?' in environ['URI']:
environ['QUERY_STRING'] = environ['URI'].split('?')[1]
else:
environ['QUERY_STRING'] = ''
try:
if environ.has_key('Content-Length'):
environ['CONTENT_LENGTH'] = environ['Content-Length'] # necessary for POST to work with Django
except:
pass
environ['wsgi.input'] = req.body

if DEBUG: print "ENVIRON: %r\n" % environ

# SimpleHandler needs file-like stream objects
# SimpleHandler needs file-like stream objects for
# requests, errors and reponses
reqIO = StringIO.StringIO(req.body)
errIO = StringIO.StringIO()
respIO = StringIO.StringIO()

# execute the application
handler = SimpleHandler(reqIO, respIO, errIO, environ, multithread = False, multiprocess = False)
handler.run(application)

# Get response and filter out the response (=data) itself,
# Get the response and filter out the response (=data) itself,
# the response headers,
# the response status code and the response status description
response = respIO.getvalue()
Expand All @@ -101,12 +114,13 @@ def wsgi_server(application):
# Especially the WSGI handler from Django seems to generate them (2 actually, huh?)
# a BOM isn't really necessary and cause HTML parsing errors in Chrome and Safari
# See also: http://www.xs4all.nl/~mechiel/projects/bomstrip/
# Although I still find this a ugly hack.
# Although I still find this a ugly hack, it does work.
data = data.replace('\xef\xbb\xbf', '')

# Get the generated errors
errors = errIO.getvalue()

# return the response
if DEBUG: print "RESPONSE: %r\n" % response
if errors:
if DEBUG: print "ERRORS: %r" % errors
Expand Down
Binary file modified wsgi.sqlite
Binary file not shown.

0 comments on commit d4ef192

Please sign in to comment.