Back to index

moin  1.9.0~rc2
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions | Private Attributes
MoinMoin.support.flup.server.ajp_base.BaseAJPServer Class Reference

List of all members.

Public Member Functions

def __init__
def handler
def error

Public Attributes

 application
 scriptName
 environ
 multithreaded
 multiprocess
 debug
 logger

Static Public Attributes

 requestClass = Request
int inputStreamShrinkThreshold = 102400

Private Member Functions

def _setupSocket
def _cleanupSocket
def _isClientAllowed
def _sanitizeEnv

Private Attributes

 _bindAddress
 _allowedServers
 _appLock

Detailed Description

Definition at line 741 of file ajp_base.py.


Constructor & Destructor Documentation

def MoinMoin.support.flup.server.ajp_base.BaseAJPServer.__init__ (   self,
  application,
  scriptName = '',
  environ = None,
  multithreaded = True,
  multiprocess = False,
  bindAddress = ('localhost', 8009,
  allowedServers = NoDefault,
  loggingLevel = logging.INFO,
  debug = False 
)
scriptName is the initial portion of the URL path that "belongs"
to your application. It is used to determine PATH_INFO (which doesn't
seem to be passed in). An empty scriptName means your application
is mounted at the root of your virtual host.

environ, which must be a dictionary, can contain any additional
environment variables you want to pass to your application.

Set multithreaded to False if your application is not thread-safe.

Set multiprocess to True to explicitly set wsgi.multiprocess to
True. (Only makes sense with threaded servers.)

bindAddress is the address to bind to, which must be a tuple of
length 2. The first element is a string, which is the host name
or IPv4 address of a local interface. The 2nd element is the port
number.

allowedServers must be None or a list of strings representing the
IPv4 addresses of servers allowed to connect. None means accept
connections from anywhere. By default, it is a list containing
the single item '127.0.0.1'.

loggingLevel sets the logging level of the module-level logger.

Definition at line 754 of file ajp_base.py.

00754 
00755                  loggingLevel=logging.INFO, debug=False):
00756         """
00757         scriptName is the initial portion of the URL path that "belongs"
00758         to your application. It is used to determine PATH_INFO (which doesn't
00759         seem to be passed in). An empty scriptName means your application
00760         is mounted at the root of your virtual host.
00761 
00762         environ, which must be a dictionary, can contain any additional
00763         environment variables you want to pass to your application.
00764 
00765         Set multithreaded to False if your application is not thread-safe.
00766 
00767         Set multiprocess to True to explicitly set wsgi.multiprocess to
00768         True. (Only makes sense with threaded servers.)
00769 
00770         bindAddress is the address to bind to, which must be a tuple of
00771         length 2. The first element is a string, which is the host name
00772         or IPv4 address of a local interface. The 2nd element is the port
00773         number.
00774 
00775         allowedServers must be None or a list of strings representing the
00776         IPv4 addresses of servers allowed to connect. None means accept
00777         connections from anywhere. By default, it is a list containing
00778         the single item '127.0.0.1'.
00779 
00780         loggingLevel sets the logging level of the module-level logger.
00781         """
00782         if environ is None:
00783             environ = {}
00784 
00785         self.application = application
00786         self.scriptName = scriptName
00787         self.environ = environ
00788         self.multithreaded = multithreaded
00789         self.multiprocess = multiprocess
00790         self.debug = debug
00791         self._bindAddress = bindAddress
00792         if allowedServers is NoDefault:
00793             allowedServers = ['127.0.0.1']
00794         self._allowedServers = allowedServers
00795 
00796         # Used to force single-threadedness.
00797         self._appLock = thread.allocate_lock()
00798 
00799         self.logger = logging.getLogger(LoggerName)
00800         self.logger.setLevel(loggingLevel)


Member Function Documentation

Closes the main socket.

Definition at line 809 of file ajp_base.py.

00809 
00810     def _cleanupSocket(self, sock):
00811         """Closes the main socket."""
00812         sock.close()

Here is the caller graph for this function:

Definition at line 813 of file ajp_base.py.

00813 
00814     def _isClientAllowed(self, addr):
00815         ret = self._allowedServers is None or addr[0] in self._allowedServers
00816         if not ret:
00817             self.logger.warning('Server connection from %s disallowed',
00818                                 addr[0])
00819         return ret

Here is the caller graph for this function:

Fill-in/deduce missing values in environ.

Definition at line 915 of file ajp_base.py.

00915 
00916     def _sanitizeEnv(self, environ):
00917         """Fill-in/deduce missing values in environ."""
00918         # Namely SCRIPT_NAME/PATH_INFO
00919         value = environ['REQUEST_URI']
00920         scriptName = environ.get('WSGI_SCRIPT_NAME', self.scriptName)
00921         if not value.startswith(scriptName):
00922             self.logger.warning('scriptName does not match request URI')
00923 
00924         environ['PATH_INFO'] = value[len(scriptName):]
00925         environ['SCRIPT_NAME'] = scriptName
00926 
00927         reqUri = None
00928         if environ.has_key('REQUEST_URI'):
00929             reqUri = environ['REQUEST_URI'].split('?', 1)
00930 
00931         if not environ.has_key('QUERY_STRING') or not environ['QUERY_STRING']:
00932             if reqUri is not None and len(reqUri) > 1:
00933                 environ['QUERY_STRING'] = reqUri[1]
00934             else:
00935                 environ['QUERY_STRING'] = ''

Here is the caller graph for this function:

Creates and binds the socket for communication with the server.

Definition at line 801 of file ajp_base.py.

00801 
00802     def _setupSocket(self):
00803         """Creates and binds the socket for communication with the server."""
00804         sock = socket.socket()
00805         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
00806         sock.bind(self._bindAddress)
00807         sock.listen(socket.SOMAXCONN)
00808         return sock

Here is the caller graph for this function:

Override to provide custom error handling. Ideally, however,
all errors should be caught at the application level.

Definition at line 936 of file ajp_base.py.

00936 
00937     def error(self, request):
00938         """
00939         Override to provide custom error handling. Ideally, however,
00940         all errors should be caught at the application level.
00941         """
00942         if self.debug:
00943             request.startResponse(200, 'OK', [('Content-Type', 'text/html')])
00944             import cgitb
00945             request.write(cgitb.html(sys.exc_info()))
00946         else:
00947             errorpage = """<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
00948 <html><head>
00949 <title>Unhandled Exception</title>
00950 </head><body>
00951 <h1>Unhandled Exception</h1>
00952 <p>An unhandled exception was thrown by the application.</p>
00953 </body></html>
00954 """
00955             request.startResponse(200, 'OK', [('Content-Type', 'text/html')])
00956             request.write(errorpage)
WSGI handler. Sets up WSGI environment, calls the application,
and sends the application's response.

Definition at line 820 of file ajp_base.py.

00820 
00821     def handler(self, request):
00822         """
00823         WSGI handler. Sets up WSGI environment, calls the application,
00824         and sends the application's response.
00825         """
00826         environ = request.environ
00827         environ.update(self.environ)
00828 
00829         environ['wsgi.version'] = (1,0)
00830         environ['wsgi.input'] = request.input
00831         environ['wsgi.errors'] = sys.stderr
00832         environ['wsgi.multithread'] = self.multithreaded
00833         environ['wsgi.multiprocess'] = self.multiprocess
00834         environ['wsgi.run_once'] = False
00835 
00836         if environ.get('HTTPS', 'off') in ('on', '1'):
00837             environ['wsgi.url_scheme'] = 'https'
00838         else:
00839             environ['wsgi.url_scheme'] = 'http'
00840 
00841         self._sanitizeEnv(environ)
00842 
00843         headers_set = []
00844         headers_sent = []
00845         result = None
00846 
00847         def write(data):
00848             assert type(data) is str, 'write() argument must be string'
00849             assert headers_set, 'write() before start_response()'
00850 
00851             if not headers_sent:
00852                 status, responseHeaders = headers_sent[:] = headers_set
00853                 statusCode = int(status[:3])
00854                 statusMsg = status[4:]
00855                 found = False
00856                 for header,value in responseHeaders:
00857                     if header.lower() == 'content-length':
00858                         found = True
00859                         break
00860                 if not found and result is not None:
00861                     try:
00862                         if len(result) == 1:
00863                             responseHeaders.append(('Content-Length',
00864                                                     str(len(data))))
00865                     except:
00866                         pass
00867                 request.startResponse(statusCode, statusMsg, responseHeaders)
00868 
00869             request.write(data)
00870 
00871         def start_response(status, response_headers, exc_info=None):
00872             if exc_info:
00873                 try:
00874                     if headers_sent:
00875                         # Re-raise if too late
00876                         raise exc_info[0], exc_info[1], exc_info[2]
00877                 finally:
00878                     exc_info = None # avoid dangling circular ref
00879             else:
00880                 assert not headers_set, 'Headers already set!'
00881 
00882             assert type(status) is str, 'Status must be a string'
00883             assert len(status) >= 4, 'Status must be at least 4 characters'
00884             assert int(status[:3]), 'Status must begin with 3-digit code'
00885             assert status[3] == ' ', 'Status must have a space after code'
00886             assert type(response_headers) is list, 'Headers must be a list'
00887             if __debug__:
00888                 for name,val in response_headers:
00889                     assert type(name) is str, 'Header name "%s" must be a string' % name
00890                     assert type(val) is str, 'Value of header "%s" must be a string' % name
00891 
00892             headers_set[:] = [status, response_headers]
00893             return write
00894 
00895         if not self.multithreaded:
00896             self._appLock.acquire()
00897         try:
00898             try:
00899                 result = self.application(environ, start_response)
00900                 try:
00901                     for data in result:
00902                         if data:
00903                             write(data)
00904                     if not headers_sent:
00905                         write('') # in case body was empty
00906                 finally:
00907                     if hasattr(result, 'close'):
00908                         result.close()
00909             except socket.error, e:
00910                 if e[0] != errno.EPIPE:
00911                     raise # Don't let EPIPE propagate beyond server
00912         finally:
00913             if not self.multithreaded:
00914                 self._appLock.release()

Here is the call graph for this function:


Member Data Documentation

Definition at line 793 of file ajp_base.py.

Definition at line 796 of file ajp_base.py.

Definition at line 790 of file ajp_base.py.

Definition at line 784 of file ajp_base.py.

Definition at line 789 of file ajp_base.py.

Definition at line 786 of file ajp_base.py.

Definition at line 749 of file ajp_base.py.

Definition at line 798 of file ajp_base.py.

Definition at line 788 of file ajp_base.py.

Definition at line 787 of file ajp_base.py.

Definition at line 743 of file ajp_base.py.

Definition at line 785 of file ajp_base.py.


The documentation for this class was generated from the following file: