Esempio n. 1
0
File: http.py Progetto: lanwan/spyne
def _cb_deferred(ret, request, p_ctx, others, resource, cb=True):
    resp_code = p_ctx.transport.resp_code
    # If user code set its own response code, don't touch it.
    if resp_code is None:
        resp_code = HTTP_200
    request.setResponseCode(int(resp_code[:3]))

    _set_response_headers(request, p_ctx.transport.resp_headers)

    om = p_ctx.descriptor.out_message
    if cb and ((not issubclass(om, ComplexModelBase)) or len(om._type_info) <= 1):
        p_ctx.out_object = [ret]
    else:
        p_ctx.out_object = ret

    retval = None
    if isinstance(ret, PushBase):
        retval = _init_push(ret, request, p_ctx, others, resource)
    else:
        resource.http_transport.get_out_string(p_ctx)

        producer = Producer(p_ctx.out_string, request)
        producer.deferred.addCallback(_cb_request_finished, request, p_ctx)
        producer.deferred.addErrback(_eb_request_finished, request, p_ctx)

        request.registerProducer(producer, False)

    process_contexts(resource.http_transport, others, p_ctx)

    return retval
Esempio n. 2
0
    def handle_error(self, p_ctx, others, exc):
        self.spyne_tpt.get_out_string(p_ctx)

        if isinstance(exc, InternalError):
            error = self.spyne_tpt.OUT_RESPONSE_SERVER_ERROR
        else:
            error = self.spyne_tpt.OUT_RESPONSE_CLIENT_ERROR

        data = p_ctx.out_document[0]
        if isinstance(data, dict):
            data = list(data.values())

        out_string = msgpack.packb([
            error, msgpack.packb(data),
        ])

        self.enqueue_outresp_data(id(p_ctx), out_string)

        p_ctx.transport.resp_length = len(out_string)
        p_ctx.close()

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 3
0
    async def response(
        self,
        req: web.Request,
        p_ctx: AioMethodContext,
        others: list,
        error: typing.Optional[Fault] = None,
    ) -> web.StreamResponse:
        status_code = 200
        if p_ctx.transport.resp_code:
            status_code = int(p_ctx.transport.resp_code[:3])

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            logger.exception(e)

        p_ctx.close()

        return await self.make_streaming_response(
            req=req,
            content=p_ctx.out_string,
            status=status_code,
            chunked=self._chunked,
            headers=p_ctx.transport.resp_headers,
        )
Esempio n. 4
0
            def _cb_push():
                process_contexts(self.http_transport, others, p_ctx)

                producer = _Producer(p_ctx.out_string, request)
                producer.deferred.addCallbacks(_cb_request_finished,
                                               _eb_request_finished)
                request.registerProducer(producer, False)
Esempio n. 5
0
File: wsgi.py Progetto: nareni/spyne
    def handle_error(self, p_ctx, others, error, start_response):
        """Serialize errors to an iterable of strings and return them.

        :param p_ctx: Primary (non-aux) context.
        :param others: List if auxiliary contexts (can be empty).
        :param error: One of ctx.{in,out}_error.
        :param start_response: See the WSGI spec for more info.
        """

        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = \
                p_ctx.out_protocol.fault_to_http_response_code(error)

        self.get_out_string(p_ctx)

        # consume the generator to get the length
        p_ctx.out_string = list(p_ctx.out_string)

        p_ctx.transport.resp_headers['Content-Length'] = \
                                    str(sum((len(s) for s in p_ctx.out_string)))
        self.event_manager.fire_event('wsgi_exception', p_ctx)

        start_response(p_ctx.transport.resp_code,
                       _gen_http_headers(p_ctx.transport.resp_headers))

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        return chain(p_ctx.out_string, self.__finalize(p_ctx))
Esempio n. 6
0
def _cb_deferred(ret, prot, p_ctx, others, nowrap=False):
    # if there is one return value or the output is bare (which means there
    # can't be anything other than 1 return value case) use the enclosing list.
    # otherwise, the return value is a tuple anyway, so leave it alone.
    if nowrap:
        p_ctx.out_object = ret

    else:
        if p_ctx.descriptor.is_out_bare():
            p_ctx.out_object = [ret]

        else:
            if len(p_ctx.descriptor.out_message._type_info) > 1:
                p_ctx.out_object = ret
            else:
                p_ctx.out_object = [ret]

    try:
        prot.spyne_tpt.get_out_string(p_ctx)
        prot.spyne_tpt.pack(p_ctx)

        out_string = b''.join(p_ctx.out_string)
        p_ctx.transport.resp_length = len(out_string)

        prot.enqueue_outresp_data(id(p_ctx), out_string)

    except Exception as e:
        logger.exception(e)
        prot.handle_error(p_ctx, others, InternalError(e))

    finally:
        p_ctx.close()

    process_contexts(prot.spyne_tpt, others, p_ctx)
Esempio n. 7
0
    def serve_forever(self):
        """Runs the ZeroMQ server."""

        while True:
            error = None

            initial_ctx = ZmqMethodContext(self)
            initial_ctx.in_string = [self.zmq_socket.recv()]

            contexts = self.generate_contexts(initial_ctx)
            p_ctx, others = contexts[0], contexts[1:]
            if p_ctx.in_error:
                p_ctx.out_object = p_ctx.in_error
                error = p_ctx.in_error

            else:
                self.get_in_object(p_ctx)

                if p_ctx.in_error:
                    p_ctx.out_object = p_ctx.in_error
                    error = p_ctx.in_error
                else:
                    self.get_out_object(p_ctx)
                    if p_ctx.out_error:
                        p_ctx.out_object = p_ctx.out_error
                        error = p_ctx.out_error

            self.get_out_string(p_ctx)

            process_contexts(self, others, error)

            self.zmq_socket.send(''.join(p_ctx.out_string))

            p_ctx.close()
Esempio n. 8
0
def _cb_deferred(ret, prot, p_ctx, others, nowrap=False):
    # if there is one return value or the output is bare (which means there
    # can't be anything other than 1 return value case) use the enclosing list.
    # otherwise, the return value is a tuple anyway, so leave it alone.
    if nowrap:
        p_ctx.out_object = ret

    else:
        if p_ctx.descriptor.is_out_bare():
            p_ctx.out_object = [ret]

        else:
            if len(p_ctx.descriptor.out_message._type_info) > 1:
                p_ctx.out_object = ret
            else:
                p_ctx.out_object = [ret]

    try:
        prot.spyne_tpt.get_out_string(p_ctx)
        prot.spyne_tpt.pack(p_ctx)

        out_string = b''.join(p_ctx.out_string)
        p_ctx.transport.resp_length = len(out_string)

        prot.enqueue_outresp_data(id(p_ctx), out_string)

    except Exception as e:
        logger.exception(e)
        logger.error("%r", p_ctx)
        prot.handle_error(p_ctx, others, InternalError(e))

    finally:
        p_ctx.close()

    process_contexts(prot.spyne_tpt, others, p_ctx)
Esempio n. 9
0
    def response(self, response, p_ctx, others, error=None):
        """Populate response with transport headers and finalize it.

        :param response: Django HttpResponse.
        :param p_ctx: Primary (non-aux) context.
        :param others: List if auxiliary contexts (can be empty).
        :param error: One of ctx.{in,out}_error.
        :returns: Django HttpResponse

        """
        for h, v in p_ctx.transport.resp_headers.items():
            if v is not None:
                response[h] = v

        if p_ctx.transport.resp_code:
            response.status_code = int(p_ctx.transport.resp_code[:3])

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        p_ctx.close()

        return response
Esempio n. 10
0
    def handle_rpc_error(self, p_ctx, others, error, request):
        logger.error(error)

        resp_code = p_ctx.transport.resp_code
        # If user code set its own response code, don't touch it.
        if resp_code is None:
            resp_code = p_ctx.out_protocol.fault_to_http_response_code(error)

        request.setResponseCode(int(resp_code[:3]))
        _set_response_headers(request, p_ctx.transport.resp_headers)

        # In case user code set its own out_* attributes before failing.
        p_ctx.out_document = None
        p_ctx.out_string = None

        p_ctx.out_object = error
        self.http_transport.get_out_string(p_ctx)

        retval = ''.join(p_ctx.out_string)

        p_ctx.close()

        process_contexts(self.http_transport, others, p_ctx, error=error)

        return retval
Esempio n. 11
0
File: http.py Progetto: tunks/spyne
def _cb_deferred(ret, request, p_ctx, others, resource, cb=True):
    resp_code = p_ctx.transport.resp_code
    # If user code set its own response code, don't touch it.
    if resp_code is None:
        resp_code = HTTP_200
    request.setResponseCode(int(resp_code[:3]))

    _set_response_headers(request, p_ctx.transport.resp_headers)

    om = p_ctx.descriptor.out_message
    if cb and ((not issubclass(om, ComplexModelBase))
               or len(om._type_info) <= 1):
        p_ctx.out_object = [ret]
    else:
        p_ctx.out_object = ret

    retval = None
    if isinstance(ret, PushBase):
        retval = _init_push(ret, request, p_ctx, others, resource)
    else:
        resource.http_transport.get_out_string(p_ctx)

        producer = Producer(p_ctx.out_string, request)
        producer.deferred.addCallback(_cb_request_finished, request, p_ctx)
        producer.deferred.addErrback(_eb_request_finished, request, p_ctx)

        request.registerProducer(producer, False)

    process_contexts(resource.http_transport, others, p_ctx)

    return retval
Esempio n. 12
0
    def handle_error(self, p_ctx, others, exc):
        self.spyne_tpt.get_out_string(p_ctx)

        if isinstance(exc, InternalError):
            error = self.spyne_tpt.OUT_RESPONSE_SERVER_ERROR
        else:
            error = self.spyne_tpt.OUT_RESPONSE_CLIENT_ERROR

        data = p_ctx.out_document[0]
        if isinstance(data, dict):
            data = list(data.values())

        out_string = msgpack.packb([
            error,
            msgpack.packb(data),
        ])

        self.enqueue_outresp_data(id(p_ctx), out_string)

        p_ctx.transport.resp_length = len(out_string)
        p_ctx.close()

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 13
0
File: wsgi.py Progetto: plq/spyne
    def handle_error(self, p_ctx, others, error, start_response):
        """Serialize errors to an iterable of strings and return them.

        :param p_ctx: Primary (non-aux) context.
        :param others: List if auxiliary contexts (can be empty).
        :param error: One of ctx.{in,out}_error.
        :param start_response: See the WSGI spec for more info.
        """

        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = \
                p_ctx.out_protocol.fault_to_http_response_code(error)

        self.get_out_string(p_ctx)

        # consume the generator to get the length
        p_ctx.out_string = list(p_ctx.out_string)

        p_ctx.transport.resp_headers['Content-Length'] = \
                                    str(sum((len(s) for s in p_ctx.out_string)))
        self.event_manager.fire_event('wsgi_exception', p_ctx)

        start_response(p_ctx.transport.resp_code,
                                _gen_http_headers(p_ctx.transport.resp_headers))

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        return chain(p_ctx.out_string, self.__finalize(p_ctx))
Esempio n. 14
0
    def serve_forever(self):
        """Runs the ZeroMQ server."""

        while True:
            error = None

            initial_ctx = ZmqMethodContext(self)
            initial_ctx.in_string = [self.zmq_socket.recv()]

            contexts = self.generate_contexts(initial_ctx)
            p_ctx, others = contexts[0], contexts[1:]
            if p_ctx.in_error:
                p_ctx.out_object = p_ctx.in_error
                error = p_ctx.in_error

            else:
                self.get_in_object(p_ctx)

                if p_ctx.in_error:
                    p_ctx.out_object = p_ctx.in_error
                    error = p_ctx.in_error
                else:
                    self.get_out_object(p_ctx)
                    if p_ctx.out_error:
                        p_ctx.out_object = p_ctx.out_error
                        error = p_ctx.out_error

            self.get_out_string(p_ctx)

            process_contexts(self, others, error)

            self.zmq_socket.send(b''.join(p_ctx.out_string))

            p_ctx.close()
Esempio n. 15
0
    def response(self, response, p_ctx, others, error=None):
        """Populate response with transport headers and finalize it.

        :param response: Django HttpResponse.
        :param p_ctx: Primary (non-aux) context.
        :param others: List if auxiliary contexts (can be empty).
        :param error: One of ctx.{in,out}_error.
        :returns: Django HttpResponse

        """
        for h, v in p_ctx.transport.resp_headers.items():
            if v is not None:
                response[h] = v

        if p_ctx.transport.resp_code:
            response.status_code = int(p_ctx.transport.resp_code[:3])

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        p_ctx.close()

        return response
Esempio n. 16
0
    def handle_rpc(self, request):
        initial_ctx = HttpMethodContext(self.http_transport, request,
                                self.http_transport.app.out_protocol.mime_type)
        initial_ctx.in_string = [request.content.getvalue()]

        contexts = self.http_transport.generate_contexts(initial_ctx)
        p_ctx, others = contexts[0], contexts[1:]

        if p_ctx.in_error:
            return self.handle_error(p_ctx, others, p_ctx.in_error, request)

        else:
            self.http_transport.get_in_object(p_ctx)

            if p_ctx.in_error:
                return self.handle_error(p_ctx, others, p_ctx.in_error, request)
            else:
                self.http_transport.get_out_object(p_ctx)
                if p_ctx.out_error:
                    return self.handle_error(p_ctx, others, p_ctx.out_error,
                                                                        request)

        self.http_transport.get_out_string(p_ctx)

        process_contexts(self.http_transport, others, p_ctx)

        def _cb_request_finished(request):
            request.finish()

        producer = _Producer(p_ctx.out_string, request)
        producer.deferred.addErrback(err).addCallback(_cb_request_finished)
        request.registerProducer(producer, False)

        return NOT_DONE_YET
Esempio n. 17
0
File: http.py Progetto: DXist/spyne
            def _cb_push():
                process_contexts(self.http_transport, others, p_ctx)

                producer = _Producer(p_ctx.out_string, request)
                producer.deferred.addCallbacks(_cb_request_finished,
                                                           _eb_request_finished)
                request.registerProducer(producer, False)
Esempio n. 18
0
    def handle_error(self, p_ctx, others, error):
        self.get_out_string(p_ctx)

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 19
0
    def handle_error(self, p_ctx, others, error):
        self.get_out_string(p_ctx)

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 20
0
        def _cb_deferred(retval, cb=True):
            if cb and len(p_ctx.descriptor.out_message._type_info) <= 1:
                p_ctx.out_object = [retval]
            else:
                p_ctx.out_object = retval

            tpt.get_out_string(p_ctx)
            self.sendFrame(opcode, ''.join(p_ctx.out_string), fin)
            p_ctx.close()
            process_contexts(tpt, others, p_ctx)
Esempio n. 21
0
        def _cb_deferred(retval, cb=True):
            if cb and len(p_ctx.descriptor.out_message._type_info) <= 1:
                p_ctx.out_object = [retval]
            else:
                p_ctx.out_object = retval

            tpt.get_out_string(p_ctx)
            self.sendFrame(opcode, ''.join(p_ctx.out_string), fin)
            p_ctx.close()
            process_contexts(tpt, others, p_ctx)
Esempio n. 22
0
def _cb_deferred(ret, request, p_ctx, others, resource, cb=True):
    resp_code = p_ctx.transport.resp_code
    # If user code set its own response code, don't touch it.
    if resp_code is None:
        resp_code = HTTP_200
    request.setResponseCode(int(resp_code[:3]))

    _set_response_headers(request, p_ctx.transport.resp_headers)

    om = p_ctx.descriptor.out_message
    single_class = None
    if cb and ((not issubclass(om, ComplexModelBase)) or len(om._type_info) <= 1):
        p_ctx.out_object = [ret]
        if len(om._type_info) == 1:
            single_class, = om._type_info.values()

    else:
        p_ctx.out_object = ret

    retval = NOT_DONE_YET

    if isinstance(ret, PushBase):
        retval = _init_push(ret, request, p_ctx, others, resource)

    elif ((isclass(om) and issubclass(om, File)) or
          (isclass(single_class) and issubclass(single_class, File))) and \
         isinstance(p_ctx.out_protocol, HttpRpc) and \
                                      getattr(ret, 'abspath', None) is not None:

        file = static.File(ret.abspath,
                        defaultType=str(ret.type) or 'application/octet-stream')
        retval = _render_file(file, request)
        if retval != NOT_DONE_YET and cb:
            request.write(retval)
            request.finish()
            p_ctx.close()
        else:
            def _close_only_context(ret):
                p_ctx.close()

            request.notifyFinish().addCallback(_close_only_context)
            request.notifyFinish().addErrback(_eb_request_finished, request, p_ctx)

    else:
        resource.http_transport.get_out_string(p_ctx)

        producer = Producer(p_ctx.out_string, request)
        producer.deferred.addCallback(_cb_request_finished, request, p_ctx)
        producer.deferred.addErrback(_eb_request_finished, request, p_ctx)

        request.registerProducer(producer, False)

    process_contexts(resource.http_transport, others, p_ctx)

    return retval
Esempio n. 23
0
    def handle_error(self, p_ctx, others, error, request):
        resp_code = self.http_transport.app.out_protocol \
                                            .fault_to_http_response_code(error)

        request.setResponseCode(int(resp_code[:3]))

        p_ctx.out_object = error
        self.http_transport.get_out_string(p_ctx)

        process_contexts(self.http_transport, others, p_ctx, error=error)

        return ''.join(p_ctx.out_string)
Esempio n. 24
0
    def handle_error(self, p_ctx, others, error, request):
        resp_code = self.http_transport.app.out_protocol \
                                            .fault_to_http_response_code(error)

        request.setResponseCode(int(resp_code[:3]))

        p_ctx.out_object = error
        self.http_transport.get_out_string(p_ctx)

        process_contexts(self.http_transport, others, p_ctx, error=error)

        return ''.join(p_ctx.out_string)
Esempio n. 25
0
        def _cb_deferred(retval, request):
            if len(p_ctx.descriptor.out_message._type_info) <= 1:
                p_ctx.out_object = [retval]
            else:
                p_ctx.out_object = retval

            self.http_transport.get_out_string(p_ctx)

            process_contexts(self.http_transport, others, p_ctx)

            producer = _Producer(p_ctx.out_string, request)
            producer.deferred.addCallbacks(_cb_request_finished,
                                                           _eb_request_finished)
            request.registerProducer(producer, False)
Esempio n. 26
0
        def _cb_deferred(retval, request, cb=True):
            if cb and len(p_ctx.descriptor.out_message._type_info) <= 1:
                p_ctx.out_object = [retval]
            else:
                p_ctx.out_object = retval

            self.http_transport.get_out_string(p_ctx)

            process_contexts(self.http_transport, others, p_ctx)

            producer = _Producer(p_ctx.out_string, request)
            producer.deferred.addCallbacks(_cb_request_finished,
                                           _eb_request_finished)
            request.registerProducer(producer, False)
Esempio n. 27
0
def _cb_deferred(retval, request, p_ctx, others, resource, cb=True):
    if cb and len(p_ctx.descriptor.out_message._type_info) <= 1:
        p_ctx.out_object = [retval]
    else:
        p_ctx.out_object = retval

    resource.http_transport.get_out_string(p_ctx)

    process_contexts(resource.http_transport, others, p_ctx)

    producer = Producer(p_ctx.out_string, request)
    producer.deferred.addCallback(_cb_request_finished, p_ctx, others, resource)
    producer.deferred.addErrback(_eb_request_finished, p_ctx, others, resource)

    request.registerProducer(producer, False)
Esempio n. 28
0
    def handle_error(self, p_ctx, others, exc):
        self._transport.get_out_string(p_ctx)

        if isinstance(exc, InternalError):
            error = SERVER_ERROR
        else:
            error = CLIENT_ERROR

        out_string = msgpack.packb({error: msgpack.packb(p_ctx.out_document[0].values())})
        self.transport.write(out_string)
        print "HE", repr(out_string)
        p_ctx.close()

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 29
0
    def handle_error(self, p_ctx, others, error, start_response):
        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = \
                self.app.out_protocol.fault_to_http_response_code(error)

        self.get_out_string(p_ctx)
        p_ctx.out_string = [''.join(p_ctx.out_string)]

        p_ctx.transport.resp_headers['Content-Length'] = str(len(p_ctx.out_string[0]))
        self.event_manager.fire_event('wsgi_exception', p_ctx)

        start_response(p_ctx.transport.resp_code,
                                             p_ctx.transport.resp_headers.items())
        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception,e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 30
0
def _cb_deferred(retval, prot, p_ctx, others, nowrap=False):
    if len(p_ctx.descriptor.out_message._type_info) > 1 or nowrap:
        p_ctx.out_object = retval
    else:
        p_ctx.out_object = [retval]

    try:
        prot._transport.get_out_string(p_ctx)
        p_ctx.out_string = list(p_ctx.out_string)
        print "PC", p_ctx.out_string
        prot.transport.write(''.join(p_ctx.out_string))

    except:
        err(retval)

    finally:
        p_ctx.close()

    process_contexts(prot._transport, others, p_ctx)
Esempio n. 31
0
def _cb_deferred(retval, prot, p_ctx, others, nowrap=False):
    if len(p_ctx.descriptor.out_message._type_info) > 1 or nowrap:
        p_ctx.out_object = retval
    else:
        p_ctx.out_object = [retval]

    try:
        prot._transport.get_out_string(p_ctx)
        p_ctx.out_string = list(p_ctx.out_string)
        print "PC", p_ctx.out_string
        prot.transport.write(''.join(p_ctx.out_string))

    except:
        err(retval)

    finally:
        p_ctx.close()

    process_contexts(prot._transport, others, p_ctx)
Esempio n. 32
0
    def handle_rpc(self, request):
        initial_ctx = HttpMethodContext(
            self.http_transport, request,
            self.http_transport.app.out_protocol.mime_type)
        initial_ctx.in_string = [request.content.getvalue()]

        contexts = self.http_transport.generate_contexts(initial_ctx)
        p_ctx, others = contexts[0], contexts[1:]

        if p_ctx.in_error:
            return self.handle_error(p_ctx, others, p_ctx.in_error, request)

        else:
            self.http_transport.get_in_object(p_ctx)

            if p_ctx.in_error:
                return self.handle_error(p_ctx, others, p_ctx.in_error,
                                         request)
            else:
                self.http_transport.get_out_object(p_ctx)
                if p_ctx.out_error:
                    return self.handle_error(p_ctx, others, p_ctx.out_error,
                                             request)

        self.http_transport.get_out_string(p_ctx)

        process_contexts(self.http_transport, others, p_ctx)

        def _cb_request_finished(request):
            request.finish()
            p_ctx.close()

        def _eb_request_finished(request):
            err(request)
            p_ctx.close()

        producer = _Producer(p_ctx.out_string, request)
        producer.deferred.addErrback(_eb_request_finished).addCallback(
            _cb_request_finished)
        request.registerProducer(producer, False)

        return NOT_DONE_YET
Esempio n. 33
0
    def handle_error(self, p_ctx, others, error, start_response):
        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = \
                self.app.out_protocol.fault_to_http_response_code(error)

        self.get_out_string(p_ctx)
        p_ctx.out_string = [''.join(p_ctx.out_string)]

        p_ctx.transport.resp_headers['Content-Length'] = \
                                                   str(len(p_ctx.out_string[0]))
        self.event_manager.fire_event('wsgi_exception', p_ctx)

        start_response(p_ctx.transport.resp_code,
                       _gen_http_headers(p_ctx.transport.resp_headers))

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception, e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 34
0
    def handle_error(self, p_ctx, others, exc):
        self._transport.get_out_string(p_ctx)

        if isinstance(exc, InternalError):
            error = OUT_RESPONSE_SERVER_ERROR
        else:
            error = OUT_RESPONSE_CLIENT_ERROR

        out_string = msgpack.packb([
            error,
            msgpack.packb(p_ctx.out_document[0].values()),
        ])
        self.transport.write(out_string)
        p_ctx.close()

        try:
            process_contexts(self, others, p_ctx, error=error)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 35
0
def _cb_deferred(retval, prot, p_ctx, others, nowrap=False):
    if len(p_ctx.descriptor.out_message._type_info) > 1 or nowrap:
        p_ctx.out_object = retval
    else:
        p_ctx.out_object = [retval]

    try:
        prot._transport.get_out_string(p_ctx)
        out_string = msgpack.packb({NO_ERROR: "".join(p_ctx.out_string)})
        prot.transport.write(out_string)
        print "PC", repr(out_string)

    except Exception as e:
        logger.exception(e)
        prot.handle_error(p_ctx, others, InternalError(e))

    finally:
        p_ctx.close()

    process_contexts(prot._transport, others, p_ctx)
Esempio n. 36
0
    def _cb_deferred(self, ret, p_ctx, others, nowrap=False):
        # this means callback is not invoked directly instead of as part of a
        # deferred chain
        if not nowrap:
            # if there is one return value or the output is bare (which means
            # there can't be anything other than 1 return value case) use the
            # enclosing list. otherwise, the return value is a tuple anyway, so
            # leave it be.
            if p_ctx.descriptor.is_out_bare():
                p_ctx.out_object = [ret]

            else:
                if len(p_ctx.descriptor.out_message._type_info) > 1:
                    p_ctx.out_object = ret
                else:
                    p_ctx.out_object = [ret]

        if p_ctx.oob_ctx is not None:
            assert isinstance(p_ctx.oob_ctx.d, Deferred)

            p_ctx.oob_ctx.d.callback(p_ctx.out_object)
            return

        try:
            self.spyne_tpt.get_out_string(p_ctx)
            self.spyne_tpt.pack(p_ctx)

            out_string = b''.join(p_ctx.out_string)
            p_ctx.transport.resp_length = len(out_string)

            self.enqueue_outresp_data(id(p_ctx), out_string)

        except Exception as e:
            logger.exception(e)
            logger.error("%r", p_ctx)
            self.handle_error(p_ctx, others, InternalError(e))

        finally:
            p_ctx.close()

        process_contexts(self.spyne_tpt, others, p_ctx)
Esempio n. 37
0
def _cb_deferred(retval, prot, p_ctx, others, nowrap=False):
    if len(p_ctx.descriptor.out_message._type_info) > 1 or nowrap:
        p_ctx.out_object = retval
    else:
        p_ctx.out_object = [retval]

    try:
        prot._transport.get_out_string(p_ctx)
        prot._transport.pack(p_ctx)

        out_string = ''.join(p_ctx.out_string)
        prot.transport.write(out_string)

    except Exception as e:
        logger.exception(e)
        prot.handle_error(p_ctx, others, InternalError(e))

    finally:
        p_ctx.close()

    process_contexts(prot._transport, others, p_ctx)
Esempio n. 38
0
File: msgpack.py Progetto: plq/spyne
def _cb_deferred(ret, prot, p_ctx, others, nowrap=False):
    # this means callback is not invoked directly instead of as part of a
    # deferred chain
    if not nowrap:
        # if there is one return value or the output is bare (which means there
        # can't be anything other than 1 return value case) use the enclosing
        # list. otherwise, the return value is a tuple anyway, so leave it be.
        if p_ctx.descriptor.is_out_bare():
            p_ctx.out_object = [ret]

        else:
            if len(p_ctx.descriptor.out_message._type_info) > 1:
                p_ctx.out_object = ret
            else:
                p_ctx.out_object = [ret]

    if p_ctx.oob_ctx is not None:
        assert isinstance(p_ctx.oob_ctx.d, Deferred)

        p_ctx.oob_ctx.d.callback(p_ctx.out_object)
        return

    try:
        prot.spyne_tpt.get_out_string(p_ctx)
        prot.spyne_tpt.pack(p_ctx)

        out_string = b''.join(p_ctx.out_string)
        p_ctx.transport.resp_length = len(out_string)

        prot.enqueue_outresp_data(id(p_ctx), out_string)

    except Exception as e:
        logger.exception(e)
        logger.error("%r", p_ctx)
        prot.handle_error(p_ctx, others, InternalError(e))

    finally:
        p_ctx.close()

    process_contexts(prot.spyne_tpt, others, p_ctx)
Esempio n. 39
0
def _cb_deferred(ret, prot, p_ctx, others, nowrap=False):
    if len(p_ctx.descriptor.out_message._type_info) > 1 or nowrap:
        p_ctx.out_object = ret
    else:
        p_ctx.out_object = [ret]

    try:
        prot.spyne_tpt.get_out_string(p_ctx)
        prot.spyne_tpt.pack(p_ctx)

        out_string = ''.join(p_ctx.out_string)
        prot.transport_write(out_string)
        p_ctx.transport.resp_length = len(out_string)

    except Exception as e:
        logger.exception(e)
        prot.handle_error(p_ctx, others, InternalError(e))

    finally:
        p_ctx.close()

    process_contexts(prot.spyne_tpt, others, p_ctx)
Esempio n. 40
0
def _cb_deferred(ret, prot, p_ctx, others, nowrap=False):
    if len(p_ctx.descriptor.out_message._type_info) > 1 or nowrap:
        p_ctx.out_object = ret
    else:
        p_ctx.out_object = [ret]

    try:
        prot.spyne_tpt.get_out_string(p_ctx)
        prot.spyne_tpt.pack(p_ctx)

        out_string = b''.join(p_ctx.out_string)
        p_ctx.transport.resp_length = len(out_string)

        prot.enqueue_outresp_data(id(p_ctx), out_string)

    except Exception as e:
        logger.exception(e)
        prot.handle_error(p_ctx, others, InternalError(e))

    finally:
        p_ctx.close()

    process_contexts(prot.spyne_tpt, others, p_ctx)
Esempio n. 41
0
 def _cb_push_finish():
     process_contexts(self, (), p_ctx)
Esempio n. 42
0
 def _cb_push_finish():
     process_contexts(self, others, p_ctx)
Esempio n. 43
0
File: _base.py Progetto: 1-bit/spyne
 def _cb_push_finish():
     p_ctx.out_stream.finish()
     process_contexts(self, others, p_ctx)
Esempio n. 44
0
def _cb_deferred(ret, request, p_ctx, others, resource, cb=True):
    resp_code = p_ctx.transport.resp_code
    # If user code set its own response code, don't touch it.
    if resp_code is None:
        resp_code = HTTP_200
    request.setResponseCode(int(resp_code[:3]))

    _set_response_headers(request, p_ctx.transport.resp_headers)

    om = p_ctx.descriptor.out_message
    single_class = None
    if cb:
        if p_ctx.descriptor.body_style in (BODY_STYLE_BARE, BODY_STYLE_EMPTY):
            p_ctx.out_object = [ret]

        elif (not issubclass(om, ComplexModelBase)) or len(om._type_info) <= 1:
            p_ctx.out_object = [ret]
            if len(om._type_info) == 1:
                single_class, = om._type_info.values()
        else:
            p_ctx.out_object = ret
    else:
        p_ctx.out_object = ret

    retval = NOT_DONE_YET

    p_ctx.out_stream = request
    if isinstance(ret, PushBase):
        retval = _init_push(ret, request, p_ctx, others, resource)

    elif ((isclass(om) and issubclass(om, File)) or
          (isclass(single_class) and issubclass(single_class, File))) and \
         isinstance(p_ctx.out_protocol, HttpRpc) and \
                                      getattr(ret, 'abspath', None) is not None:

        file = static.File(ret.abspath,
                        defaultType=str(ret.type) or 'application/octet-stream')
        retval = _render_file(file, request)
        if retval != NOT_DONE_YET and cb:
            request.write(retval)
            request.finish()
            p_ctx.close()
        else:
            def _close_only_context(ret):
                p_ctx.close()

            request.notifyFinish().addCallback(_close_only_context)
            request.notifyFinish().addErrback(_eb_request_finished, request, p_ctx)

    else:
        resource.http_transport.get_out_string(p_ctx)

        producer = Producer(p_ctx.out_string, request)
        producer.deferred.addCallback(_cb_request_finished, request, p_ctx)
        producer.deferred.addErrback(_eb_request_finished, request, p_ctx)

        request.registerProducer(producer, False)

    process_contexts(resource.http_transport, others, p_ctx)

    return retval
Esempio n. 45
0
 def _cb_push_finish():
     p_ctx.out_stream.finish()
     process_contexts(resource.http_transport, others, p_ctx)
Esempio n. 46
0
 def _cb_push_finish():
     process_contexts(self, others, p_ctx)
Esempio n. 47
0
        except TypeError:
            retval_iter = iter(p_ctx.out_string)
            try:
                first_chunk = retval_iter.next()
            except StopIteration:
                first_chunk = ''

            start_response(p_ctx.transport.resp_code,
                                _gen_http_headers(p_ctx.transport.resp_headers))

            retval = itertools.chain([first_chunk], retval_iter,
                                                        self.__finalize(p_ctx))

        try:
            process_contexts(self, others, p_ctx, error=None)
        except Exception, e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        return retval

    def __finalize(self, p_ctx):
        p_ctx.close()
        self.event_manager.fire_event('wsgi_close', p_ctx)

        return ()

    def __reconstruct_wsgi_request(self, http_env):
        """Reconstruct http payload using information in the http header."""
Esempio n. 48
0
 def _cb_push_finish():
     p_ctx.out_stream.finish()
     process_contexts(self, others, p_ctx)
Esempio n. 49
0
def _cb_deferred(ret, request, p_ctx, others, resource, cb=True):
    ### set response headers
    resp_code = p_ctx.transport.resp_code

    # If user code set its own response code, don't touch it.
    if resp_code is None:
        resp_code = HTTP_200
    request.setResponseCode(int(resp_code[:3]))

    _set_response_headers(request, p_ctx.transport.resp_headers)

    ### normalize response data
    om = p_ctx.descriptor.out_message
    single_class = None
    if cb:
        if p_ctx.descriptor.is_out_bare():
            p_ctx.out_object = [ret]

        elif (not issubclass(om, ComplexModelBase)) or len(om._type_info) <= 1:
            p_ctx.out_object = [ret]
            if len(om._type_info) == 1:
                single_class, = om._type_info.values()
        else:
            p_ctx.out_object = ret
    else:
        p_ctx.out_object = ret

    ### start response
    retval = NOT_DONE_YET

    if isinstance(ret, PushBase):
        resource.http_transport.init_root_push(ret, p_ctx, others)

    elif ((isclass(om) and issubclass(om, File)) or
          (isclass(single_class) and issubclass(single_class, File))) and \
         isinstance(p_ctx.out_protocol, HttpRpc) and \
                                      getattr(ret, 'abspath', None) is not None:

        file = static.File(ret.abspath,
                           defaultType=str(ret.type)
                           or 'application/octet-stream')
        retval = _render_file(file, request)
        if retval != NOT_DONE_YET and cb:
            request.write(retval)
            request.finish()
            p_ctx.close()
        else:

            def _close_only_context(ret):
                p_ctx.close()

            request.notifyFinish() \
                .addCallback(_close_only_context) \
                .addErrback(_eb_request_finished, request, p_ctx) \
                .addErrback(log_and_let_go, logger)

    else:
        ret = resource.http_transport.get_out_string(p_ctx)

        if not isinstance(ret, Deferred):
            producer = Producer(p_ctx.out_string, request)
            producer.deferred \
                .addCallback(_cb_request_finished, request, p_ctx) \
                .addErrback(_eb_request_finished, request, p_ctx) \
                .addErrback(log_and_let_go, logger)

            try:
                request.registerProducer(producer, False)
            except Exception as e:
                logger_server.exception(e)
                try:
                    _eb_deferred(Failure(), request, p_ctx, others, resource)
                except Exception as e:
                    logger_server.exception(e)
                    raise

        else:

            def _cb(ret):
                if isinstance(ret, Deferred):
                    return ret \
                        .addCallback(_cb) \
                        .addErrback(_eb_request_finished, request, p_ctx) \
                        .addErrback(log_and_let_go, logger)
                else:
                    return _cb_request_finished(ret, request, p_ctx)

            ret \
                .addCallback(_cb) \
                .addErrback(_eb_request_finished, request, p_ctx) \
                .addErrback(log_and_let_go, logger)

    process_contexts(resource.http_transport, others, p_ctx)

    return retval
Esempio n. 50
0
        except TypeError:
            retval_iter = iter(p_ctx.out_string)
            try:
                first_chunk = retval_iter.next()
            except StopIteration:
                first_chunk = ''

            start_response(p_ctx.transport.resp_code,
                                _gen_http_headers(p_ctx.transport.resp_headers))

            retval = itertools.chain([first_chunk], retval_iter,
                                                        self.__finalize(p_ctx))

        try:
            process_contexts(self, others, p_ctx, error=None)
        except Exception, e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        return retval

    def __finalize(self, p_ctx):
        p_ctx.close()
        self.event_manager.fire_event('wsgi_close', p_ctx)

        return ()

    def __reconstruct_wsgi_request(self, http_env):
        """Reconstruct http payload using information in the http header."""
Esempio n. 51
0
File: wsgi.py Progetto: nareni/spyne
    def handle_rpc(self, req_env, start_response):
        initial_ctx = WsgiMethodContext(self, req_env,
                                        self.app.out_protocol.mime_type)

        self.event_manager.fire_event('wsgi_call', initial_ctx)
        initial_ctx.in_string, in_string_charset = \
                                        self.__reconstruct_wsgi_request(req_env)

        contexts = self.generate_contexts(initial_ctx, in_string_charset)
        p_ctx, others = contexts[0], contexts[1:]

        # TODO: rate limiting
        p_ctx.active = True

        if p_ctx.in_error:
            return self.handle_error(p_ctx, others, p_ctx.in_error,
                                     start_response)

        self.get_in_object(p_ctx)
        if p_ctx.in_error:
            logger.error(p_ctx.in_error)
            return self.handle_error(p_ctx, others, p_ctx.in_error,
                                     start_response)

        self.get_out_object(p_ctx)
        if p_ctx.out_error:
            return self.handle_error(p_ctx, others, p_ctx.out_error,
                                     start_response)

        assert p_ctx.out_object is not None
        g = next(iter(p_ctx.out_object))
        is_generator = len(p_ctx.out_object) == 1 and isgenerator(g)

        # if the out_object is a generator function, this hack makes the user
        # code run until first yield, which lets it set response headers and
        # whatnot before calling start_response. It's important to run this
        # here before serialization as the user function can also set output
        # protocol. Is there a better way?
        if is_generator:
            first_obj = next(g)
            p_ctx.out_object = (chain((first_obj, ), g), )

        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = HTTP_200

        try:
            self.get_out_string(p_ctx)

        except Exception as e:
            logger.exception(e)
            p_ctx.out_error = Fault('Server',
                                    get_fault_string_from_exception(e))
            return self.handle_error(p_ctx, others, p_ctx.out_error,
                                     start_response)


        if isinstance(p_ctx.out_protocol, HttpRpc) and \
                                               p_ctx.out_header_doc is not None:
            p_ctx.transport.resp_headers.update(p_ctx.out_header_doc)

        if p_ctx.descriptor and p_ctx.descriptor.mtom:
            # when there is more than one return type, the result is
            # encapsulated inside a list. when there's just one, the result
            # is returned in a non-encapsulated form. the apply_mtom always
            # expects the objects to be inside an iterable, hence the
            # following test.
            out_type_info = p_ctx.descriptor.out_message._type_info
            if len(out_type_info) == 1:
                p_ctx.out_object = [p_ctx.out_object]

            p_ctx.transport.resp_headers, p_ctx.out_string = apply_mtom(
                p_ctx.transport.resp_headers,
                p_ctx.out_string,
                p_ctx.descriptor.out_message._type_info.values(),
                p_ctx.out_object,
            )

        self.event_manager.fire_event('wsgi_return', p_ctx)

        if self.chunked:
            # the user has not set a content-length, so we delete it as the
            # input is just an iterable.
            if 'Content-Length' in p_ctx.transport.resp_headers:
                del p_ctx.transport.resp_headers['Content-Length']
        else:
            p_ctx.out_string = [''.join(p_ctx.out_string)]

        try:
            len(p_ctx.out_string)

            p_ctx.transport.resp_headers['Content-Length'] = \
                                    str(sum([len(a) for a in p_ctx.out_string]))
        except TypeError:
            pass

        start_response(p_ctx.transport.resp_code,
                       _gen_http_headers(p_ctx.transport.resp_headers))

        retval = chain(p_ctx.out_string, self.__finalize(p_ctx))

        try:
            process_contexts(self, others, p_ctx, error=None)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        return retval
Esempio n. 52
0
    def handle_rpc(self, req_env, start_response):
        initial_ctx = WsgiMethodContext(self, req_env,
                                                self.app.out_protocol.mime_type)

        # implementation hook
        self.event_manager.fire_event('wsgi_call', initial_ctx)
        initial_ctx.in_string, in_string_charset = \
                                        self.__reconstruct_wsgi_request(req_env)

        contexts = self.generate_contexts(initial_ctx, in_string_charset)
        p_ctx, others = contexts[0], contexts[1:]

        if p_ctx.in_error:
            return self.handle_error(p_ctx, others, p_ctx.in_error, start_response)

        self.get_in_object(p_ctx)
        if p_ctx.in_error:
            logger.error(p_ctx.in_error)
            return self.handle_error(p_ctx, others, p_ctx.in_error, start_response)

        self.get_out_object(p_ctx)
        if p_ctx.out_error:
            return self.handle_error(p_ctx, others, p_ctx.out_error, start_response)

        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = HTTP_200

        self.get_out_string(p_ctx)

        if p_ctx.descriptor and p_ctx.descriptor.mtom:
            # when there is more than one return type, the result is
            # encapsulated inside a list. when there's just one, the result
            # is returned in a non-encapsulated form. the apply_mtom always
            # expects the objects to be inside an iterable, hence the
            # following test.
            out_type_info = p_ctx.descriptor.out_message._type_info
            if len(out_type_info) == 1:
                out_object = [out_object]

            p_ctx.transport.resp_headers, p_ctx.out_string = apply_mtom(
                    p_ctx.transport.resp_headers, p_ctx.out_string,
                    p_ctx.descriptor.out_message._type_info.values(),
                    out_object
                )

        # implementation hook
        self.event_manager.fire_event('wsgi_return', p_ctx)

        # the client has not set a content-length, so we delete it as the input
        # is just an iterable.
        if self.chunked:
            if 'Content-Length' in p_ctx.transport.resp_headers:
                del p_ctx.transport.resp_headers['Content-Length']

        else:
            p_ctx.out_string = [''.join(p_ctx.out_string)]

        # if the out_string is a generator function, this hack lets the user
        # code run until first yield, which lets it set response headers and
        # whatnot beforce calling start_response. yes it causes an additional
        # copy of the first fragment of the response to be made, but if you know
        # a better way of having generator functions execute until first yield,
        # just let us know.
        try:
            len(p_ctx.out_string) # iterator?
            # nope

            p_ctx.transport.resp_headers['Content-Length'] = \
                                 str(sum([len(a) for a in p_ctx.out_string]))

            start_response(p_ctx.transport.resp_code,
                                            p_ctx.transport.resp_headers.items())

            retval = p_ctx.out_string

        except TypeError:
            retval_iter = iter(p_ctx.out_string)
            retval = retval_iter.next()

            start_response(p_ctx.transport.resp_code,
                                            p_ctx.transport.resp_headers.items())

            retval = itertools.chain([retval], retval_iter)

        try:
            process_contexts(self, others, p_ctx, error=None)
        except Exception, e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)
Esempio n. 53
0
 def _cb_push_finish():
     process_contexts(self, (), p_ctx)
Esempio n. 54
0
File: wsgi.py Progetto: plq/spyne
    def handle_rpc(self, req_env, start_response):
        initial_ctx = WsgiMethodContext(self, req_env,
                                                self.app.out_protocol.mime_type)

        self.event_manager.fire_event('wsgi_call', initial_ctx)
        initial_ctx.in_string, in_string_charset = \
                                        self.__reconstruct_wsgi_request(req_env)

        contexts = self.generate_contexts(initial_ctx, in_string_charset)
        p_ctx, others = contexts[0], contexts[1:]

        # TODO: rate limiting
        p_ctx.active = True

        if p_ctx.in_error:
            return self.handle_error(p_ctx, others, p_ctx.in_error,
                                                                 start_response)

        self.get_in_object(p_ctx)
        if p_ctx.in_error:
            logger.error(p_ctx.in_error)
            return self.handle_error(p_ctx, others, p_ctx.in_error,
                                                                 start_response)

        self.get_out_object(p_ctx)
        if p_ctx.out_error:
            return self.handle_error(p_ctx, others, p_ctx.out_error,
                                                                 start_response)

        assert p_ctx.out_object is not None
        g = next(iter(p_ctx.out_object))
        is_generator = len(p_ctx.out_object) == 1 and isgenerator(g)

        # if the out_object is a generator function, this hack makes the user
        # code run until first yield, which lets it set response headers and
        # whatnot before calling start_response. It's important to run this
        # here before serialization as the user function can also set output
        # protocol. Is there a better way?
        if is_generator:
            first_obj = next(g)
            p_ctx.out_object = ( chain((first_obj,), g), )

        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = HTTP_200

        try:
            self.get_out_string(p_ctx)

        except Exception as e:
            logger.exception(e)
            p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e))
            return self.handle_error(p_ctx, others, p_ctx.out_error,
                                                                 start_response)


        if isinstance(p_ctx.out_protocol, HttpRpc) and \
                                               p_ctx.out_header_doc is not None:
            p_ctx.transport.resp_headers.update(p_ctx.out_header_doc)

        if p_ctx.descriptor and p_ctx.descriptor.mtom:
            # when there is more than one return type, the result is
            # encapsulated inside a list. when there's just one, the result
            # is returned in a non-encapsulated form. the apply_mtom always
            # expects the objects to be inside an iterable, hence the
            # following test.
            out_type_info = p_ctx.descriptor.out_message._type_info
            if len(out_type_info) == 1:
                p_ctx.out_object = [p_ctx.out_object]

            p_ctx.transport.resp_headers, p_ctx.out_string = apply_mtom(
                    p_ctx.transport.resp_headers, p_ctx.out_string,
                    p_ctx.descriptor.out_message._type_info.values(),
                    p_ctx.out_object,
                )

        self.event_manager.fire_event('wsgi_return', p_ctx)

        if self.chunked:
            # the user has not set a content-length, so we delete it as the
            # input is just an iterable.
            if 'Content-Length' in p_ctx.transport.resp_headers:
                del p_ctx.transport.resp_headers['Content-Length']
        else:
            p_ctx.out_string = [''.join(p_ctx.out_string)]

        try:
            len(p_ctx.out_string)

            p_ctx.transport.resp_headers['Content-Length'] = \
                                    str(sum([len(a) for a in p_ctx.out_string]))
        except TypeError:
            pass

        start_response(p_ctx.transport.resp_code,
                                _gen_http_headers(p_ctx.transport.resp_headers))

        retval = chain(p_ctx.out_string, self.__finalize(p_ctx))

        try:
            process_contexts(self, others, p_ctx, error=None)
        except Exception as e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)

        return retval
Esempio n. 55
0
    def handle_rpc(self, req_env, start_response):
        initial_ctx = WsgiMethodContext(self, req_env,
                                        self.app.out_protocol.mime_type)

        # implementation hook
        self.event_manager.fire_event('wsgi_call', initial_ctx)
        initial_ctx.in_string, in_string_charset = \
                                        self.__reconstruct_wsgi_request(req_env)

        contexts = self.generate_contexts(initial_ctx, in_string_charset)
        p_ctx, others = contexts[0], contexts[1:]

        if p_ctx.in_error:
            return self.handle_error(p_ctx, others, p_ctx.in_error,
                                     start_response)

        self.get_in_object(p_ctx)
        if p_ctx.in_error:
            logger.error(p_ctx.in_error)
            return self.handle_error(p_ctx, others, p_ctx.in_error,
                                     start_response)

        self.get_out_object(p_ctx)
        if p_ctx.out_error:
            return self.handle_error(p_ctx, others, p_ctx.out_error,
                                     start_response)

        if p_ctx.transport.resp_code is None:
            p_ctx.transport.resp_code = HTTP_200

        self.get_out_string(p_ctx)

        if isinstance(self.app.out_protocol, HttpRpc) and \
                                               p_ctx.out_header_doc is not None:
            p_ctx.transport.resp_headers.update(p_ctx.out_header_doc)

        if p_ctx.descriptor and p_ctx.descriptor.mtom:
            # when there is more than one return type, the result is
            # encapsulated inside a list. when there's just one, the result
            # is returned in a non-encapsulated form. the apply_mtom always
            # expects the objects to be inside an iterable, hence the
            # following test.
            out_type_info = p_ctx.descriptor.out_message._type_info
            if len(out_type_info) == 1:
                out_object = [out_object]

            p_ctx.transport.resp_headers, p_ctx.out_string = apply_mtom(
                p_ctx.transport.resp_headers, p_ctx.out_string,
                p_ctx.descriptor.out_message._type_info.values(), out_object)

        # implementation hook
        self.event_manager.fire_event('wsgi_return', p_ctx)

        if self.chunked:
            # the client has not set a content-length, so we delete it as the
            # input is just an iterable.
            if 'Content-Length' in p_ctx.transport.resp_headers:
                del p_ctx.transport.resp_headers['Content-Length']
        else:
            p_ctx.out_string = [''.join(p_ctx.out_string)]

        # if the out_string is a generator function, this hack lets the user
        # code run until first yield, which lets it set response headers and
        # whatnot before calling start_response. Is there a better way?
        try:
            len(p_ctx.out_string)  # generator?

            # nope
            p_ctx.transport.resp_headers['Content-Length'] = \
                                    str(sum([len(a) for a in p_ctx.out_string]))

            start_response(p_ctx.transport.resp_code,
                           _gen_http_headers(p_ctx.transport.resp_headers))

            retval = itertools.chain(p_ctx.out_string, self.__finalize(p_ctx))

        except TypeError:
            retval_iter = iter(p_ctx.out_string)
            try:
                first_chunk = retval_iter.next()
            except StopIteration:
                first_chunk = ''

            start_response(p_ctx.transport.resp_code,
                           _gen_http_headers(p_ctx.transport.resp_headers))

            retval = itertools.chain([first_chunk], retval_iter,
                                     self.__finalize(p_ctx))

        try:
            process_contexts(self, others, p_ctx, error=None)
        except Exception, e:
            # Report but ignore any exceptions from auxiliary methods.
            logger.exception(e)