def test_16_noTimeoutInResponse(self):
        """
        Once the full request has been received, the L{HTTP} protocol will not
        time out, i.e. will not close the connection even if it sits more than
        60 seconds without receiving bytes.

        This is because at this point it's the server's responsibility to
        reply, which may take a while, and in the interim the server doesn't
        expect any bytes from the client so lack of data from client does not
        indicate a problem.
        """
        transport = AbortableTransport()
        fakeReactor = task.Clock()
        # Handler that takes forever to return, while still keeping reference
        # to the Deferred. If it didn't do the latter, it would get GC'ed,
        # which can cause unexpected things like a GeneratorExit exception in
        # an inlineCallbacks-decorated handler.
        handlerResult = defer.Deferred()
        def handler(*args):
            return handlerResult

        protocol = HTTP(handler, reactor=fakeReactor)

        protocol.makeConnection(transport)
        protocol.dataReceived('GET / HTTP/1.1\r\n\r\n')
        self.assertFalse(transport.aborting)

        # Wait 60 seconds:
        fakeReactor.advance(60)
        self.assertFalse(transport.aborting)
 def assertBadRequest(request):
     protocol = HTTP(None, reactor=task.Clock())
     protocol.makeConnection(AbortableTransport())
     result = []
     protocol.badRequestReceived = lambda: result.append(True)
     protocol.dataReceived(request)
     self.assertEqual(result, [True])
    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_15_timeout(self):
        """
        If the L{HTTP} protocol takes more than 60 seconds to receive the
        request, it will close the connection by calling transport.abortConnection().
        """
        transport = AbortableTransport()
        fakeReactor = task.Clock()
        protocol = HTTP(None, reactor=fakeReactor)

        protocol.makeConnection(transport)
        protocol.dataReceived('GET')
        self.assertFalse(transport.aborting)

        # Wait 60 seconds:
        fakeReactor.advance(60)
        self.assertTrue(transport.aborting)
    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", {}, "")])