#!/usr/bin/env python

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed
# with this work for additional information regarding copyright
# ownership.  The ASF licenses this file to you under the Apache
# License, Version 2.0 (the "License"); you may not use this file
# except in compliance with the License.  You may obtain a copy of the
# License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.  See the License for the specific language governing
# permissions and limitations under the License.

from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http

print '''1..1 finalChunkEncodingDisconnect
# The proxy forwards the final chunk even if the origin disconnects
# immediately afterward'''


def callback():
    print 'not ok 1 - No final chunk yet'

    reactor.stop()


reactor.callLater(2, callback)


class factory(http.HTTPFactory):
    class protocol(http.HTTPChannel):
        class requestFactory(http.Request):
            def requestReceived(ctx, method, target, version):

                ctx.client = None
                ctx.clientproto = version

                ctx.write('finalChunkedEncodingDisconnect')

                # If the proxy reads the final chunk before it sends the
                # response headers, it may send a Content-Length header vs. a
                # chunked response
                def callback():
                    try:
                        ctx.finish()

                    except RuntimeError:
                        print 'not ok 1 - Did the proxy crash?  (The origin connection closed.)'

                        reactor.stop()

                    else:
                        ctx.transport.loseConnection()

                reactor.callLater(1, callback)


origin = tcp.Port(0, factory())
origin.startListening()

print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())


class factory(protocol.ClientFactory):
    def clientConnectionFailed(ctx, connector, reason):

        print 'Bail out!'
        reason.printTraceback()

        reactor.stop()

    class protocol(http.HTTPClient):
        def connectionLost(ctx, reason):
            try:
                reactor.stop()

            except error.ReactorNotRunning:
                pass

            else:
                print 'not ok 1 - Did the proxy crash?  (The client connection closed.)'

        def connectionMade(ctx):
            ctx.transport.write('GET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))

        def handleHeader(ctx, k, v):
            if k.lower() == 'content-length':
                print 'not ok 1 - Got a Content-Length header vs. a chunked response'

                # No hope of a final chunk now
                reactor.stop()

        # Avoid calling undefined handleResponse() at the end of the
        # message (if the proxy sent a Content-Length header vs. a chunked
        # response).  (Override connectionLost() when the proxy crashes or
        # we stop the reactor.)
        #
        # Data that was already received will get processed (the end of
        # the headers), then shutdown events will fire (connections will
        # get closed), and then finally the reactor will grind to a halt.
        def handleResponseEnd(ctx):
            pass

        def handleResponsePart(ctx, data):
            if data.endswith('0\r\n\r\n'):
                print 'ok 1 - Got the final chunk'

                reactor.stop()


tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect()

reactor.run()
