Beispiel #1
0
    def test_cookie_parse(self):
        string = 'some_string'
        class RequestHeader(ComplexModel):
            some_field = String

        class SomeService(ServiceBase):
            __in_header__ = RequestHeader

            @rpc(String)
            def some_call(ctx, s):
                assert ctx.in_header.some_field == string

        def start_response(code, headers):
            assert code == HTTP_200

        c = SimpleCookie()
        c['some_field'] = string

        ''.join(wsgiref_validator(WsgiApplication(Application([SomeService], 'tns',
            in_protocol=HttpRpc(parse_cookie=True), out_protocol=HttpRpc())))({
                'SCRIPT_NAME': '',
                'QUERY_STRING': '',
                'PATH_INFO': '/some_call',
                'REQUEST_METHOD': 'GET',
                'SERVER_NAME': 'localhost',
                'SERVER_PORT': "9999",
                'HTTP_COOKIE': str(c),
                'wsgi.url_scheme': 'http',
                'wsgi.version': (1,0),
                'wsgi.input': StringIO(),
                'wsgi.errors': StringIO(),
                'wsgi.multithread': False,
                'wsgi.multiprocess': False,
                'wsgi.run_once': True,
            }, start_response))
Beispiel #2
0
    def test_http_headers(self):
        d = datetime(year=2013, month=1, day=1)
        string = ['hey', 'yo']

        class ResponseHeader(ComplexModel):
            _type_info = {
                'Set-Cookie': String(max_occurs='unbounded'),
                'Expires': DateTime
            }

        class SomeService(ServiceBase):
            __out_header__ = ResponseHeader

            @rpc(String)
            def some_call(ctx, s):
                assert s is not None
                ctx.out_header = ResponseHeader(**{
                    'Set-Cookie': string,
                    'Expires': d
                })

        def start_response(code, headers):
            print(headers)
            assert len([s for s in string
                        if ('Set-Cookie', s) in headers]) == len(string)
            assert dict(headers)['Expires'] == 'Tue, 01 Jan 2013 00:00:00 GMT'

        app = Application([SomeService],
                          'tns',
                          in_protocol=HttpRpc(),
                          out_protocol=HttpRpc())
        wsgi_app = WsgiApplication(app)

        req_dict = {
            'SCRIPT_NAME': '',
            'QUERY_STRING': '&s=foo',
            'PATH_INFO': '/some_call',
            'REQUEST_METHOD': 'GET',
            'SERVER_NAME': 'localhost',
            'SERVER_PORT': "9999",
            'wsgi.url_scheme': 'http',
            'wsgi.version': (1, 0),
            'wsgi.input': StringIO(),
            'wsgi.errors': StringIO(),
            'wsgi.multithread': False,
            'wsgi.multiprocess': False,
            'wsgi.run_once': True,
        }

        ret = wsgi_app(req_dict, start_response)
        print(list(ret))

        wsgi_app = wsgiref_validator(wsgi_app)

        ret = wsgi_app(req_dict, start_response)

        assert list(ret) == [b'']
Beispiel #3
0
    def from_base64(cls, value):
        if value is None:
            return None
        istream = StringIO(value)
        ostream = StringIO()

        base64.decode(istream, ostream)
        ostream.seek(0)

        return Attachment(data=ostream.read())
Beispiel #4
0
    def test_many(self):
        class SomeComplexModel(ComplexModel):
            s = Unicode
            i = Integer

        v = [
            SomeComplexModel(s='a', i=1),
            SomeComplexModel(s='b', i=2),
            SomeComplexModel(s='c', i=3),
            SomeComplexModel(s='d', i=4),
            SomeComplexModel(s='e', i=5),
        ]

        class SomeService(ServiceBase):
            @rpc(_returns=Array(SomeComplexModel))
            def get(ctx):
                return v

        desc = SomeService.public_methods['get']
        ctx = FakeContext(out_object=[v], descriptor=desc)
        ostr = ctx.out_stream = StringIO()
        XmlDocument(Application([SomeService], __name__)) \
                            .serialize(ctx, XmlDocument.RESPONSE)

        elt = etree.fromstring(ostr.getvalue())
        print(etree.tostring(elt, pretty_print=True))

        assert elt.xpath('x:getResult/x:SomeComplexModel/x:i/text()',
                        namespaces={'x': __name__}) == ['1', '2', '3', '4', '5']
        assert elt.xpath('x:getResult/x:SomeComplexModel/x:s/text()',
                        namespaces={'x': __name__}) == ['a', 'b', 'c', 'd', 'e']
Beispiel #5
0
    def test_unicode_chars_in_exception(self):
        class SomeService(ServiceBase):
            @srpc(Unicode(pattern=u'x'), _returns=Unicode)
            def some_call(s):
                test(never,reaches,here)

        app = Application([SomeService], "tns", name="test_mandatory_elements",
                          in_protocol=XmlDocument(validator='lxml'),
                          out_protocol=XmlDocument())
        server = WsgiApplication(app)

        req = (
            '<some_call xmlns="tns">'
                '<s>Ğ</s>'
            '</some_call>'
        )

        resp = server({
            'QUERY_STRING': '',
            'PATH_INFO': '/',
            'REQUEST_METHOD': 'POST',
            'SERVER_NAME': 'localhost',
            'SERVER_PORT': '80',
            'wsgi.input': StringIO(req),
            "wsgi.url_scheme": 'http',
        }, lambda x,y: print(x,y))

        assert 'Ğ' in ''.join(resp)
Beispiel #6
0
    def test_one(self):
        class SomeComplexModel(ComplexModel):
            s = Unicode
            i = Integer

        v = SomeComplexModel(s='a', i=1),

        class SomeService(ServiceBase):
            @rpc(_returns=SomeComplexModel)
            def get(ctx):
                return v

        desc = SomeService.public_methods['get']
        ctx = FakeContext(out_object=v, descriptor=desc)
        ostr = ctx.out_stream = StringIO()
        XmlDocument(Application([SomeService], __name__)) \
                             .serialize(ctx, XmlDocument.RESPONSE)

        elt = etree.fromstring(ostr.getvalue())
        print etree.tostring(elt, pretty_print=True)

        assert elt.xpath('x:getResult/x:i/text()',
                         namespaces={'x': __name__}) == ['1']
        assert elt.xpath('x:getResult/x:s/text()',
                         namespaces={'x': __name__}) == ['a']
Beispiel #7
0
    def serialize(self, ctx, message):
        """Uses ``ctx.out_object``, ``ctx.out_header`` or ``ctx.out_error`` to
        set ``ctx.out_body_doc``, ``ctx.out_header_doc`` and
        ``ctx.out_document`` as an ``lxml.etree._Element instance``.

        Not meant to be overridden.
        """

        assert message in (self.REQUEST, self.RESPONSE)

        self.event_manager.fire_event('before_serialize', ctx)

        if ctx.out_stream is None:
            ctx.out_stream = StringIO()
            logger.debug("%r %d", ctx.out_stream, id(ctx.out_stream))

        if ctx.out_error is not None:
            # All errors at this point must be Fault subclasses.
            inst = ctx.out_error
            cls = inst.__class__
            name = cls.get_type_name()

            ctx.out_document = E.div()
            with self.docfile(ctx.out_stream) as xf:
                # as XmlDocument is not push-ready yet, this is what we do.
                # this is an ugly hack, bear with me.
                retval = XmlCloth.HtmlMicroFormat() \
                                            .to_parent(ctx, cls, inst, xf, name)

        else:
            assert message is self.RESPONSE
            result_message_class = ctx.descriptor.out_message

            name = result_message_class.get_type_name()
            if ctx.descriptor.body_style == BODY_STYLE_WRAPPED:
                if self.ignore_wrappers:
                    result_message = ctx.out_object[0]
                    while result_message_class.Attributes._wrapper and \
                                      len(result_message_class._type_info) == 1:
                        result_message_class, = \
                                        result_message_class._type_info.values()

                else:
                    result_message = result_message_class()

                    for i, attr_name in enumerate(
                            result_message_class._type_info.keys()):
                        setattr(result_message, attr_name, ctx.out_object[i])

            else:
                result_message, = ctx.out_object

            retval = self.incgen(ctx, result_message_class, result_message,
                                 name)

        self.event_manager.fire_event('after_serialize', ctx)

        return retval
Beispiel #8
0
    def to_base64(cls, value):
        if value is None:
            return None

        ostream = StringIO()
        if not (value.data is None):
            istream = StringIO(value.data)

        elif not (value.file_name is None):
            istream = open(value.file_name, 'rb')

        else:
            raise ValueError("Neither data nor a file_name has been specified")

        base64.encode(istream, ostream)
        ostream.seek(0)

        return ostream.read()
Beispiel #9
0
    def serialize(self, ctx, message):
        """Uses ``ctx.out_object``, ``ctx.out_header`` or ``ctx.out_error`` to
        set ``ctx.out_body_doc``, ``ctx.out_header_doc`` and
        ``ctx.out_document`` as an ``lxml.etree._Element instance``.

        Not meant to be overridden.
        """

        assert message in (self.REQUEST, self.RESPONSE)

        self.event_manager.fire_event('before_serialize', ctx)

        if ctx.out_stream is None:
            ctx.out_stream = StringIO()

        if ctx.out_error is not None:
            # All errors at this point must be Fault subclasses.
            inst = ctx.out_error
            cls = inst.__class__
            name = cls.get_type_name()

            ctx.out_document = E.div()
            from lxml import etree
            with etree.xmlfile(ctx.out_stream) as xf:
                retval = HtmlBase.HtmlMicroFormat() \
                                            .to_parent(ctx, cls, inst, xf, name)

        else:
            assert message is self.RESPONSE
            result_message_class = ctx.descriptor.out_message

            name = result_message_class.get_type_name()
            if ctx.descriptor.body_style == BODY_STYLE_WRAPPED:
                if self.ignore_wrappers:
                    ctx.out_object = ctx.out_object[0]
                    result_message = ctx.out_object
                    while result_message_class.Attributes._wrapper:
                        result_message_class = next(
                            iter(result_message_class._type_info.values()))

                else:
                    result_message = result_message_class()

                    for i, attr_name in enumerate(
                            result_message_class._type_info.keys()):
                        setattr(result_message, attr_name, ctx.out_object[i])

            else:
                result_message = ctx.out_object

            retval = self.incgen(ctx, result_message_class, result_message,
                                 name)

        self.event_manager.fire_event('after_serialize', ctx)

        return retval
Beispiel #10
0
    def test_wsgi(self):
        retval = ''.join(self.wsgi_app({
            'PATH_INFO': '/',
            'QUERY_STRING': 'wsdl',
            'SERVER_NAME': 'localhost',
            'SERVER_PORT': '7000',
            'REQUEST_METHOD': 'GET',
            'wsgi.url_scheme': 'http',
            'wsgi.input': StringIO(),
        }, start_response))

        from lxml import etree

        assert etree.fromstring(retval).tag == '{%s}definitions' % NS_WSDL
Beispiel #11
0
    def from_base64(cls, value):
        if value is None:
            return None
        istream = StringIO(value)
        ostream = StringIO()

        base64.decode(istream, ostream)
        ostream.seek(0)

        return Attachment(data=ostream.read())
Beispiel #12
0
    def test_fault_generation(self):
        class SoapException(ServiceBase):
            @srpc()
            def soap_exception():
                raise Fault(
                    "Client.Plausible", "A plausible fault", 'http://faultactor.example.com')
        app = Application([SoapException], 'tns', in_protocol=Soap12(), out_protocol=Soap12())

        req = """
        <soap12env:Envelope
                xmlns:soap12env="http://www.w3.org/2003/05/soap-envelope"
                xmlns:tns="tns">
            <soap12env:Body>
                <tns:soap_exception/>
            </soap12env:Body>
        </soap12env:Envelope>
        """

        server = WsgiApplication(app)
        response = etree.fromstring(''.join(server({
            'QUERY_STRING': '',
            'PATH_INFO': '/call',
            'REQUEST_METHOD': 'GET',
            'wsgi.input': StringIO(req)
        }, start_response, "http://null")))

        response_str = etree.tostring(response, pretty_print=True)
        print(response_str)

        expected = """
            <soap12env:Envelope xmlns:soap12env="http://www.w3.org/2003/05/soap-envelope">
              <soap12env:Body>
                <soap12env:Fault>
                  <soap12env:Reason>
                      <soap12env:Text xml:lang="en">A plausible fault</soap12env:Text>
                  </soap12env:Reason>
                  <soap12env:Role>http://faultactor.example.com</soap12env:Role>
                  <soap12env:Code>
                    <soap12env:Value>soap12env:Sender</soap12env:Value>
                    <soap12env:Subcode>
                      <soap12env:Value>Plausible</soap12env:Value>
                    </soap12env:Subcode>
                  </soap12env:Code>
                </soap12env:Fault>
              </soap12env:Body>
            </soap12env:Envelope>"""
        if not LXMLOutputChecker().check_output(expected, response_str, PARSE_XML):
            raise Exception("Got: %s but expected: %s" % (response_str, expected))
Beispiel #13
0
    def to_base64(cls, value):
        if value is None:
            return None

        ostream = StringIO()
        if not (value.data is None):
            istream = StringIO(value.data)

        elif not (value.file_name is None):
            istream = open(value.file_name, 'rb')

        else:
            raise ValueError("Neither data nor a file_name has been specified")

        base64.encode(istream, ostream)
        ostream.seek(0)

        return ostream.read()
Beispiel #14
0
    def test_soap_bare_empty_output(self):
        class SomeService(ServiceBase):
            @rpc(String, _body_style='bare')
            def some_call(ctx, s):
                assert s == 'abc'

        app = Application([SomeService],
                          'tns',
                          in_protocol=Soap11(),
                          out_protocol=Soap11(cleanup_namespaces=True))

        req = """
        <soap11env:Envelope  xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/"
                        xmlns:tns="tns">
            <soap11env:Body>
                <tns:some_call>abc</tns:some_call>
            </soap11env:Body>
        </soap11env:Envelope>
        """

        server = WsgiApplication(app)
        resp = etree.fromstring(''.join(
            server(
                {
                    'QUERY_STRING': '',
                    'PATH_INFO': '/call',
                    'REQUEST_METHOD': 'GET',
                    'SERVER_NAME': 'localhost',
                    'wsgi.input': StringIO(req)
                }, start_response, "http://null")))

        print(etree.tostring(resp, pretty_print=True))

        assert resp[0].tag == '{http://schemas.xmlsoap.org/soap/envelope/}Body'
        assert len(resp[0]) == 1
        assert resp[0][0].tag == '{tns}some_call' + RESPONSE_SUFFIX
        assert len(resp[0][0]) == 0
Beispiel #15
0
    def test_soap_bare_wrapped_array_output(self):
        class SomeService(ServiceBase):
            @rpc(_body_style='bare', _returns=Array(String))
            def some_call(ctx):
                return ['abc', 'def']

        app = Application([SomeService],
                          'tns',
                          in_protocol=Soap11(),
                          out_protocol=Soap11(cleanup_namespaces=True))

        req = """
        <soap11env:Envelope  xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/"
                        xmlns:tns="tns">
            <soap11env:Body>
                <tns:some_call/>
            </soap11env:Body>
        </soap11env:Envelope>
        """

        server = WsgiApplication(app)
        resp = etree.fromstring(''.join(
            server(
                {
                    'QUERY_STRING': '',
                    'PATH_INFO': '/call',
                    'REQUEST_METHOD': 'GET',
                    'wsgi.input': StringIO(req)
                }, start_response, "http://null")))

        print(etree.tostring(resp, pretty_print=True))

        assert resp[0].tag == '{http://schemas.xmlsoap.org/soap/envelope/}Body'
        assert resp[0][0].tag == '{tns}some_call' + RESPONSE_SUFFIX
        assert resp[0][0][0].text == 'abc'
        assert resp[0][0][1].text == 'def'
Beispiel #16
0
    def test_rpc(self):
        data = {"a": "b", "c": "d"}

        class KeyValuePair(ComplexModel):
            key = Unicode
            value = Unicode

        class Service(ServiceBase):
            @rpc(String(max_occurs='unbounded'),
                 _returns=Array(KeyValuePair),
                 _in_variable_names={'keys': 'key'})
            def get_values(ctx, keys):
                for k in keys:
                    yield KeyValuePair(key=k, value=data[k])

        application = Application(
            [Service],
            in_protocol=MessagePackRpc(),
            out_protocol=MessagePackRpc(ignore_wrappers=False),
            name='Service',
            tns='tns')
        server = WsgiApplication(application)

        input_string = msgpack.packb([0, 0, "get_values", [["a", "c"]]])
        input_stream = StringIO(input_string)

        ret = server(
            {
                'CONTENT_LENGTH': str(len(input_string)),
                'CONTENT_TYPE': 'application/x-msgpack',
                'HTTP_CONNECTION': 'close',
                'HTTP_CONTENT_LENGTH': str(len(input_string)),
                'HTTP_CONTENT_TYPE': 'application/x-msgpack',
                'PATH_INFO': '/',
                'QUERY_STRING': '',
                'SERVER_NAME': 'localhost',
                'SERVER_PORT': '7000',
                'REQUEST_METHOD': 'POST',
                'wsgi.url_scheme': 'http',
                'wsgi.input': input_stream,
            }, start_response)

        ret = ''.join(ret)
        print(repr(ret))
        print(msgpack.unpackb(ret))
        s = msgpack.packb([
            1, 0, None, {
                'get_valuesResponse': {
                    'get_valuesResult': [
                        {
                            "KeyValuePair": {
                                'value': 'b',
                                'key': 'a'
                            }
                        },
                        {
                            "KeyValuePair": {
                                'value': 'd',
                                'key': 'c'
                            }
                        },
                    ]
                }
            }
        ])
        print(s)
        assert ret == s