Example #1
0
 def close(self):
     try:
         self.request_handler.log_request(
             self.status.split(' ',1)[0], self.bytes_sent
         )
     finally:
         SimpleHandler.close(self)
Example #2
0
    def finish_response(self):
        """
        Completes the response and performs the following tasks:

        - Remove the `'ws4py.socket'` and `'ws4py.websocket'`
          environ keys.
        - Attach the returned websocket, if any, to the WSGI server
          using its ``link_websocket_to_server`` method.
        """
        # force execution of the result iterator until first actual content
        rest = iter(self.result)
        first = list(itertools.islice(rest, 1))
        self.result = itertools.chain(first, rest)
        # now it's safe to look if environ was modified
        ws = None
        if self.environ:
            self.environ.pop('ws4py.socket', None)
            ws = self.environ.pop('ws4py.websocket', None)

        try:
            SimpleHandler.finish_response(self)
        except:
            if ws:
                ws.close(1011, reason='Something broke')
            raise
        else:
            if ws:
                self.request_handler.server.link_websocket_to_server(ws)
    def close(self):
        # M:
        # S.split([sep [,maxsplit]]) -> list of strings
        # >>> status
        # '200 OK'
        # >>> status.split(' ', 0)
        # ['200 OK']
        # >>> status.split(' ', 1)
        # ['200', 'OK']
        # >>> status.split(' ', 2)
        # ['200', 'OK']


        # In WSGIRequestHandler.handle
        # handler.request_handler = self

        # WSGIRequestHandler.log_request 
        # -> BaseHTTPRequestHandler.log_request
        # -> BaseHTTPRequestHandler.log_message
        # -> sys.stderr.write


        # SimpleHandler.close
        # -> BaseHandler.close

        try:
            self.request_handler.log_request(
                self.status.split(' ',1)[0], self.bytes_sent
            )
        finally:
            SimpleHandler.close(self)
Example #4
0
    def testPartialWrite(self):
        written = bytearray()

        class PartialWriter:
            def write(self, b):
                partial = b[:7]
                written.extend(partial)
                return len(partial)

            def flush(self):
                pass

        environ = {"SERVER_PROTOCOL": "HTTP/1.0"}
        h = SimpleHandler(BytesIO(), PartialWriter(), sys.stderr, environ)
        msg = "should not do partial writes"
        with self.assertWarnsRegex(DeprecationWarning, msg):
            h.run(hello_app)
        self.assertEqual(
            b"HTTP/1.0 200 OK\r\n"
            b"Content-Type: text/plain\r\n"
            b"Date: Mon, 05 Jun 2006 18:49:54 GMT\r\n"
            b"Content-Length: 13\r\n"
            b"\r\n"
            b"Hello, world!",
            written,
        )
Example #5
0
 def setup_environ(self):
     """
     Setup the environ dictionary and add the
     `'ws4py.socket'` key. Its associated value
     is the real socket underlying socket.
     """
     SimpleHandler.setup_environ(self)
     self.environ['ws4py.socket'] = self.environ['wsgi.input']._sock
Example #6
0
 def setup_environ(self):
     """
     Setup the environ dictionary and add the
     `'ws4py.socket'` key. Its associated value
     is the real socket underlying socket.
     """
     SimpleHandler.setup_environ(self)
     self.environ['ws4py.socket'] = get_connection(self.environ['wsgi.input'])
     self.http_version = self.environ['SERVER_PROTOCOL'].rsplit('/')[-1]
Example #7
0
	def handle(self):
		self.raw_requestline = self.rfile.readline()
		if not self.parse_request(): # An error code has been sent, just exit
			return

		handler = SimpleHandler(
			self.rfile, self.wfile, self.get_stderr(), self.get_environ()
		)
		handler.request_handler = self	  # backpointer for logging
		handler.run(self.server.get_app())
Example #8
0
    def finish_response(self):
        """
        Completes the response and performs the following tasks:

        - Remove the `'ws4py.socket'` and `'ws4py.websocket'`
          environ keys.
        - Attach the returned websocket, if any, to the WSGI server
          using its ``link_websocket_to_server`` method.
        """
        ws = None
        if self.environ:
            self.environ.pop('ws4py.socket', None)
            ws = self.environ.pop('ws4py.websocket', None)

        try:
            SimpleHandler.finish_response(self)
        except:
            if ws:
                ws.close(1011, reason='Something broke')
            raise
        else:
            if ws:
                self.request_handler.server.link_websocket_to_server(ws)
Example #9
0
 def cleanup_headers(self):
     SimpleHandler.cleanup_headers(self)
     self.headers['Connection'] = 'Close'
Example #10
0
def wsgi_server(application, conn):
    '''WSGI handler based on the Python wsgiref SimpleHandler.

    A WSGI application should return a iterable op StringTypes.
    Any encoding must be handled by the WSGI application itself.
    '''

    # TODO - this wsgi handler executes the application and renders a page in
    # memory completely before returning it as a response to the client.
    # Thus, it does not "stream" the result back to the client. It should be
    # possible though. The SimpleHandler accepts file-like stream objects. So,
    # it should be just a matter of connecting 0MQ requests/response streams
    # to the SimpleHandler requests and response streams. However, the Python
    # API for Mongrel2 doesn't seem to support file-like stream objects for
    # requests and responses. Unless I have missed something.

    # setup connection handler
    # sender_id is automatically generated
    # so that each handler instance is uniquely identified

    while True:
        debug("WAITING FOR REQUEST")

        # receive a request
        req = conn.recv()
        if DEBUG:
            debug("REQUEST HEADERS: %r\n" % req.headers)
            debug("REQUEST BODY: %r\n" % req.body)

        if req.is_disconnect():
            print("DISCONNECT")
            continue  # effectively ignore the disconnect from the client

        # json parsing gives us unicode instead of ascii.
        headers = dict((key.encode('ascii'), value.encode('ascii'))
                       for (key, value) in req.headers.items())

        env = {}

        add_request_metavariables(env, headers)
        add_http_variables(env, headers)

        debug("ENVIRON: %r\n" % env)

        # SimpleHandler needs file-like stream objects for
        # requests, errors and reponses
        reqIO = StringIO(req.body)
        errIO = StringIO()
        respIO = StringIO()

        # execute the application
        simple_handler = SimpleHandler(reqIO, respIO, errIO, env,
                                       multithread=False,
                                       multiprocess=False)
        simple_handler.run(application)

        response = respIO.getvalue()
        errors = errIO.getvalue()

        # return the response
        debug("RESPONSE: %r\n" % response)
        if errors:
            debug("ERRORS: %r" % errors)

        conn.reply(req, response)

        # Check if we should close the connection.

        respIO.seek(0)

        protocol = respIO.readline()[:8]
        msg = httplib.HTTPMessage(respIO, 0)
        http_1p1 = protocol == 'HTTP/1.1'

        conn_close = http_1p1 and msg.getheader("Connection") == "close"
        keep_alive = http_1p1 or msg.getheader("Connection") == "Keep-Alive"
        if conn_close or not keep_alive:
            debug("EXPLICITLY CLOSING CONNECTION")
            conn.reply(req, "")
Example #11
0
 def __init__(self, stdin, stdout, stderr):
     base_environ = dict(os.environ.items())
     base_environ['SERVER_PROTOCOL'] = 'HTTP/1.0'
     SimpleHandler.__init__(self, stdin, stdout, stderr, base_environ,
                            multithread=False, multiprocess=True)
Example #12
0
	def handle_wsgi_request(stdin, stdout, stderr, environ):
		handler = SimpleHandler(stdin.buffer, stdout.buffer, stderr, environ.vars, environ.server.multithread, environ.server.multiprocess)
		handler.run_once = not environ.server.multiconnection
		handler.server_software = environ.server.software
		handler.run(app)