Package pyamf :: Package remoting :: Package gateway :: Module wsgi
[hide private]
[frames] | no frames]

Source Code for Module pyamf.remoting.gateway.wsgi

  1  # Copyright (c) 2007-2008 The PyAMF Project. 
  2  # See LICENSE for details. 
  3   
  4  """ 
  5  WSGI server implementation. 
  6   
  7  The Python Web Server Gateway Interface (WSGI) is a simple and universal 
  8  interface between web servers and web applications or frameworks. 
  9   
 10  The WSGI interface has two sides: the "server" or "gateway" side, and the 
 11  "application" or "framework" side. The server side invokes a callable 
 12  object (usually a function or a method) that is provided by the application 
 13  side. Additionally WSGI provides middlewares; a WSGI middleware implements 
 14  both sides of the API, so that it can be inserted "between" a WSGI server 
 15  and a WSGI application -- the middleware will act as an application from 
 16  the server's point of view, and as a server from the application's point 
 17  of view. 
 18   
 19  @see: U{WSGI homepage (external)<http://wsgi.org>} 
 20  @see: U{PEP-333 (external)<http://www.python.org/peps/pep-0333.html>} 
 21   
 22  @author: U{Nick Joyce<mailto:nick@boxdesign.co.uk>} 
 23   
 24  @since: 0.1.0 
 25  """ 
 26   
 27  import pyamf 
 28  from pyamf import remoting 
 29  from pyamf.remoting import gateway 
 30   
 31  __all__ = ['WSGIGateway'] 
 32   
33 -class WSGIGateway(gateway.BaseGateway):
34 """ 35 WSGI Remoting Gateway. 36 """ 37
38 - def getResponse(self, request, environ):
39 """ 40 Processes the AMF request, returning an AMF response. 41 42 @param request: The AMF Request. 43 @type request: L{Envelope<pyamf.remoting.Envelope>} 44 @rtype: L{Envelope<pyamf.remoting.Envelope>} 45 @return: The AMF Response. 46 """ 47 response = remoting.Envelope(request.amfVersion, request.clientType) 48 49 for name, message in request: 50 processor = self.getProcessor(message) 51 response[name] = processor(message, http_request=environ) 52 53 return response
54
55 - def badRequestMethod(self, environ, start_response):
56 """ 57 Return HTTP 400 Bad Request. 58 """ 59 response = "400 Bad Request\n\nTo access this PyAMF gateway you " \ 60 "must use POST requests (%s received)" % environ['REQUEST_METHOD'] 61 62 start_response('400 Bad Request', [ 63 ('Content-Type', 'text/plain'), 64 ('Content-Length', str(len(response))), 65 ]) 66 67 return [response]
68
69 - def __call__(self, environ, start_response):
70 """ 71 @rtype: C{StringIO} 72 @return: File-like object. 73 """ 74 if environ['REQUEST_METHOD'] != 'POST': 75 return self.badRequestMethod(environ, start_response) 76 77 body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) 78 stream = None 79 80 context = pyamf.get_context(pyamf.AMF0) 81 82 # Decode the request 83 try: 84 request = remoting.decode(body, context) 85 except pyamf.DecodeError: 86 self.logger.debug(gateway.format_exception()) 87 88 response = "400 Bad Request\n\nThe request body was unable to " \ 89 "be successfully decoded." 90 91 if self.debug: 92 response += "\n\nTraceback:\n\n%s" % gateway.format_exception() 93 94 start_response('400 Bad Request', [ 95 ('Content-Type', 'text/plain'), 96 ('Content-Length', str(len(response))), 97 ]) 98 99 return [response] 100 101 # Process the request 102 try: 103 response = self.getResponse(request, environ) 104 except (KeyboardInterrupt, SystemExit): 105 raise 106 except: 107 self.logger.debug(gateway.format_exception()) 108 109 response = "500 Internal Server Error\n\nThe request was " \ 110 "unable to be successfully processed." 111 112 if self.debug: 113 response += "\n\nTraceback:\n\n%s" % gateway.format_exception() 114 115 start_response('500 Internal Server Error', [ 116 ('Content-Type', 'text/plain'), 117 ('Content-Length', str(len(response))), 118 ]) 119 120 return [response] 121 122 # Encode the response 123 try: 124 stream = remoting.encode(response, context) 125 except pyamf.EncodeError: 126 self.logger.debug(gateway.format_exception()) 127 128 response = "500 Internal Server Error\n\nThe request was " \ 129 "unable to be encoded." 130 131 if self.debug: 132 response += "\n\nTraceback:\n\n%s" % gateway.format_exception() 133 134 start_response('500 Internal Server Error', [ 135 ('Content-Type', 'text/plain'), 136 ('Content-Length', str(len(response))), 137 ]) 138 139 return [response] 140 141 response = stream.getvalue() 142 143 start_response('200 OK', [ 144 ('Content-Type', remoting.CONTENT_TYPE), 145 ('Content-Length', str(len(response))), 146 ]) 147 148 return [response]
149