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-2009 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  @since: 0.1.0 
 23  """ 
 24   
 25  import pyamf 
 26  from pyamf import remoting 
 27  from pyamf.remoting import gateway 
 28   
 29  __all__ = ['WSGIGateway'] 
 30   
31 -class WSGIGateway(gateway.BaseGateway):
32 """ 33 WSGI Remoting Gateway. 34 """ 35
36 - def getResponse(self, request, environ):
37 """ 38 Processes the AMF request, returning an AMF response. 39 40 @param request: The AMF Request. 41 @type request: L{Envelope<pyamf.remoting.Envelope>} 42 @rtype: L{Envelope<pyamf.remoting.Envelope>} 43 @return: The AMF Response. 44 """ 45 response = remoting.Envelope(request.amfVersion, request.clientType) 46 47 for name, message in request: 48 processor = self.getProcessor(message) 49 response[name] = processor(message, http_request=environ) 50 51 return response
52
53 - def badRequestMethod(self, environ, start_response):
54 """ 55 Return HTTP 400 Bad Request. 56 """ 57 response = "400 Bad Request\n\nTo access this PyAMF gateway you " \ 58 "must use POST requests (%s received)" % environ['REQUEST_METHOD'] 59 60 start_response('400 Bad Request', [ 61 ('Content-Type', 'text/plain'), 62 ('Content-Length', str(len(response))), 63 ('Server', gateway.SERVER_NAME), 64 ]) 65 66 return [response]
67
68 - def __call__(self, environ, start_response):
69 """ 70 @rtype: C{StringIO} 71 @return: File-like object. 72 """ 73 if environ['REQUEST_METHOD'] != 'POST': 74 return self.badRequestMethod(environ, start_response) 75 76 body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) 77 stream = None 78 79 context = pyamf.get_context(pyamf.AMF0) 80 81 # Decode the request 82 try: 83 request = remoting.decode(body, context, strict=self.strict) 84 except (pyamf.DecodeError, EOFError): 85 self.logger.exception(gateway.format_exception()) 86 87 response = "400 Bad Request\n\nThe request body was unable to " \ 88 "be successfully decoded." 89 90 if self.debug: 91 response += "\n\nTraceback:\n\n%s" % gateway.format_exception() 92 93 start_response('400 Bad Request', [ 94 ('Content-Type', 'text/plain'), 95 ('Content-Length', str(len(response))), 96 ('Server', gateway.SERVER_NAME), 97 ]) 98 99 return [response] 100 except (KeyboardInterrupt, SystemExit): 101 raise 102 except: 103 self.logger.exception(gateway.format_exception()) 104 105 response = "500 Internal Server Error\n\nAn unexpected error occurred whilst decoding." 106 107 if self.debug: 108 response += "\n\nTraceback:\n\n%s" % gateway.format_exception() 109 110 start_response('500 Internal Server Error', [ 111 ('Content-Type', 'text/plain'), 112 ('Content-Length', str(len(response))), 113 ('Server', gateway.SERVER_NAME), 114 ]) 115 116 return [response] 117 118 self.logger.debug("AMF Request: %r" % request) 119 120 # Process the request 121 try: 122 response = self.getResponse(request, environ) 123 except (KeyboardInterrupt, SystemExit): 124 raise 125 except: 126 self.logger.exception(gateway.format_exception()) 127 128 response = "500 Internal Server Error\n\nThe request was " \ 129 "unable to be successfully processed." 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 ('Server', gateway.SERVER_NAME), 138 ]) 139 140 return [response] 141 142 self.logger.debug("AMF Response: %r" % response) 143 144 # Encode the response 145 try: 146 stream = remoting.encode(response, context, strict=self.strict) 147 except: 148 self.logger.exception(gateway.format_exception()) 149 150 response = "500 Internal Server Error\n\nThe request was " \ 151 "unable to be encoded." 152 153 if self.debug: 154 response += "\n\nTraceback:\n\n%s" % gateway.format_exception() 155 156 start_response('500 Internal Server Error', [ 157 ('Content-Type', 'text/plain'), 158 ('Content-Length', str(len(response))), 159 ('Server', gateway.SERVER_NAME), 160 ]) 161 162 return [response] 163 164 response = stream.getvalue() 165 166 start_response('200 OK', [ 167 ('Content-Type', remoting.CONTENT_TYPE), 168 ('Content-Length', str(len(response))), 169 ('Server', gateway.SERVER_NAME), 170 ]) 171 172 return [response]
173