diff options
| -rwxr-xr-x | paste/server.py | 4 | ||||
| -rw-r--r-- | paste/twisted_wsgi.py | 247 |
2 files changed, 1 insertions, 250 deletions
diff --git a/paste/server.py b/paste/server.py index b6a63e1..a36c636 100755 --- a/paste/server.py +++ b/paste/server.py @@ -159,9 +159,7 @@ def help(): return help_message % {'program': program} def twisted_serve(conf, app): - from paste.twisted_wsgi import serve_application - serve_application( - app, port=int(conf.get('port', 8080))) + print 'Twisted support has been temporarily removed from Paste.' servers['twisted'] = twisted_serve diff --git a/paste/twisted_wsgi.py b/paste/twisted_wsgi.py deleted file mode 100644 index 022180e..0000000 --- a/paste/twisted_wsgi.py +++ /dev/null @@ -1,247 +0,0 @@ -# By Peter Hunt -# The canonical location for this file: http://st0rm.hopto.org:8080/wsgi/ - -# new twisted.wsgi resource which uses the wsgiref library, available -# at http://cvs.eby-sarna.com/wsgiref/ - -from wsgiref import handlers - -from twisted.web import resource, server, static -from twisted.internet import reactor -from twisted.python import log -from twisted import copyright - -import string -import sys -import os -import time -import urllib -import types -# TODO: sendfile()! - -class WSGIResource(resource.Resource): - isLeaf = True - def __init__(self, application, async=False): - """ - application - WSGI application to host - async - is the application guaranteed to NOT block? - """ - resource.Resource.__init__(self) - self.application = application - self.async = async - def render(self, request): - TwistedHandler(self.application, request, self.async) - return server.NOT_DONE_YET - -class LogWrapper: - def write(self, msg): - log.err(msg) - def flush(self): - pass - -log_wrapper = LogWrapper() - -class TwistedHandler(handlers.BaseHandler): - origin_server = True - server_software = server.version - def __init__(self, application, request, async=False): - self.request = request - if async: - self.run_async(application) - else: - reactor.callInThread(self.run, application) - def async_finish_response(self): - """Reads the next block of data yielded from the application generator, similar to finish_response except for async apps""" - if not self.result_is_file() and not self.sendfile(): - if isinstance(self.result, types.GeneratorType): - while True: - try: - data = self.result.next() - if len(data) == 0: - break # till next time folks! - else: - self._write(data) - except StopIteration: - self.close() # we're done - break - else: - self.finish_response() - else: - self.close() - def _resume(self): - reactor.callLater(0, self.async_finish_response) - def run_async(self, application): - try: - self.setup_environ() - self.environ["twisted.wsgi.resume"] = self._resume - self.result = application(self.environ, self.start_response) - self.async_finish_response() - except: - import traceback - traceback.print_exc() - try: - self.handle_error() - except: - # If we get an error handling an error, just give up already! - self.close() - raise # ...and let the actual server figure it out. - def run(self, application): - """Invoke the application synchronously""" - # Note to self: don't move the close()! Asynchronous servers shouldn't - # call close() from finish_response(), so if you close() anywhere but - # the double-error branch here, you'll break asynchronous servers by - # prematurely closing. Async servers must return from 'run()' without - # closing if there might still be output to iterate over. - try: - self.setup_environ() - self.result = application(self.environ, self.start_response) - self.finish_response() - except: - try: - self.handle_error() - except: - # If we get an error handling an error, just give up already! - self.close() - raise # ...and let the actual server figure it out. - def close(self): - handlers.BaseHandler.close(self) - self.request.finish() - def send_headers(self): - """OVERRIDE ME!""" - self.cleanup_headers() - self.headers_sent = True - if self.client_is_modern(): - self.send_preamble() - for (h,v) in self.headers.items(): - self.request.setHeader(h, v) - def send_preamble(self): - """Transmit version/status/date/server, via self._write()""" - if self.client_is_modern(): - code,message = self.status.split(" ",1) - self.request.setResponseCode(int(code), message) - if not self.headers.has_key('Date'): - self.headers.add_header('Date', time.asctime(time.gmtime(time.time()))) - if self.server_software and not self.headers.has_key('Server'): - self.headers.add_header('Server', self.server_software) - def _write(self,data): - """Override in subclass to buffer data for send to client - - It's okay if this method actually transmits the data; BaseHandler - just separates write and flush operations for greater efficiency - when the underlying system actually has such a distinction. - """ - self.request.write(data) - - def _flush(self): - """Override in subclass to force sending of recent '_write()' calls - - It's okay if this method is a no-op (i.e., if '_write()' actually - sends the data. - """ - # no-op - #self.request.flush() - - def get_stdin(self): - """Override in subclass to return suitable 'wsgi.input'""" - self.request.content.seek(0) - return self.request.content - - def get_stderr(self): - """Override in subclass to return suitable 'wsgi.errors'""" - return log_wrapper - - def add_cgi_vars(self): - """Override in subclass to insert CGI variables in 'self.environ'""" - script_name = "/"+string.join(self.request.prepath, '/') - serverName = string.split(self.request.getRequestHostname(), ':')[0] - if float(copyright.version[:3]) >= 1.3: - port = str(self.request.getHost().port) - else: - port = str(self.request.getHost()[2]) - - env = {"SERVER_SOFTWARE": server.version, - "SERVER_NAME": serverName, - "GATEWAY_INTERFACE": "CGI/1.1", - "SERVER_PROTOCOL": self.request.clientproto, - "SERVER_PORT": port, - "REQUEST_METHOD": self.request.method, - "SCRIPT_NAME": script_name, # XXX - "SCRIPT_FILENAME": "[wsgi application]", - "REQUEST_URI": self.request.uri, - "SCRIPT_URI": self.request.uri, - "SCRIPT_URL": self.request.path - } - - client = self.request.getClient() - if client is not None: - env['REMOTE_HOST'] = client - ip = self.request.getClientIP() - if ip is not None: - env['REMOTE_ADDR'] = ip - pp = self.request.postpath - if pp: - env["PATH_INFO"] = "/"+string.join(pp, '/') - - qindex = string.find(self.request.uri, '?') - if qindex != -1: - qs = env['QUERY_STRING'] = self.request.uri[qindex+1:] - if '=' in qs: - qargs = [] - else: - qargs = [urllib.unquote(x) for x in qs.split('+')] - else: - env['QUERY_STRING'] = '' - qargs = [] - - # Propogate HTTP headers - for title, header in self.request.getAllHeaders().items(): - envname = string.upper(string.replace(title, '-', '_')) - if title not in ('content-type', 'content-length'): - envname = "HTTP_" + envname - env[envname] = header - # Propogate our environment - # dont need to do this since we're updating old environ - #for key, value in os.environ.items(): - # if not env.has_key(key): - # env[key] = value - self.environ.update(env) - -# simple little delayed processing app -from twisted.internet import defer - -def blocking_call(): - d = defer.Deferred() - reactor.callLater(2, d.callback, None) - return d - -def phase2(result, environ): - environ["thetime"] = time.time() - environ["twisted.wsgi.resume"]() - -def blocking_async_app(environ, start_response): - write = start_response("200 OK", [("Content-type","text/plain")]) - yield "the time right now is " + `time.time()` + "\n" - blocking_call().addCallback(phase2, environ) - yield "" - yield "the time now is " + `environ["thetime"]` - -def serve_application(application, port=8080, async=False): - resource = WSGIResource(application, async=async) - reactor.listenTCP(port, server.Site(resource)) - reactor.run() - -if __name__ == "__main__": - import sys - import optparse - from paste.webkit.wsgiwebkit import webkit - parser = optparse.OptionParser() - parser.add_option('-p', '--port', dest='port', - default=8080, type='int', - help="Port to serve on (default 8080)") - options, args = parser.parse_args() - if not len(args) == 1: - print "You must give one path, which is the root of your application" - sys.exit(2) - app = webkit(args[0]) - serve_application(app, port=options.port) - |
