def test_02_handler(self):
        """
        L{HTTP.__init__} is called with a function as its argument. This
        function is called by L{HTTP.requestReceived} with the request
        parameters, and its response is passed to L{HTTP._writeResponse}.

        In other words, this function determines how the HTTP server processes
        and handles requests.
        """
        def handler(method, path, headers, body):
            self.assertEqual(method, "WOO")
            self.assertEqual(path, "/path")
            self.assertEqual(headers, {"Key": "value"})
            return Response(300, "hello", {"k": "v"})

        protocol = HTTP(handler, reactor=task.Clock())
        response = []
        protocol._writeResponse = lambda r: response.append(r)

        # Handler is stored as an attribute of the protocol:
        self.assertIdentical(protocol._handler, handler)
        # requestReceived calls handler, and then takes the results and passes
        # it to _writeResponse:
        protocol.requestReceived("WOO", "/path", {"Key": "value"}, "")
        self.assertResponsesEqual(response[0],
                                  Response(300, "hello", {"k": "v"}))
    def test_14_handlerReturnsDeferredWithFailure(self):
        """
        If the handler returns a Deferred that fires with a failure,
        L{HTTP.requestReceived} writes a 500 response code using
        L{HTTP._writeResponse} and logs the exception.
        """
        # Handler that returns eventual result:
        result = defer.Deferred()
        def handler(method, path, headers, body):
            return result

        protocol = HTTP(handler, reactor=task.Clock())
        response = []
        protocol._writeResponse = lambda r: response.append(r)

        protocol.requestReceived("GET", "/", [], "")
        # Deferred hasn't fired yet, so no response is sent yet:
        self.assertEqual(len(response), 0)
        # Now we fire the Deferred with an exception:
        result.errback(ZeroDivisionError())

        # 500 response code:
        self.assertEqual(len(response), 1)
        self.assertEqual(response[0].code, 500)
        # The error was logged using twisted.python.log.err():
        excs = self.flushLoggedErrors(ZeroDivisionError)
        self.assertEqual(len(excs), 1)
    def test_11_handlerException(self):
        """
        If the handler throws an exception, L{HTTP.requestReceived} writes a
        response with error code 500 (internal server error), and the
        exception is logged.
        """
        def handler(method, path, headers, body):
            raise RuntimeError("I am a buggy handler!")

        protocol = HTTP(handler, reactor=task.Clock())
        response = []
        protocol._writeResponse = lambda r: response.append(r)

        protocol.requestReceived("GET", "/", [], "")
        # We don't assert anything on the body of the response; if you're
        # feeling ambitious you can include the text of the traceback in your
        # response:
        self.assertEqual(len(response), 1)
        self.assertEqual(response[0].code, 500)
        # You should log the error using twisted.python.log.err(). This makes
        # sure the logged error doesn't cause the test to fail:
        excs = self.flushLoggedErrors(RuntimeError)
        # And this asserts that you logged it, i.e. that there was one
        # RuntimeError logged:
        self.assertEqual(len(excs), 1)
    def test_19_requestBodyToHandler(self):
        """
        If the HTTP request includes a body, it is passed to the handler
        function.
        """
        result = []
        def handler(method, path, headers, body):
            result.append(body)
            return Response(200, "hello", {})

        protocol = HTTP(handler, reactor=task.Clock())
        response = []
        protocol._writeResponse = lambda r: response.append(r)

        protocol.requestReceived("GET", "/", {}, "the body")
        self.assertEqual(result, ["the body"])
    def test_03_receiveRequest(self):
        """
        When L{HTTP.dataReceived} receives the bytes for a HTTP request,
        L{HTTP.requestRecieved} is called with the method and path.
        """
        protocol = HTTP(None, reactor=task.Clock())
        received = []
        protocol.requestReceived = lambda *args: received.append(args)

        # Hook up a fake in-memory transport:
        protocol.makeConnection(AbortableTransport())
        protocol.dataReceived("GET /foo/bar HTTP/1.1\r\n\r\n")
        self.assertEqual(received, [("GET", "/foo/bar", {}, "")])
    def test_12_handlerReturnsDeferred(self):
        """
        If the handler returns a Deferred that fires with (code, body,
        headers), L{HTTP.requestReceived} writes it as a response using
        L{HTTP._writeResponse}.
        """
        # Handler that returns eventual result:
        result = defer.Deferred()
        def handler(method, path, headers, body):
            return result

        protocol = HTTP(handler, reactor=task.Clock())
        response = []
        protocol._writeResponse = lambda r: response.append(r)

        protocol.requestReceived("GET", "/", [], "")
        # Deferred hasn't fired yet, so no response is sent yet:
        self.assertEqual(len(response), 0)
        # Now we fire the Deferred, and response should be written:
        result.callback(Response(200, "response", {"key": "value"}))
        self.assertResponsesEqual(response[0],
                                  Response(200, "response", {"key": "value"}))
    def test_04_receiveHeaders(self):
        """
        When L{HTTP.dataReceived} receives the bytes for a HTTP request,
        L{HTTP.requestRecieved} is called with a dictionary of headers.
        """
        protocol = HTTP(None, reactor=task.Clock())
        received = []
        protocol.requestReceived = lambda *args: received.append(args)

        protocol.makeConnection(AbortableTransport())
        protocol.dataReceived("GET /foo/bar HTTP/1.1\r\n"
                              "Key: val ue\r\n"
                              "Another: thing\r\n"
                              "\r\n")
        self.assertEqual(
            received,
            [("GET", "/foo/bar", {"Key": "val ue", "Another": "thing"}, "")])
    def test_18_contentLength(self):
        """
        If the HTTP request includes a 'content-length' header, the value
        indicates the number of bytes of the request body, which will get
        passed as the fourth argument to the requestReceived.
        """
        protocol = HTTP(None, reactor=task.Clock())
        received = []
        protocol.requestReceived = lambda *args: received.append(args)
        protocol.makeConnection(AbortableTransport())

        protocol.dataReceived("GET /foo/bar HTTP/1.1\r\n")
        protocol.dataReceived("Content-Length: 10\r\n")
        protocol.dataReceived("\r\n")
        protocol.dataReceived("abcde")
        self.assertEqual(received, [])
        protocol.dataReceived("fghij")
        self.assertEqual(
            received,
            [("GET", "/foo/bar", {"Content-Length": "10"}, "abcdefghij")])
    def test_05_receiveAfterFinalNewline(self):
        """
        L{HTTP.requestReceived} is only called after C{dataReceived} gets the
        final line with just '\r\n'.

        (Network connections may not deliver the full request in a single
        dataReceived() call, so the protocol will need to implement a state
        machine tracking where it is in the process of parsing the HTTP
        request.)
        """
        protocol = HTTP(None, reactor=task.Clock())
        received = []
        protocol.requestReceived = lambda *args: received.append(args)

        protocol.makeConnection(AbortableTransport())
        protocol.dataReceived("HEAD /?x=y HTTP/")
        protocol.dataReceived("1.1\r\n")
        self.assertEqual(received, [])
        protocol.dataReceived("\r\n")
        self.assertEqual(received, [("HEAD", "/?x=y", {}, "")])