def setUp(self):
     WeightlessTestCase.setUp(self)
     self.httpprotocol = HttpProtocol()
     self.server = Server(self.reactor, self.port)
     dna = (Transparant(),
         (self.server,
             (self.httpprotocol,
                 # add your test thing here
             )
         )
     )
     self.body = be(dna)
 def setUp(self):
     WeightlessTestCase.setUp(self)
     self.httpprotocol = HttpProtocol()
     self.server = Server(self.reactor, self.port)
     dna = (Transparant(),
         (self.server,
             (self.httpprotocol,
                 # add your test thing here
             )
         )
     )
     self.body = be(dna)
예제 #3
0
    def XXXXXXXXXXXXXXXXXXXtestOpenHttpWithTransactionOnConnectionScopeExample(
            self):
        class Transaction(Observable):
            def __init__(self, txmanagers):
                super(Transaction, self).__init__()
                self._txmanagers = txmanagers

            def unknown(self, message, *args, **kwargs):
                txs = []
                for txmanager in sefl._txmanagers:
                    tx = txmanager.begin()
                    txs.append(tx)
                try:
                    for response in self.all.unknown(message, *args, **kwargs):
                        yield response
                except:
                    for tx in txs:
                        tx.abort()
                else:
                    for tx in txs:
                        tx.commit()

        class MyDB(object):
            def begin(self):
                self._preparedData = []
                return self

            def store(self, data):
                self._preparedData.append(data)

            def commit(self):
                self.commitedData = ''.join(self._preparedData)
                self._preparedData = []

        class MyHandler(Observable):
            def upload(self, ContentLength, *args, **kwargs):
                body = yield readBytes(ContentLength)
                self.any.store(body)

        mydb = MyDB()
        reactor = Reactor()
        server = Server(reactor, 8080)
        pipe = be((
            Observable(),
            (
                server,
                (
                    Transaction(
                        [mydb]),  # Transaction commits when connection closes
                    (HttpProtocol(), (MyHandler(), (mydb, )))))))
        self.fail('continue here')
예제 #4
0
 def setUp(self):
     self._timer = HttpProtocol.Timer
     HttpProtocol.Timer = MockTimer
     self.p = HttpProtocol()
예제 #5
0
class HttpProtocolTest(TestCase):

    def setUp(self):
        self._timer = HttpProtocol.Timer
        HttpProtocol.Timer = MockTimer
        self.p = HttpProtocol()

    def tearDown(self):
        HttpProtocol.Timer = self._timer

    def addHandler(self, handler):
        self.p.addObserver(handler)

    def processConnection(self):
        stack = compose(self.p.processConnection())
        self.assertEquals(None, stack.next()) # i.e. it starts with accepting data
        return stack

    def testRequestHandledByDifferentObservers(self):
        class GetHandler(object):
            def processRequest(self, Method=None, **kwargs):
                if Method=='GET':
                    return (x for x in ['HTTP/1.1 200 Ok\r\n', 'hello GET'])
        class PostHandler(object):
            def processRequest(self, Method=None, **kwargs):
                if Method=='HEAD':
                    return (x for x in ['HTTP/1.1 200 Ok\r\n', 'hello POST'])
        self.addHandler(PostHandler())
        self.addHandler(GetHandler())
        stack = self.processConnection()
        response = stack.send('GET / HTTP/1.1\r\n\r\n')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        self.assertEquals('hello GET', stack.next())
        stack.next()
        response = stack.send('HEAD / HTTP/1.1\r\n\r\n')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        self.assertEquals('hello POST', stack.next())

    def testForwardParsedGETRequest(self):
        args = []
        class MyHandler(object):
            def processRequest(self, **kwargs):
                args.append(kwargs)
                yield 'HTTP/1.....etc'
        self.addHandler(MyHandler())
        stack = self.processConnection()
        uri = 'http://host:80/path;user=jan/show;a=all?&a=b&a=c#ref'
        header = 'Content-Type: text/xml; encoding="utf-8"; version="1.0"'
        message = 'GET %s HTTP/1.1\r\n%s\r\n\r\n' % (uri, header)
        response = stack.send(message)
        self.assertEquals('HTTP/1.....etc', response)
        args = args[0]
        self.assertEquals('HTTP/1.....etc', response)
        self.assertEquals(args['fragment'], 'ref')
        self.assertEquals(args['RequestURI'], 'http://host:80/path;user=jan/show;a=all?&a=b&a=c#ref')
        self.assertEquals(args['netloc'], ('host', '80')),
        headers = args['Headers']
        self.assertEquals(headers['content-type'], {'text/xml': {'encoding':'utf-8', 'version':'1.0'}})
        self.assertEquals(args['query'], {'a': ['b', 'c']})
        self.assertEquals(args['path'], '/path;user=jan/show;a=all')
        self.assertEquals(args['scheme'], 'http')
        self.assertEquals(args['Method'], 'GET')
        self.assertEquals(args['HTTPVersion'], '1.1')

    def testForwardParsedPOSTRequest(self):
        args = []
        class MyHandler(object):
            def processRequest(self, **kwargs):
                args.append(kwargs)
                yield 'HTTP/1.....etc'
        self.addHandler(MyHandler())
        stack = self.processConnection()
        uri = 'http://ahost:8000/a/b;user=pete/a;b=any?&x=y&p=q#anchor'
        header = 'Content-Type: text/plain; encoding="utf-16"; version="1.1"\r\nContent-Length: 20'
        message = 'POST %s HTTP/1.0\r\n%s\r\n\r\n' % (uri, header)
        response = stack.send(message)
        args = args[0]
        self.assertEquals('HTTP/1.....etc', response)
        self.assertEquals(args['fragment'], 'anchor')
        self.assertEquals(args['RequestURI'], 'http://ahost:8000/a/b;user=pete/a;b=any?&x=y&p=q#anchor')
        self.assertEquals(args['netloc'], ('ahost', '8000')),
        headers = args['Headers']
        self.assertEquals(headers['content-length'], {'20': {}})
        self.assertEquals(headers['content-type'], {'text/plain': {'encoding':'utf-16', 'version':'1.1'}})
        self.assertEquals(args['ContentLength'], 20)
        self.assertEquals(args['query'], {'x': ['y'], 'p': ['q']})
        self.assertEquals(args['path'], '/a/b;user=pete/a;b=any')
        self.assertEquals(args['scheme'], 'http')
        self.assertEquals(args['Method'], 'POST')
        self.assertEquals(args['HTTPVersion'], '1.0')

    def testPOST(self):
        class Buffer(object):
            def __init__(self):
                self.buff = []
            @autostart
            def sink(self):
                while True:
                    self.buff.append((yield))
            def value(self):
                return ''.join(self.buff)
        buff = Buffer()
        class MyHandler(object):
            def processRequest(self, ContentLength=None, **kwargs):
                yield copyBytes(ContentLength, buff.sink())
                yield 'HTTP/1.1 2'
                yield '00 Ok\r\n'
        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send('POST / HTTP/1.1\r')
        self.assertEquals(None, response)
        response = stack.send('\nContent-Length: 5\r\n\r\n12345')
        self.assertEquals('HTTP/1.1 2', response)
        response = stack.next()
        self.assertEquals('00 Ok\r\n', response)
        self.assertEquals('12345', buff.value())

    def testPostWith100Continue(self):
        class Buffer(object):
            def __init__(self):
                self.buff = []
            @autostart
            def sink(self):
                while True:
                    self.buff.append((yield))
            def value(self):
                return ''.join(self.buff)
        buff = Buffer()
        class MyHandler(object):
            def processRequest(self, ContentLength=None, **kwargs):
                yield copyBytes(ContentLength, buff.sink())
                yield 'HTTP/1.1 200 Ok\r\n'
        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send('POST / HTTP/1.1\r\nContent-Length: 5\r\nExpect: 100-continue\r\n\r\n')
        self.assertEquals('HTTP/1.1 100 Continue\r\n', response)
        response = stack.send(None)
        self.assertEquals(None, response)
        response = stack.send('12345')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        self.assertEquals('12345', buff.value())

    def testPostWith100ContinueNOT(self):
        class MyHandler(object):
            def processRequest(self, ContentLength=None, **kwargs):
                return
        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send('POST / HTTP/1.1\r\nContent-Length: 5\r\nExpect: 100-continue\r\n\r\n')
        self.assertEquals('HTTP/1.1 417 Expectation failed\r\n', response)

    def testNotImplemented(self):
        stack = self.processConnection()
        response = stack.send('POST / HTTP/1.1\r\nContent-Length: 5\r\n\r\n')
        self.assertEquals('HTTP/1.1 501 Not Implemented\r\n', response)

    def testReadChunkEncoded(self):
        parts = []
        class MyHandler(object):
            def processRequest(self, **kwargs):
                while True:
                    try:
                        part = yield
                    except StopIteration:
                        break
                    else:
                        parts.append(part)
                yield 'HTTP/1.1 200 Ok\r\n'
                yield ''.join(parts)

        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send('POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5\r\n12345\r\n0')
        self.assertEquals(None, response)
        response = stack.send('\r\n')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        response = stack.next()
        self.assertEquals('12345', response)
        self.assertEquals('12345', ''.join(parts))
예제 #6
0
class HttpProtocolIntegrationTest(WeightlessTestCase):
    def setUp(self):
        WeightlessTestCase.setUp(self)
        self.httpprotocol = HttpProtocol()
        self.server = Server(self.reactor, self.port)
        dna = (
            Transparant(),
            (
                self.server,
                (
                    self.httpprotocol,
                    # add your test thing here
                )))
        self.body = be(dna)

    def tearDown(self):
        self.server.stop()
        WeightlessTestCase.tearDown(self)

    def assertNetStat(self, local, remote, state):
        statelines = getNetStat(local, remote)
        if not state:
            self.assertEquals(0, len(statelines), statelines)
        else:
            self.assertTrue(state in statelines[0], statelines[0])

    def testSimpleServerSetUpAndAFewPOSTRequests(self):
        class MyServer(object):
            def processRequest(self,
                               Method=None,
                               ContentLength=None,
                               *args,
                               **kwargs):
                if Method != 'POST':
                    return
                result = yield http.readRe('(?P<BODY>.*)', ContentLength)
                body = result['BODY']
                yield http.ok()
                yield http.headers('a', 'b')
                yield 'Hello ' + body

        self.httpprotocol.addObserver(MyServer())
        with self.loopingReactor():
            result1 = urlopen(
                Request('http://localhost:%s/' % self.port,
                        data='Johan')).read()
            result2 = urlopen(
                Request('http://localhost:%s/' % self.port,
                        data='Erik')).read()
        self.assertEquals('Hello Johan', result1)
        self.assertEquals('Hello Erik', result2)

    def testContentLenght(self):
        body = []

        class MyServer(object):
            def processRequest(this, Method, RequestURI, HTTPVersion, Headers,
                               **kwargs):
                length = int(Headers['content-length'].keys()[0])

                @autostart
                def destination(result):
                    while True:
                        result += (yield)

                result = []
                yield http.copyBytes(length, destination(result))
                self.assertEquals('This is a body', ''.join(result))
                yield http.ok()
                yield http.headers('a', 'b')
                yield 'Hello ' + ''.join(result)

        self.httpprotocol.addObserver(MyServer())
        with self.loopingReactor():
            result1 = urlopen(
                Request('http://localhost:%s/' % self.port,
                        data='This is a body')).read()
        self.assertEquals('Hello This is a body', result1)

    def testOneRequest(self):
        done = []

        class MyServer(object):
            def processRequest(this, Method, RequestURI, HTTPVersion, Headers,
                               **kwargs):
                self.assertEquals('GET', Method)
                self.assertEquals('/seven', RequestURI)
                self.assertEquals('1.0', HTTPVersion)
                self.assertEquals({}, Headers)
                yield 'Hello there'
                done.append(True)

        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))
        sok.send('GET /seven HTTP/1.0\r\n\r\n')
        while not done:
            self.reactor.step()
        self.assertEquals([True], done)
        self.assertEquals('Hello there', sok.recv(99))

    def testHttp11TwoRequests(self):
        done = []

        class MyServer(object):
            def processRequest(self,
                               Method=None,
                               RequestURI=None,
                               HTTPVersion=None,
                               Headers=None,
                               fragment=None,
                               netloc=None,
                               query=None,
                               path=None,
                               scheme=None):
                yield http.ok()
                yield http.noheaders()
                yield 'Echo ' + RequestURI
                done.append(True)

        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))  # ONE connection!
        sok.send('GET /six HTTP/1.1\r\n\r\n')
        while not done:
            self.reactor.step()
        response = sok.recv(999)
        self.assertEquals('HTTP/1.1 200 Ok\r\n\r\nEcho /six', response)
        sok.send('GET /seven HTTP/1.1\r\n\r\n')
        done = []
        while not done:
            self.reactor.step()
        self.assertEquals([True], done)
        response = sok.recv(999)
        self.assertEquals('HTTP/1.1 200 Ok\r\n\r\nEcho /seven', response)
        sok.close()  # need to do this, because we use HTTP/1.1
        self.reactor.step()

    def testGETWithResponse(self):
        class MyServer(object):
            def processRequest(self, **kwargs):
                yield 'answer 1'
                yield 'answer 2'

        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))  # ONE connection!
        sok.send('GET /one HTTP/1.1\r\n\r\n')
        self.reactor.step().step().step()
        self.assertEquals('answer 1', sok.recv(999))
        self.reactor.step()
        self.assertEquals('answer 2', sok.recv(999))
        sok.shutdown(1)
        self.reactor.step()
        self.assertEquals('', sok.recv(999))
        sok.close()

    def testPOSTandThenGET(self):
        class MyPOSTServer(object):
            def processRequest(this,
                               Method=None,
                               RequestURI=None,
                               ContentLength=0,
                               **kwargs):
                if Method == 'POST':
                    return this.handle(ContentLength)

            def handle(this, ContentLength):
                body = yield http.readRe('(?P<BODY>.*)', ContentLength)
                self.assertEquals('XXYYZZ', body['BODY'])
                yield http.ok()
                yield http.noheaders()
                yield 'this was the post handler'

        class MyGETServer(object):
            def processRequest(this, Method=None, RequestURI=None, **kwargs):
                if Method == 'GET':
                    return this.handle()

            def handle(self):
                yield http.ok()
                yield http.noheaders()
                yield 'this was the GET handler'

        self.httpprotocol.addObserver(MyPOSTServer())
        self.httpprotocol.addObserver(MyGETServer())
        body = 'XXYYZZ'
        sok = socket()
        sok.connect(('localhost', self.port))  # ONE connection!
        sok.send('POST /one HTTP/1.1\r\nContent-Length: %s\r\n\r\n' %
                 len(body) + body)
        self.reactor.step().step().step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('this was the post handler', sok.recv(999))
        sok.send('GET /two HTTP/1.1\r\n\r\n')
        self.reactor.step().step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('this was the GET handler', sok.recv(999))
        sok.close()
        self.reactor.step()

    def testTwoRequestOnSameConnectionAndConnectionCloseHeader(self):
        done = []

        class MyServer(object):
            def processRequest(this,
                               Method=None,
                               RequestURI=None,
                               ContentLength=0,
                               *args,
                               **kwargs):
                yield http.ok()
                if Method == 'POST':

                    @autostart
                    def devNull():
                        while True:
                            yield

                    yield http.copyBytes(ContentLength, devNull())
                wrong = yield 'Path = ' + str(RequestURI)
                self.assertEquals(None,
                                  wrong)  # Second request must not end up here
                done.append(True)

        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))
        body = 'XXYYZZ'
        sok.send('POST /one HTTP/1.1\r\nContent-Length: %s\r\n\r\n' %
                 len(body) + body)
        sok.send('GET /two HTTP/1.1\r\nConnection: close\r\n\r\n')
        while not done == [True]:
            self.reactor.step()
        self.assertEquals([True], done)
        self.assertEquals('HTTP/1.1 200 Ok\r\nPath = /one', sok.recv(99))
        while not done == [True, True]:
            self.reactor.step()
        self.assertEquals('HTTP/1.1 200 Ok\r\nPath = /two', sok.recv(99))
        sok.close()

    def testConnectionCloseForHTTP10afterPIPELINING(self):
        class MyServer(object):
            def processRequest(this, Method, RequestURI, HTTPVersion, Headers,
                               *args, **kwargs):
                yield http.ok()
                yield http.headers('Content-Length', 3)
                yield 'Bye'

        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))
        sok.send('GET /one HTTP/1.1\r\n\r\n')  #pipeline 2 requests
        sok.send('GET /two HTTP/1.0\r\n\r\n')
        self.reactor.step().step().step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Content-Length: 3\r\n\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Bye', sok.recv(999))
        self.reactor.step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Content-Length: 3\r\n\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Bye', sok.recv(999))
        self.assertEquals(
            '', sok.recv(999))  # empty string means 'closed' in socket land

    def testTimerFiresWhenConnectedClientIsSilent(self):
        sok = socket()
        sok.connect(('localhost', self.port))
        localport = sok.getsockname()[1]
        with self.loopingReactor():
            response = sok.recv(9999)
        self.assertEquals('HTTP/1.1 408 Request Timeout\r\n\r\n', response)
        sok.close()
        stat = getNetStat(self.port, localport)
        self.assertTrue('TIME_WAIT' in stat[0], stat[0])
        stat = getNetStat(localport, self.port)
        self.assertEquals(0, len(stat), stat)

    def testTimerWhenInvalidRequest(self):
        sok = socket()
        sok.connect(('localhost', self.port))
        sok.send('GET / HTTP/1.1\r')  # unterminated Request Line
        sok.send('some garbage' *
                 1024)  # some kB garbage to trigger buffer protection
        sok.send('\rxyz')  # unterminated end of Headers
        self.reactor.step().step().step().step()
        self.assertEquals('HTTP/1.1 413 Request Entity Too Large\r\n\r\n',
                          sok.recv(999))
        #self.reactor.step()
        #self.assertEquals('\r\n', sok.recv(999))
        sok.close()

    def testReuseAddress(self):
        remoteport = self.port + 1
        server = socket()
        server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        server.bind(('127.0.0.1', remoteport))
        server.listen(1)
        local = socket()
        local.connect(('127.0.0.1', remoteport))
        server.close()
        server = socket()
        server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        try:
            server.bind(('127.0.0.1', remoteport))
        except:
            self.fail('bind must succeed')

    def testCloseStatesRemoteFirst(self):
        remoteport = self.port + 1
        server = socket()
        server.bind(('127.0.0.1', remoteport))
        server.listen(1)
        local = socket()
        local.connect(('127.0.0.1', remoteport))
        localport = local.getsockname()[1]

        remote = server.accept()[0]
        self.assertNetStat(remoteport, localport, 'ESTABLISHED')
        self.assertNetStat(localport, remoteport, 'ESTABLISHED')

        remote.close()
        self.assertNetStat(remoteport, localport, 'FIN_WAIT')
        self.assertNetStat(localport, remoteport, 'CLOSE_WAIT')

        local.close()
        self.assertNetStat(remoteport, localport, 'TIME_WAIT')
        self.assertNetStat(localport, remoteport, None)

        server.close()
        server = socket()
        try:
            server.bind(('127.0.0.1', remoteport))
            self.fail('re-bind must raise Address Already in Use Exception')
        except AssertionError:
            raise
        except Exception, e:
            pass
예제 #7
0
 def setUp(self):
     TestCase.setUp(self)
     self._timer = HttpProtocol.Timer
     HttpProtocol.Timer = MockTimer
     self.p = HttpProtocol()
예제 #8
0
class HttpProtocolTest(TestCase):
    def setUp(self):
        TestCase.setUp(self)
        self._timer = HttpProtocol.Timer
        HttpProtocol.Timer = MockTimer
        self.p = HttpProtocol()

    def tearDown(self):
        HttpProtocol.Timer = self._timer
        TestCase.tearDown(self)

    def addHandler(self, handler):
        self.p.addObserver(handler)

    def processConnection(self):
        stack = compose(self.p.processConnection())
        self.assertEquals(None,
                          stack.next())  # i.e. it starts with accepting data
        return stack

    def testRequestHandledByDifferentObservers(self):
        class GetHandler(object):
            def processRequest(self, Method=None, **kwargs):
                if Method == 'GET':
                    return (x for x in ['HTTP/1.1 200 Ok\r\n', 'hello GET'])

        class PostHandler(object):
            def processRequest(self, Method=None, **kwargs):
                if Method == 'HEAD':
                    return (x for x in ['HTTP/1.1 200 Ok\r\n', 'hello POST'])

        self.addHandler(PostHandler())
        self.addHandler(GetHandler())
        stack = self.processConnection()
        response = stack.send('GET / HTTP/1.1\r\n\r\n')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        self.assertEquals('hello GET', stack.next())
        stack.next()
        response = stack.send('HEAD / HTTP/1.1\r\n\r\n')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        self.assertEquals('hello POST', stack.next())

    def testForwardParsedGETRequest(self):
        args = []

        class MyHandler(object):
            def processRequest(self, **kwargs):
                args.append(kwargs)
                yield 'HTTP/1.....etc'

        self.addHandler(MyHandler())
        stack = self.processConnection()
        uri = 'http://host:80/path;user=jan/show;a=all?&a=b&a=c#ref'
        header = 'Content-Type: text/xml; encoding="utf-8"; version="1.0"'
        message = 'GET %s HTTP/1.1\r\n%s\r\n\r\n' % (uri, header)
        response = stack.send(message)
        self.assertEquals('HTTP/1.....etc', response)
        args = args[0]
        self.assertEquals('HTTP/1.....etc', response)
        self.assertEquals(args['fragment'], 'ref')
        self.assertEquals(
            args['RequestURI'],
            'http://host:80/path;user=jan/show;a=all?&a=b&a=c#ref')
        self.assertEquals(args['netloc'], ('host', '80')),
        headers = args['Headers']
        self.assertEquals(
            headers['content-type'],
            {'text/xml': {
                'encoding': 'utf-8',
                'version': '1.0'
            }})
        self.assertEquals(args['query'], {'a': ['b', 'c']})
        self.assertEquals(args['path'], '/path;user=jan/show;a=all')
        self.assertEquals(args['scheme'], 'http')
        self.assertEquals(args['Method'], 'GET')
        self.assertEquals(args['HTTPVersion'], '1.1')

    def testForwardParsedPOSTRequest(self):
        args = []

        class MyHandler(object):
            def processRequest(self, **kwargs):
                args.append(kwargs)
                yield 'HTTP/1.....etc'

        self.addHandler(MyHandler())
        stack = self.processConnection()
        uri = 'http://ahost:8000/a/b;user=pete/a;b=any?&x=y&p=q#anchor'
        header = 'Content-Type: text/plain; encoding="utf-16"; version="1.1"\r\nContent-Length: 20'
        message = 'POST %s HTTP/1.0\r\n%s\r\n\r\n' % (uri, header)
        response = stack.send(message)
        args = args[0]
        self.assertEquals('HTTP/1.....etc', response)
        self.assertEquals(args['fragment'], 'anchor')
        self.assertEquals(
            args['RequestURI'],
            'http://ahost:8000/a/b;user=pete/a;b=any?&x=y&p=q#anchor')
        self.assertEquals(args['netloc'], ('ahost', '8000')),
        headers = args['Headers']
        self.assertEquals(headers['content-length'], {'20': {}})
        self.assertEquals(
            headers['content-type'],
            {'text/plain': {
                'encoding': 'utf-16',
                'version': '1.1'
            }})
        self.assertEquals(args['ContentLength'], 20)
        self.assertEquals(args['query'], {'x': ['y'], 'p': ['q']})
        self.assertEquals(args['path'], '/a/b;user=pete/a;b=any')
        self.assertEquals(args['scheme'], 'http')
        self.assertEquals(args['Method'], 'POST')
        self.assertEquals(args['HTTPVersion'], '1.0')

    def testPOST(self):
        class Buffer(object):
            def __init__(self):
                self.buff = []

            @autostart
            def sink(self):
                while True:
                    self.buff.append((yield))

            def value(self):
                return ''.join(self.buff)

        buff = Buffer()

        class MyHandler(object):
            def processRequest(self, ContentLength=None, **kwargs):
                yield copyBytes(ContentLength, buff.sink())
                yield 'HTTP/1.1 2'
                yield '00 Ok\r\n'

        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send('POST / HTTP/1.1\r')
        self.assertEquals(None, response)
        response = stack.send('\nContent-Length: 5\r\n\r\n12345')
        self.assertEquals('HTTP/1.1 2', response)
        response = stack.next()
        self.assertEquals('00 Ok\r\n', response)
        self.assertEquals('12345', buff.value())

    def testPostWith100Continue(self):
        class Buffer(object):
            def __init__(self):
                self.buff = []

            @autostart
            def sink(self):
                while True:
                    self.buff.append((yield))

            def value(self):
                return ''.join(self.buff)

        buff = Buffer()

        class MyHandler(object):
            def processRequest(self, ContentLength=None, **kwargs):
                yield copyBytes(ContentLength, buff.sink())
                yield 'HTTP/1.1 200 Ok\r\n'

        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send(
            'POST / HTTP/1.1\r\nContent-Length: 5\r\nExpect: 100-continue\r\n\r\n'
        )
        self.assertEquals('HTTP/1.1 100 Continue\r\n', response)
        response = stack.send(None)
        self.assertEquals(None, response)
        response = stack.send('12345')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        self.assertEquals('12345', buff.value())

    def testPostWith100ContinueNOT(self):
        class MyHandler(object):
            def processRequest(self, ContentLength=None, **kwargs):
                return

        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send(
            'POST / HTTP/1.1\r\nContent-Length: 5\r\nExpect: 100-continue\r\n\r\n'
        )
        self.assertEquals('HTTP/1.1 417 Expectation failed\r\n', response)

    def testNotImplemented(self):
        stack = self.processConnection()
        response = stack.send('POST / HTTP/1.1\r\nContent-Length: 5\r\n\r\n')
        self.assertEquals('HTTP/1.1 501 Not Implemented\r\n', response)

    def testReadChunkEncoded(self):
        parts = []

        class MyHandler(object):
            def processRequest(self, **kwargs):
                while True:
                    try:
                        part = yield
                    except StopIteration:
                        break
                    else:
                        parts.append(part)
                yield 'HTTP/1.1 200 Ok\r\n'
                yield ''.join(parts)

        self.addHandler(MyHandler())
        stack = self.processConnection()
        response = stack.send(
            'POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n5\r\n12345\r\n0'
        )
        self.assertEquals(None, response)
        response = stack.send('\r\n')
        self.assertEquals('HTTP/1.1 200 Ok\r\n', response)
        response = stack.next()
        self.assertEquals('12345', response)
        self.assertEquals('12345', ''.join(parts))
class HttpProtocolIntegrationTest(WeightlessTestCase):

    def setUp(self):
        WeightlessTestCase.setUp(self)
        self.httpprotocol = HttpProtocol()
        self.server = Server(self.reactor, self.port)
        dna = (Transparant(),
            (self.server,
                (self.httpprotocol,
                    # add your test thing here
                )
            )
        )
        self.body = be(dna)

    def tearDown(self):
        self.server.stop()
        WeightlessTestCase.tearDown(self)

    def assertNetStat(self, local, remote, state):
        statelines = getNetStat(local, remote)
        if not state:
            self.assertEquals(0, len(statelines), statelines)
        else:
            self.assertTrue(state in statelines[0], statelines[0])

    def testSimpleServerSetUpAndAFewPOSTRequests(self):
        class MyServer(object):
            def processRequest(self, Method=None, ContentLength=None, *args, **kwargs):
                if Method != 'POST':
                    return
                result = yield http.readRe('(?P<BODY>.*)', ContentLength)
                body = result['BODY']
                yield http.ok()
                yield http.headers('a', 'b')
                yield 'Hello ' + body
        self.httpprotocol.addObserver(MyServer())
        with self.loopingReactor():
            result1 = urlopen(Request('http://localhost:%s/' % self.port, data='Johan')).read()
            result2 = urlopen(Request('http://localhost:%s/' % self.port, data='Erik')).read()
        self.assertEquals('Hello Johan', result1)
        self.assertEquals('Hello Erik', result2)

    def testContentLenght(self):
        body = []
        class MyServer(object):
            def processRequest(this, Method, RequestURI, HTTPVersion, Headers, **kwargs):
                length = int(Headers['content-length'].keys()[0])
                @autostart
                def destination(result):
                    while True:
                        result += (yield)
                result = []
                yield http.copyBytes(length, destination(result))
                self.assertEquals('This is a body', ''.join(result))
                yield http.ok()
                yield http.headers('a', 'b')
                yield 'Hello ' + ''.join(result)
        self.httpprotocol.addObserver(MyServer())
        with self.loopingReactor():
            result1 = urlopen(Request('http://localhost:%s/' % self.port, data='This is a body')).read()
        self.assertEquals('Hello This is a body', result1)

    def testOneRequest(self):
        done = []
        class MyServer(object):
            def processRequest(this, Method, RequestURI, HTTPVersion, Headers, **kwargs):
                self.assertEquals('GET', Method)
                self.assertEquals('/seven', RequestURI)
                self.assertEquals('1.0', HTTPVersion)
                self.assertEquals({}, Headers)
                yield 'Hello there'
                done.append(True)
        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))
        sok.send('GET /seven HTTP/1.0\r\n\r\n')
        while not done:
            self.reactor.step()
        self.assertEquals([True], done)
        self.assertEquals('Hello there', sok.recv(99))

    def testHttp11TwoRequests(self):
        done = []
        class MyServer(object):
            def processRequest(self, Method=None, RequestURI=None, HTTPVersion=None, Headers=None, fragment=None, netloc=None, query=None, path=None, scheme=None):
                yield http.ok()
                yield http.noheaders()
                yield 'Echo ' + RequestURI
                done.append(True)
        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port)) # ONE connection!
        sok.send('GET /six HTTP/1.1\r\n\r\n')
        while not done:
            self.reactor.step()
        response = sok.recv(999)
        self.assertEquals('HTTP/1.1 200 Ok\r\n\r\nEcho /six', response)
        sok.send('GET /seven HTTP/1.1\r\n\r\n')
        done = []
        while not done:
            self.reactor.step()
        self.assertEquals([True], done)
        response = sok.recv(999)
        self.assertEquals('HTTP/1.1 200 Ok\r\n\r\nEcho /seven', response)
        sok.close() # need to do this, because we use HTTP/1.1
        self.reactor.step()

    def testGETWithResponse(self):
        class MyServer(object):
            def processRequest(self, **kwargs):
                yield 'answer 1'
                yield 'answer 2'
        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port)) # ONE connection!
        sok.send('GET /one HTTP/1.1\r\n\r\n')
        self.reactor.step().step().step()
        self.assertEquals('answer 1', sok.recv(999))
        self.reactor.step()
        self.assertEquals('answer 2', sok.recv(999))
        sok.shutdown(1)
        self.reactor.step()
        self.assertEquals('', sok.recv(999))
        sok.close()

    def testPOSTandThenGET(self):
        class MyPOSTServer(object):
            def processRequest(this, Method=None, RequestURI=None, ContentLength=0, **kwargs):
                if Method == 'POST':
                    return this.handle(ContentLength)
            def handle(this, ContentLength):
                body = yield http.readRe('(?P<BODY>.*)', ContentLength)
                self.assertEquals('XXYYZZ', body['BODY'])
                yield http.ok()
                yield http.noheaders()
                yield 'this was the post handler'
        class MyGETServer(object):
            def processRequest(this, Method=None, RequestURI=None, **kwargs):
                if Method == 'GET':
                    return this.handle()
            def handle(self):
                yield http.ok()
                yield http.noheaders()
                yield 'this was the GET handler'
        self.httpprotocol.addObserver(MyPOSTServer())
        self.httpprotocol.addObserver(MyGETServer())
        body = 'XXYYZZ'
        sok = socket()
        sok.connect(('localhost', self.port)) # ONE connection!
        sok.send('POST /one HTTP/1.1\r\nContent-Length: %s\r\n\r\n' % len(body) + body)
        self.reactor.step().step().step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('this was the post handler', sok.recv(999))
        sok.send('GET /two HTTP/1.1\r\n\r\n')
        self.reactor.step().step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('this was the GET handler', sok.recv(999))
        sok.close()
        self.reactor.step()

    def testTwoRequestOnSameConnectionAndConnectionCloseHeader(self):
        done = []
        class MyServer(object):
            def processRequest(this, Method=None, RequestURI=None, ContentLength=0, *args, **kwargs):
                yield http.ok()
                if Method == 'POST':
                    @autostart
                    def devNull():
                        while True: yield
                    yield http.copyBytes(ContentLength, devNull())
                wrong = yield 'Path = ' + str(RequestURI)
                self.assertEquals(None, wrong) # Second request must not end up here
                done.append(True)
        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))
        body = 'XXYYZZ'
        sok.send('POST /one HTTP/1.1\r\nContent-Length: %s\r\n\r\n' % len(body) + body)
        sok.send('GET /two HTTP/1.1\r\nConnection: close\r\n\r\n')
        while not done == [True]:
            self.reactor.step()
        self.assertEquals([True], done)
        self.assertEquals('HTTP/1.1 200 Ok\r\nPath = /one', sok.recv(99))
        while not done == [True, True]:
            self.reactor.step()
        self.assertEquals('HTTP/1.1 200 Ok\r\nPath = /two', sok.recv(99))
        sok.close()

    def testConnectionCloseForHTTP10afterPIPELINING(self):
        class MyServer(object):
            def processRequest(this, Method, RequestURI, HTTPVersion, Headers, *args, **kwargs):
                yield http.ok()
                yield http.headers('Content-Length', 3)
                yield 'Bye'
        self.httpprotocol.addObserver(MyServer())
        sok = socket()
        sok.connect(('localhost', self.port))
        sok.send('GET /one HTTP/1.1\r\n\r\n') #pipeline 2 requests
        sok.send('GET /two HTTP/1.0\r\n\r\n')
        self.reactor.step().step().step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Content-Length: 3\r\n\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Bye', sok.recv(999))
        self.reactor.step()
        self.assertEquals('HTTP/1.1 200 Ok\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Content-Length: 3\r\n\r\n', sok.recv(999))
        self.reactor.step()
        self.assertEquals('Bye', sok.recv(999))
        self.assertEquals('', sok.recv(999))  # empty string means 'closed' in socket land

    def testTimerFiresWhenConnectedClientIsSilent(self):
        sok = socket()
        sok.connect(('localhost', self.port))
        localport = sok.getsockname()[1]
        with self.loopingReactor():
            response = sok.recv(9999)
        self.assertEquals('HTTP/1.1 408 Request Timeout\r\n\r\n', response)
        sok.close()
        stat = getNetStat(self.port, localport)
        self.assertTrue('TIME_WAIT' in stat[0], stat[0])
        stat = getNetStat(localport, self.port)
        self.assertEquals(0, len(stat), stat)

    def testTimerWhenInvalidRequest(self):
        sok = socket()
        sok.connect(('localhost', self.port))
        sok.send('GET / HTTP/1.1\r') # unterminated Request Line
        sok.send('some garbage'*1024) # some kB garbage to trigger buffer protection
        sok.send('\rxyz') # unterminated end of Headers
        self.reactor.step().step().step().step()
        self.assertEquals('HTTP/1.1 413 Request Entity Too Large\r\n\r\n', sok.recv(999))
        #self.reactor.step()
        #self.assertEquals('\r\n', sok.recv(999))
        sok.close()

    def testReuseAddress(self):
        remoteport = self.port + 1
        server = socket()
        server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        server.bind(('127.0.0.1', remoteport))
        server.listen(1)
        local = socket()
        local.connect(('127.0.0.1', remoteport))
        server.close()
        server = socket()
        server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        try:
            server.bind(('127.0.0.1', remoteport))
        except:
            self.fail('bind must succeed')

    def testCloseStatesRemoteFirst(self):
        remoteport = self.port+1
        server = socket()
        server.bind(('127.0.0.1', remoteport))
        server.listen(1)
        local = socket()
        local.connect(('127.0.0.1', remoteport))
        localport = local.getsockname()[1]

        remote = server.accept()[0]
        self.assertNetStat(remoteport, localport, 'ESTABLISHED')
        self.assertNetStat(localport, remoteport, 'ESTABLISHED')

        remote.close()
        self.assertNetStat(remoteport, localport, 'FIN_WAIT')
        self.assertNetStat(localport, remoteport, 'CLOSE_WAIT')

        local.close()
        self.assertNetStat(remoteport, localport, 'TIME_WAIT')
        self.assertNetStat(localport, remoteport, None)

        server.close()
        server = socket()
        try:
            server.bind(('127.0.0.1', remoteport))
            self.fail('re-bind must raise Address Already in Use Exception')
        except AssertionError:
            raise
        except Exception, e:
            pass
예제 #10
0
#
# You should have received a copy of the GNU General Public License
# along with "Weightless"; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
## end license ##

from weightless.core import be
from weightless.io import Reactor, Server
from weightless.httpng import HttpProtocol, http


class HelloWorld(object):
    def processRequest(self, *args, **kwargs):
        yield http.ok()
        yield http.headers('Content-Length', 6)
        yield 'Hello!'


reactor = Reactor()

dna = \
    (Server(reactor, 8080),
        (HttpProtocol(),
            (HelloWorld(),)
        )
    )

server = be(dna)
reactor.loop()
예제 #11
0
 def setUp(self):
     TestCase.setUp(self)
     self._timer = HttpProtocol.Timer
     HttpProtocol.Timer = MockTimer
     self.p = HttpProtocol()
예제 #12
0
 def setUp(self):
     self._timer = HttpProtocol.Timer
     HttpProtocol.Timer = MockTimer
     self.p = HttpProtocol()