Beispiel #1
0
 def dispatch(self, conn, src_addr, dst_addr):
     
     env     = self.base_environ.copy()        
     status  = '200 OK'
     
     headers         = []    # Populated by start_response()
     headers_sent    = []
     
     def write(value):
         
         # Write or queue value
         if not headers_set:
             raise AssertionError("write() before start_response()")
         pass
     
     def start_response(status, response_headers, exc_info=None):
         
         status          = status
         headers_sent    = response_headers
         
         messages.send_response(    
             conn,
             int(status.split(' ')[0]),
             message =status.split(' ')[1],
             version ='HTTP/1.1',
             headers = response_headers
         )
         return write
     
     logging.debug('Grabbing request...')
     req = (
         req_method,
         req_uri,
         req_version,
         req_headers
     ) = messages.get_request(conn)
     
     # Determine the app
     # Call the app
     logging.debug('Calling App...')
     r = hello_world_app(env, start_response)
                 
     logging.debug('Sending response...')
     conn.sendall(''.join(r))
Beispiel #2
0
 def __dispatch(self, conn, src_addr, dst_addr):
     
     req_count = 0
     
     while True:
         
         req_count += 1
         
         env     = self._env(src_addr, dst_addr)
         status  = '200 OK'
         
         headers         = []    # Populated by start_response()
         headers_sent    = []
         
         def write(value):
             
             # Write or queue value
             if not headers_set:
                 raise AssertionError("write() before start_response()")
             pass
         
         def start_response(status, response_headers, exc_info=None):
             
             status          = status                # Update the non-local var "status"
             headers_sent    = response_headers      # Update the non-local var "headers_sent"
             
             messages.send_response_line(            # Send request-line on the wire
                 conn,
                 int(status.split(' ')[0]),
                 status.split(' ')[1],
                 version = WSGI.http_ver
             )
             for k, v in response_headers:
                 messages.send_header(conn, k, v)    # Send some headers on the wire
             
             return write
         
         try:
             
             req = (
                 req_method,
                 req_uri,
                 req_version,
                 req_headers
             ) = messages.get_request(conn)
         except:
             logging.error('Failed retrieving request!', exc_info=3)
             req = None
             break
         
         (scheme, netloc, path, query, fragment) = urlparse.urlsplit(req_uri)
         
         # Populate the environment variable!
         env["REQUEST_METHOD"]   = req_method
         env['SCRIPT_NAME']      = os.path.basename(path)
         env['PATH_INFO']        = path
         env['QUERY_STRING']     = query+fragment
         
         # Non-wsgi-compliant MIFCHO hacks...
         env['mifcho.cm']        = self.cm
         env['mifcho.conn']      = conn          # not WSGI compatible!
         
         for (hk, hv) in req_headers:            # Transform headers, WSGI-style
             hk = hk.replace('-','_').upper()
             hv = hv.strip()
             
             if hk == 'CONTENT_LENGTH':
                 env[hk] = int(hv.strip())
             elif hk == 'CONTENT_TYPE':
                 env[hk] = hv.strip()
             else:
                 env['HTTP_%s' % hk] = hv
         
         env['wsgi.input'] = ''      # wsgi.input to read request content
         if 'CONTENT_LENGTH' in env and int(env['CONTENT_LENGTH']) > 0:
             env['wsgi.input'] = conn.read_bytes(int(env['CONTENT_LENGTH']))
         else:
             logging.debug('No CONTENT-LENGTH header or CONTENT-LENGTH == 0')
         
         # Determine app based on the request...
         try:
             logging.debug(">>1 [%s]" % env["PATH_INFO"].split('/')[-1])
             
             parts = env["PATH_INFO"].split('/')
             
             app     = parts[1]
             apps    = ['admin', 'hello', 'info', 'pyremo', 'static']
             if app in apps:
                 env["PATH_INFO"] = "/"+"/".join(parts[2:])
             else:
                 app = "static"
             logging.debug(">>2 [%s]" % env["PATH_INFO"])
             
             m       = __import__(app, fromlist=['app'])
             content = m.app(env, start_response)
             
             logging.debug("<< [%s]" % env["PATH_INFO"].split('/')[-1])
         except:
             logging.error('Unhandled app-error', exc_info=3)
             break
         
         try:
             
             messages.send_header(
                 conn,
                 'Transfer-Encoding',
                 'chunked'
             )
             messages.end_headers(conn)
             
             for chunk in content:                    
                 cl  = len(chunk)     # Length of chunk
                 hcl = hex(cl)[2:]
                 conn.sendall('%s\r\n' % hcl)
                 conn.sendall(chunk+'\r\n')
                 
             conn.sendall('0\r\n\r\n')
             
         except:
             logging.error('Error sending response!', exc_info=3)
             break
     
     try:
         conn.close()
     except:
         logging.error('Failed closing the connection...')
         raise