Beispiel #1
0
    def pyamfEncode(self, obj, amf3=False, use_proxies=False):
        if amf3 is True:
            context = pyamf.get_context(pyamf.AMF3)
        else:
            context = pyamf.get_context(pyamf.AMF0)

        stream = BufferedByteStream()

        if amf3 is True:
            pyamf_encoder = pyamf.get_encoder(pyamf.AMF3, stream=stream, context=context)
        else:
            pyamf_encoder = pyamf.get_encoder(pyamf.AMF0, stream=stream, context=context)

        pyamf_encoder.writeElement(obj)
        return pyamf_encoder.stream.getvalue()
Beispiel #2
0
def decode(stream, context=None, strict=False):
    """
    Decodes the incoming stream.

    @type   stream: L{BufferedByteStream<pyamf.util.BufferedByteStream>}
    @param  stream: AMF data.
    @type   context: L{amf0.Context<pyamf.amf0.Context>} or
    L{amf3.Context<pyamf.amf3.Context>}
    @param  context: Context.
    @type strict: C{bool}
    @param strict: Enforce strict encoding. Default is C{False}.

    @raise DecodeError: Malformed stream.
    @raise RuntimeError: Decoder is unable to fully consume the
    stream buffer.

    @return: Message envelope.
    @rtype: L{Envelope}
    """
    if not isinstance(stream, util.BufferedByteStream):
        stream = util.BufferedByteStream(stream)

    msg = Envelope()
    msg.amfVersion = stream.read_uchar()

    # see http://osflash.org/documentation/amf/envelopes/remoting#preamble
    # why we are doing this...
    if msg.amfVersion > 0x09:
        raise pyamf.DecodeError("Malformed stream (amfVersion=%d)" %
            msg.amfVersion)

    if context is None:
        context = pyamf.get_context(pyamf.AMF0)
    else:
        context = copy.copy(context)

    decoder = pyamf._get_decoder_class(pyamf.AMF0)(stream, context=context, strict=strict)
    msg.clientType = stream.read_uchar()

    header_count = stream.read_ushort()

    for i in xrange(header_count):
        name, required, data = _read_header(stream, decoder, strict)
        msg.headers[name] = data

        if required:
            msg.headers.set_required(name)

    body_count = stream.read_short()

    for i in range(body_count):
        context.reset()

        target, payload = _read_body(stream, decoder, strict)
        msg[target] = payload

    if strict and stream.remaining() > 0:
        raise RuntimeError("Unable to fully consume the buffer")

    return msg
    def getNewContext():
        if old_context:
            import copy

            return copy.copy(old_context)
        else:
            return pyamf.get_context(pyamf.AMF0)
Beispiel #4
0
def decode(stream, context=None, strict=False):
    """
    Decodes the incoming stream.

    @type   stream: L{BufferedByteStream<pyamf.util.BufferedByteStream>}
    @param  stream: AMF data.
    @type   context: L{amf0.Context<pyamf.amf0.Context>} or
    L{amf3.Context<pyamf.amf3.Context>}
    @param  context: Context.
    @type strict: C{bool}
    @param strict: Enforce strict encoding. Default is C{False}.

    @raise DecodeError: Malformed stream.
    @raise RuntimeError: Decoder is unable to fully consume the
    stream buffer.

    @return: Message envelope.
    @rtype: L{Envelope}
    """
    if not isinstance(stream, util.BufferedByteStream):
        stream = util.BufferedByteStream(stream)

    msg = Envelope()
    msg.amfVersion = stream.read_uchar()

    # see http://osflash.org/documentation/amf/envelopes/remoting#preamble
    # why we are doing this...
    if msg.amfVersion > 0x09:
        raise pyamf.DecodeError("Malformed stream (amfVersion=%d)" %
            msg.amfVersion)

    if context is None:
        context = pyamf.get_context(pyamf.AMF0)
    else:
        context = copy.copy(context)

    decoder = pyamf._get_decoder_class(pyamf.AMF0)(stream, context=context, strict=strict)
    msg.clientType = stream.read_uchar()

    header_count = stream.read_ushort()

    for i in xrange(header_count):
        name, required, data = _read_header(stream, decoder, strict)
        msg.headers[name] = data

        if required:
            msg.headers.set_required(name)

    body_count = stream.read_short()

    for i in range(body_count):
        context.reset()

        target, payload = _read_body(stream, decoder, strict)
        msg[target] = payload

    if strict and stream.remaining() > 0:
        raise RuntimeError("Unable to fully consume the buffer")

    return msg
Beispiel #5
0
    def getNewContext():
        if old_context:
            import copy

            return copy.copy(old_context)
        else:
            return pyamf.get_context(pyamf.AMF0)
Beispiel #6
0
    def getNewContext():
        if context:
            new_context = copy.copy(context)
            new_context.reset()

            return new_context
        else:
            return pyamf.get_context(pyamf.AMF0)
Beispiel #7
0
    def getNewContext():
        if context:
            new_context = copy.copy(context)
            new_context.reset()

            return new_context
        else:
            return pyamf.get_context(pyamf.AMF0)
Beispiel #8
0
    def pyamfEncode(self, obj, amf3=False, use_proxies=False):
        if amf3 is True:
            context = pyamf.get_context(pyamf.AMF3)
        else:
            context = pyamf.get_context(pyamf.AMF0)

        stream = BufferedByteStream()

        if amf3 is True:
            pyamf_encoder = pyamf.get_encoder(pyamf.AMF3,
                                              stream=stream,
                                              context=context)
        else:
            pyamf_encoder = pyamf.get_encoder(pyamf.AMF0,
                                              stream=stream,
                                              context=context)

        pyamf_encoder.writeElement(obj)
        return pyamf_encoder.stream.getvalue()
    def __call__(self, http_request):
        """
        Processes and dispatches the request.

        @param http_request: The C{HTTPRequest} object.
        @type http_request: C{HTTPRequest}
        @return: The response to the request.
        @rtype: C{HTTPResponse}
        """
        if http_request.method != 'POST':
            return http.HttpResponseNotAllowed(['POST'])

        context = pyamf.get_context(pyamf.AMF0)
        stream = None
        http_response = http.HttpResponse()

        # Decode the request
        try:
            request = remoting.decode(http_request.raw_post_data, context)
        except pyamf.DecodeError:
            self.logger.exception(gateway.format_exception())
            http_response.status_code = 400

            return http_response

        self.logger.debug("AMF Request: %r" % request)

        # Process the request
        try:
            response = self.getResponse(http_request, request)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.logger.exception(gateway.format_exception())

            return http.HttpResponseServerError()

        self.logger.debug("AMF Response: %r" % response)

        # Encode the response
        try:
            stream = remoting.encode(response, context)
        except pyamf.EncodeError:
            self.logger.exception(gateway.format_exception())

            return http.HttpResponseServerError('Unable to encode the response')

        buf = stream.getvalue()
        http_response['Content-Type'] = remoting.CONTENT_TYPE
        http_response['Content-Length'] = str(len(buf))
        http_response['Server'] = gateway.SERVER_NAME
        http_response.write(buf)

        return http_response
Beispiel #10
0
    def __call__(self, http_request):
        """
        Processes and dispatches the request.

        @param http_request: The C{HTTPRequest} object.
        @type http_request: C{HTTPRequest}
        @return: The response to the request.
        @rtype: C{HTTPResponse}
        """
        if http_request.method != 'POST':
            return http.HttpResponseNotAllowed(['POST'])

        context = pyamf.get_context(pyamf.AMF0)
        stream = None
        http_response = http.HttpResponse()

        # Decode the request
        try:
            request = remoting.decode(http_request.raw_post_data, context)
        except pyamf.DecodeError:
            self.logger.debug(gateway.format_exception())
            http_response.status_code = 400

            return http_response

        self.logger.debug("AMF Request: %r" % request)

        # Process the request
        try:
            response = self.getResponse(http_request, request)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.logger.debug(gateway.format_exception())

            return http.HttpResponseServerError()

        self.logger.debug("AMF Response: %r" % response)

        # Encode the response
        try:
            stream = remoting.encode(response, context)
        except pyamf.EncodeError:
            self.logger.debug(gateway.format_exception())

            return http.HttpResponseServerError(
                'Unable to encode the response')

        buf = stream.getvalue()
        http_response['Content-Type'] = remoting.CONTENT_TYPE
        http_response['Content-Length'] = str(len(buf))
        http_response.write(buf)

        return http_response
Beispiel #11
0
    def decodePacket(self, raw_packet, *args, **kwargs):
        if amfast.log_raw:
            self.logRaw('rawDecodePacket', raw_packet)

        context = pyamf.get_context(pyamf.AMF0)
        pyamf_packet = pyamf.remoting.decode(raw_packet, context)
        packet = pc.packet_to_amfast(pyamf_packet)

        if amfast.log_debug:
            amfast.logger.debug("<decodedPyAmfPacket>%s</decodedPyAmfPacket>" % pyamf_packet)

        return packet
Beispiel #12
0
def encode(msg, context=None, strict=False, logger=None, timezone_offset=None):
    """
    Encodes AMF stream and returns file object.

    @type   msg: L{Envelope}
    @param  msg: The message to encode.
    @type strict: C{bool}
    @param strict: Determines whether encoding should be strict. Specifically
        header/body lengths will be written correctly, instead of the default 0.
        Default is C{False}. Introduced in 0.4.
    @param logger: Used to log interesting events whilst encoding a remoting
        message.
    @type logger: A L{logging.Logger} instance or C{None}.
    @param timezone_offset: The difference between the current timezone and
        UTC. Date/times should always be handled in UTC to avoid confusion but
        this is required for legacy systems.
    @type timezone_offset: L{datetime.timedelta}
    @rtype: C{StringIO}
    @return: File object.
    """
    stream = util.BufferedByteStream()

    if context is None:
        context = pyamf.get_context(pyamf.AMF0, exceptions=False)

    encoder = pyamf.get_encoder(pyamf.AMF0,
                                stream,
                                context=context,
                                timezone_offset=timezone_offset,
                                strict=strict)

    if msg.clientType == pyamf.ClientTypes.Flash9:
        encoder.use_amf3 = True

    stream.write_uchar(msg.amfVersion)
    stream.write_uchar(msg.clientType)
    stream.write_short(len(msg.headers))

    for name, header in msg.headers.iteritems():
        _write_header(name, header, int(msg.headers.is_required(name)), stream,
                      encoder, strict)

    stream.write_short(len(msg))

    for name, message in msg.iteritems():
        encoder.context.clear()

        _write_body(name, message, stream, encoder, strict)

    stream.seek(0)

    return stream
Beispiel #13
0
    def encodePacket(self, packet):
        pyamf_packet = pc.packet_to_pyamf(packet)
        if amfast.log_debug:
            amfast.logger.debug("<encodedPyAmfPacket>%s</encodedPyAmfPacket>" % pyamf_packet)

        context = pyamf.get_context(pyamf.AMF0)
        stream = pyamf.remoting.encode(pyamf_packet, context)
        raw_packet = stream.getvalue()

        if amfast.log_raw:
            self.logRaw('rawEncodePacket', raw_packet)

        return raw_packet
Beispiel #14
0
    def decodePacket(self, raw_packet, *args, **kwargs):
        if amfast.log_raw:
            self.logRaw('rawDecodePacket', raw_packet)

        context = pyamf.get_context(pyamf.AMF0)
        pyamf_packet = pyamf.remoting.decode(raw_packet, context)
        packet = pc.packet_to_amfast(pyamf_packet)

        if amfast.log_debug:
            amfast.logger.debug("<decodedPyAmfPacket>%s</decodedPyAmfPacket>" %
                                pyamf_packet)

        return packet
Beispiel #15
0
    def decode(self, raw_obj, amf3=False):
        if amf3 is True:
            amf_type = pyamf.AMF3
        else:
            amf_type = pyamf.AMF0

        context = pyamf.get_context(amf_type)
        decoder = pyamf.get_decoder(amf_type, raw_obj, context=context)
        obj = decoder.readElement()

        if amfast.log_raw:
            self.logRaw('rawDecodeObject', raw_obj)

        return obj
Beispiel #16
0
    def decode(self, raw_obj, amf3=False):
        if amf3 is True:
            amf_type = pyamf.AMF3
        else:
            amf_type = pyamf.AMF0

        context = pyamf.get_context(amf_type)
        decoder = pyamf.get_decoder(amf_type, raw_obj, context=context)
        obj = decoder.readElement()

        if amfast.log_raw:
            self.logRaw('rawDecodeObject', raw_obj)

        return obj
Beispiel #17
0
def encode(msg, context=None, strict=False, logger=None, timezone_offset=None):
    """
    Encodes AMF stream and returns file object.

    @type   msg: L{Envelope}
    @param  msg: The message to encode.
    @type strict: C{bool}
    @param strict: Determines whether encoding should be strict. Specifically
        header/body lengths will be written correctly, instead of the default 0.
        Default is C{False}. Introduced in 0.4.
    @param logger: Used to log interesting events whilst encoding a remoting
        message.
    @type logger: A L{logging.Logger} instance or C{None}.
    @param timezone_offset: The difference between the current timezone and
        UTC. Date/times should always be handled in UTC to avoid confusion but
        this is required for legacy systems.
    @type timezone_offset: L{datetime.timedelta}
    @rtype: C{StringIO}
    @return: File object.
    """
    stream = util.BufferedByteStream()

    if context is None:
        context = pyamf.get_context(pyamf.AMF0, exceptions=False)

    encoder = pyamf.get_encoder(pyamf.AMF0, stream, context=context,
        timezone_offset=timezone_offset, strict=strict)

    if msg.clientType == pyamf.ClientTypes.Flash9:
        encoder.use_amf3 = True

    stream.write_uchar(msg.amfVersion)
    stream.write_uchar(msg.clientType)
    stream.write_short(len(msg.headers))

    for name, header in msg.headers.iteritems():
        _write_header(
            name, header, int(msg.headers.is_required(name)),
            stream, encoder, strict)

    stream.write_short(len(msg))

    for name, message in msg.iteritems():
        encoder.context.clear()

        _write_body(name, message, stream, encoder, strict)

    stream.seek(0)

    return stream
Beispiel #18
0
    def encodePacket(self, packet):
        pyamf_packet = pc.packet_to_pyamf(packet)
        if amfast.log_debug:
            amfast.logger.debug("<encodedPyAmfPacket>%s</encodedPyAmfPacket>" %
                                pyamf_packet)

        context = pyamf.get_context(pyamf.AMF0)
        stream = pyamf.remoting.encode(pyamf_packet, context)
        raw_packet = stream.getvalue()

        if amfast.log_raw:
            self.logRaw('rawEncodePacket', raw_packet)

        return raw_packet
Beispiel #19
0
def encode(msg, context=None, strict=False, logger=None, timezone_offset=None):
    """
    Encodes AMF stream and returns file object.

    :type   msg: :class:`Envelope`
    :param  msg: The message to encode.
    :type strict: `bool`
    :param strict: Determines whether encoding should be strict. Specifically
        header/body lengths will be written correctly, instead of the default 0.
        Default is `False`. Introduced in 0.4.
    :param logger: Used to log interesting events whilst encoding a remoting
        message.
    :type logger: A `logging.Logger` instance or `None`.
    :param timezone_offset: The difference between the current timezone and
        UTC. Date/times should always be handled in UTC to avoid confusion but
        this is required for legacy systems.
    :type timezone_offset: `datetime.timedelta`
    :rtype: `StringIO`
    :return: File object.
    """
    stream = util.BufferedByteStream()

    if context is None:
        context = pyamf.get_context(pyamf.AMF0)

    encoder = pyamf.get_encoder(pyamf.AMF0, stream, context=context,
        timezone_offset=timezone_offset, strict=strict)

    if msg.amfVersion == pyamf.AMF3:
        encoder.use_amf3 = True

    stream.write_ushort(msg.amfVersion)
    stream.write_ushort(len(msg.headers))

    for name, header in msg.headers.iteritems():
        _write_header(
            name, header, int(msg.headers.is_required(name)),
            stream, encoder, strict)

    stream.write_short(len(msg))

    for name, message in msg.iteritems():
        encoder.context.clear()

        _write_body(name, message, stream, encoder, strict)

    stream.seek(0)

    return stream
Beispiel #20
0
    def encode(self, obj, amf3=False):
        if amf3 is True:
            amf_type = pyamf.AMF3
        else:
            amf_type = pyamf.AMF0

        stream = pyamf_util.BufferedByteStream()

        context = pyamf.get_context(amf_type)
        encoder = pyamf.get_encoder(amf_type, stream, context=context)
        encoder.writeElement(obj)

        raw_obj = stream.getvalue()

        if amfast.log_raw:
            self.logRaw('rawEncodeObject', raw_obj)

        return raw_obj
Beispiel #21
0
    def encode(self, obj, amf3=False):
        if amf3 is True:
            amf_type = pyamf.AMF3
        else:
            amf_type = pyamf.AMF0

        stream = pyamf_util.BufferedByteStream()

        context = pyamf.get_context(amf_type)
        encoder = pyamf.get_encoder(amf_type, stream, context=context)
        encoder.writeElement(obj)

        raw_obj = stream.getvalue()

        if amfast.log_raw:
            self.logRaw('rawEncodeObject', raw_obj)

        return raw_obj
Beispiel #22
0
    def readAMF3(self):
        """
        Read AMF3 elements from the data stream.

        @rtype: C{mixed}
        @return: The AMF3 element read from the stream
        """
        if not hasattr(self.context, 'amf3_context'):
            self.context.amf3_context = pyamf.get_context(pyamf.AMF3, exceptions=False)

        if not hasattr(self.context, 'amf3_decoder'):
            self.context.amf3_decoder = pyamf.get_decoder(
                pyamf.AMF3, self.stream, self.context.amf3_context)

        decoder = self.context.amf3_decoder
        element = decoder.readElement()
        self.context.addAMF3Object(element)

        return element
Beispiel #23
0
    def writeAMF3(self, data):
        """
        Writes an element to the datastream in L{AMF3<pyamf.amf3>} format.

        @type data: C{mixed}
        @param data: The data to be encoded to the AMF0 data stream.
        """
        if not hasattr(self.context, 'amf3_context'):
            self.context.amf3_context = pyamf.get_context(pyamf.AMF3, exceptions=False)

        if not hasattr(self.context, 'amf3_encoder'):
            self.context.amf3_encoder = pyamf.get_encoder(
                pyamf.AMF3, self.stream, self.context.amf3_context)

        self.context.addAMF3Object(data)
        encoder = self.context.amf3_encoder

        self.writeType(TYPE_AMF3)
        encoder.writeElement(data)
Beispiel #24
0
    def readAMF3(self):
        """
        Read AMF3 elements from the data stream.

        @rtype: C{mixed}
        @return: The AMF3 element read from the stream
        """
        if not hasattr(self.context, 'amf3_context'):
            self.context.amf3_context = pyamf.get_context(pyamf.AMF3,
                                                          exceptions=False)

        if not hasattr(self.context, 'amf3_decoder'):
            self.context.amf3_decoder = pyamf.get_decoder(
                pyamf.AMF3, self.stream, self.context.amf3_context)

        decoder = self.context.amf3_decoder
        element = decoder.readElement()
        self.context.addAMF3Object(element)

        return element
Beispiel #25
0
    def writeAMF3(self, data):
        """
        Writes an element to the datastream in L{AMF3<pyamf.amf3>} format.

        @type data: C{mixed}
        @param data: The data to be encoded to the AMF0 data stream.
        """
        if not hasattr(self.context, 'amf3_context'):
            self.context.amf3_context = pyamf.get_context(pyamf.AMF3,
                                                          exceptions=False)

        if not hasattr(self.context, 'amf3_encoder'):
            self.context.amf3_encoder = pyamf.get_encoder(
                pyamf.AMF3, self.stream, self.context.amf3_context)

        self.context.addAMF3Object(data)
        encoder = self.context.amf3_encoder

        self.writeType(TYPE_AMF3)
        encoder.writeElement(data)
Beispiel #26
0
    def render_POST(self, request):
        """
        Read remoting request from the client.

        @type request: The HTTP Request.
        @param request: C{twisted.web.http.Request}
        """
        def handleDecodeError(failure):
            """
            Return HTTP 400 Bad Request.
            """
            errMesg = "%s: %s" % (failure.type, failure.getErrorMessage())
            self.logger.error(errMesg)
            self.logger.info(failure.getTraceback())

            body = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                body += "\n\nTraceback:\n\n%s" % failure.getTraceback()

            self._finaliseRequest(request, 400, body)

        request.content.seek(0, 0)
        context = pyamf.get_context(pyamf.AMF0)

        d = threads.deferToThread(remoting.decode,
                                  request.content.read(),
                                  context,
                                  strict=self.strict)

        def cb(amf_request):
            self.logger.debug("AMF Request: %r" % amf_request)
            x = self.getResponse(request, amf_request)

            x.addCallback(self.sendResponse, request, context)

        # Process the request
        d.addCallback(cb).addErrback(handleDecodeError)

        return server.NOT_DONE_YET
Beispiel #27
0
    def render_POST(self, request):
        """
        Read remoting request from the client.

        @type request: The HTTP Request.
        @param request: C{twisted.web.http.Request}
        """
        def handleDecodeError(failure):
            """
            Return HTTP 400 Bad Request.
            """
            errMesg = "%s: %s" % (failure.type, failure.getErrorMessage())
            self.logger.error(errMesg)
            self.logger.info(failure.getTraceback())
    
            body = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                body += "\n\nTraceback:\n\n%s" % failure.getTraceback()

            self._finaliseRequest(request, 400, body)

        request.content.seek(0, 0)
        context = pyamf.get_context(pyamf.AMF0)

        d = threads.deferToThread(remoting.decode, request.content.read(),
            context, strict=self.strict)

        def cb(amf_request):
            self.logger.debug("AMF Request: %r" % amf_request)
            x = self.getResponse(request, amf_request)

            x.addCallback(self.sendResponse, request, context)

        # Process the request
        d.addCallback(cb).addErrback(handleDecodeError)

        return server.NOT_DONE_YET
Beispiel #28
0
    def __call__(self, environ, start_response):
        """
        @type environ:
        @param environ:
        @type start_response:
        @param start_response:

        @rtype: C{StringIO}
        @return: File-like object.
        """
        if environ['REQUEST_METHOD'] != 'POST':
            return self.badRequestMethod(environ, start_response)

        body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))
        stream = None

        context = pyamf.get_context(pyamf.AMF0)

        # Decode the request
        try:
            request = remoting.decode(body, context)
        except pyamf.DecodeError:
            self.logger.debug(gateway.format_exception())

            response = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response('400 Bad Request', [
                ('Content-Type', 'text/plain'),
                ('Content-Length', str(len(response))),
            ])

            return [response]

        # Process the request
        try:
            response = self.getResponse(request, environ)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.logger.debug(gateway.format_exception())

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be successfully processed."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response('500 Internal Server Error', [
                ('Content-Type', 'text/plain'),
                ('Content-Length', str(len(response))),
            ])

            return [response]

        # Encode the response
        try:
            stream = remoting.encode(response, context)
        except pyamf.EncodeError:
            self.logger.debug(gateway.format_exception())

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be encoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response('500 Internal Server Error', [
                ('Content-Type', 'text/plain'),
                ('Content-Length', str(len(response))),
            ])

            return [response]

        response = stream.getvalue()

        start_response('200 OK', [
            ('Content-Type', remoting.CONTENT_TYPE),
            ('Content-Length', str(len(response))),
        ])

        return [response]
Beispiel #29
0
    def __call__(self, http_request):
        """
        Processes and dispatches the request.

        @param http_request: The C{HTTPRequest} object.
        @type http_request: C{HTTPRequest}
        @return: The response to the request.
        @rtype: C{HTTPResponse}
        """
        if http_request.method != 'POST':
            return http.HttpResponseNotAllowed(['POST'])

        context = pyamf.get_context(pyamf.AMF0)
        stream = None

        # Decode the request
        try:
            request = remoting.decode(http_request.raw_post_data,
                                      context,
                                      strict=self.strict)
        except (pyamf.DecodeError, EOFError):
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseBadRequest(mimetype='text/plain',
                                               content=response)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nAn unexpected error occurred."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseServerError(mimetype='text/plain',
                                                content=response)

        self.logger.debug("AMF Request: %r" % request)

        # Process the request
        try:
            response = self.getResponse(http_request, request)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be successfully processed."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseServerError(mimetype='text/plain',
                                                content=response)

        self.logger.debug("AMF Response: %r" % response)

        # Encode the response
        try:
            stream = remoting.encode(response, context, strict=self.strict)
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be encoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseServerError(mimetype='text/plain',
                                                content=response)

        buf = stream.getvalue()

        http_response = http.HttpResponse(mimetype=remoting.CONTENT_TYPE)
        http_response['Server'] = gateway.SERVER_NAME
        http_response['Content-Length'] = str(len(buf))

        http_response.write(buf)

        return http_response
Beispiel #30
0
    def __call__(self, environ, start_response):
        """
        @rtype: C{StringIO}
        @return: File-like object.
        """
        if environ["REQUEST_METHOD"] != "POST":
            return self.badRequestMethod(environ, start_response)

        body = environ["wsgi.input"].read(int(environ["CONTENT_LENGTH"]))
        stream = None

        context = pyamf.get_context(pyamf.AMF0)

        # Decode the request
        try:
            request = remoting.decode(body, context, strict=self.strict)
        except (pyamf.DecodeError, EOFError):
            self.logger.exception(gateway.format_exception())

            response = "400 Bad Request\n\nThe request body was unable to " "be successfully decoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response(
                "400 Bad Request",
                [
                    ("Content-Type", "text/plain"),
                    ("Content-Length", str(len(response))),
                    ("Server", gateway.SERVER_NAME),
                ],
            )

            return [response]
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.logger.exception(gateway.format_exception())

            response = "500 Internal Server Error\n\nAn unexpected error occurred whilst decoding."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response(
                "500 Internal Server Error",
                [
                    ("Content-Type", "text/plain"),
                    ("Content-Length", str(len(response))),
                    ("Server", gateway.SERVER_NAME),
                ],
            )

            return [response]

        self.logger.debug("AMF Request: %r" % request)

        # Process the request
        try:
            response = self.getResponse(request, environ)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.logger.exception(gateway.format_exception())

            response = "500 Internal Server Error\n\nThe request was " "unable to be successfully processed."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response(
                "500 Internal Server Error",
                [
                    ("Content-Type", "text/plain"),
                    ("Content-Length", str(len(response))),
                    ("Server", gateway.SERVER_NAME),
                ],
            )

            return [response]

        self.logger.debug("AMF Response: %r" % response)

        # Encode the response
        try:
            stream = remoting.encode(response, context, strict=self.strict)
        except:
            self.logger.exception(gateway.format_exception())

            response = "500 Internal Server Error\n\nThe request was " "unable to be encoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response(
                "500 Internal Server Error",
                [
                    ("Content-Type", "text/plain"),
                    ("Content-Length", str(len(response))),
                    ("Server", gateway.SERVER_NAME),
                ],
            )

            return [response]

        response = stream.getvalue()

        start_response(
            "200 OK",
            [
                ("Content-Type", remoting.CONTENT_TYPE),
                ("Content-Length", str(len(response))),
                ("Server", gateway.SERVER_NAME),
            ],
        )

        return [response]
Beispiel #31
0
    def __call__(self, http_request):
        """
        Processes and dispatches the request.

        @param http_request: The C{HTTPRequest} object.
        @type http_request: C{HTTPRequest}
        @return: The response to the request.
        @rtype: C{HTTPResponse}
        """
        if http_request.method != 'POST':
            return http.HttpResponseNotAllowed(['POST'])

        context = pyamf.get_context(pyamf.AMF0)
        stream = None

        # Decode the request
        try:
            request = remoting.decode(http_request.raw_post_data, context, strict=self.strict)
        except (pyamf.DecodeError, EOFError):
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseBadRequest(mimetype='text/plain', content=response)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nAn unexpected error occurred."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseServerError(mimetype='text/plain', content=response)

        self.logger.debug("AMF Request: %r" % request)

        # Process the request
        try:
            response = self.getResponse(http_request, request)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be successfully processed."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseServerError(mimetype='text/plain', content=response)

        self.logger.debug("AMF Response: %r" % response)

        # Encode the response
        try:
            stream = remoting.encode(response, context, strict=self.strict)
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be encoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            return http.HttpResponseServerError(mimetype='text/plain', content=response)

        buf = stream.getvalue()

        http_response = http.HttpResponse(mimetype=remoting.CONTENT_TYPE)
        http_response['Server'] = gateway.SERVER_NAME
        http_response['Content-Length'] = str(len(buf))

        http_response.write(buf)

        return http_response
Beispiel #32
0
    def __call__(self, environ, start_response):
        """
        @rtype: C{StringIO}
        @return: File-like object.
        """
        if environ['REQUEST_METHOD'] != 'POST':
            return self.badRequestMethod(environ, start_response)

        body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))
        stream = None

        context = pyamf.get_context(pyamf.AMF0)

        # Decode the request
        try:
            request = remoting.decode(body, context)
        except pyamf.DecodeError:
            self.logger.debug(gateway.format_exception())

            response = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response('400 Bad Request', [
                ('Content-Type', 'text/plain'),
                ('Content-Length', str(len(response))),
            ])

            return [response]

        # Process the request
        try:
            response = self.getResponse(request, environ)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.logger.debug(gateway.format_exception())

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be successfully processed."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response('500 Internal Server Error', [
                ('Content-Type', 'text/plain'),
                ('Content-Length', str(len(response))),
            ])

            return [response]

        # Encode the response
        try:
            stream = remoting.encode(response, context)
        except pyamf.EncodeError:
            self.logger.debug(gateway.format_exception())

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be encoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % gateway.format_exception()

            start_response('500 Internal Server Error', [
                ('Content-Type', 'text/plain'),
                ('Content-Length', str(len(response))),
            ])

            return [response]

        response = stream.getvalue()

        start_response('200 OK', [
            ('Content-Type', remoting.CONTENT_TYPE),
            ('Content-Length', str(len(response))),
        ])

        return [response]
Beispiel #33
0
def decode(stream, context=None, strict=False, logger=None, timezone_offset=None):
    """
    Decodes the incoming stream as a remoting message.

    :param stream: AMF data.
    :type stream: :class:`BufferedByteStream<pyamf.util.BufferedByteStream>`
    :param context: Context.
    :type context: :class:`amf0.Context<pyamf.amf0.Context>` or
                   :class:`amf3.Context<pyamf.amf3.Context>`
    :param strict: Enforce strict decoding. Default is `False`.
    :type strict: `bool`
    :param logger: Used to log interesting events whilst decoding a remoting
        message.
    :type logger: A `logging.Logger` instance or `None`.
    :param timezone_offset: The difference between the current timezone and
        UTC. Date/times should always be handled in UTC to avoid confusion but
        this is required for legacy systems.
    :type timezone_offset: `datetime.timedelta`

    :raise DecodeError: Malformed stream.
    :raise RuntimeError: Decoder is unable to fully consume the
        stream buffer.

    :return: Message envelope.
    :rtype: :class:`Envelope`
    """
    if not isinstance(stream, util.BufferedByteStream):
        stream = util.BufferedByteStream(stream)

    if logger is not None:
        logger.debug('remoting.decode start')

    msg = Envelope()
    msg.amfVersion = stream.read_ushort()

    # see http://osflash.org/documentation/amf/envelopes/remoting#preamble
    # why we are doing this...
    if msg.amfVersion > 0x09:
        raise pyamf.DecodeError("Malformed stream (amfVersion=%d)" %
            msg.amfVersion)

    if context is None:
        context = pyamf.get_context(pyamf.AMF0)

    decoder = pyamf.get_decoder(pyamf.AMF0, stream, context=context,
        strict=strict, timezone_offset=timezone_offset)

    header_count = stream.read_ushort()

    for i in xrange(header_count):
        name, required, data = _read_header(stream, decoder, strict)
        msg.headers[name] = data

        if required:
            msg.headers.set_required(name)

    body_count = stream.read_short()

    for i in range(body_count):
        context.clear()

        target, payload = _read_body(stream, decoder, strict, logger)
        msg[target] = payload

    if strict and stream.remaining() > 0:
        raise RuntimeError("Unable to fully consume the buffer")

    if logger is not None:
        logger.debug('remoting.decode end')

    return msg
Beispiel #34
0
    def post(self):
        body = self.request.body_file.read()
        stream = None

        context = pyamf.get_context(pyamf.AMF0)

        # Decode the request
        try:
            request = remoting.decode(body, context, strict=self.strict)
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            self.error(400)
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.headers['Server'] = gateway.SERVER_NAME
            self.response.out.write(response)

            return

        self.logger.debug("AMF Request: %r" % request)

        # Process the request
        try:
            response = self.getResponse(request)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be successfully processed."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            self.error(500)
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.headers['Server'] = gateway.SERVER_NAME
            self.response.out.write(response)

            return

        self.logger.debug("AMF Response: %r" % response)

        # Encode the response
        try:
            stream = remoting.encode(response, context, strict=self.strict)
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be encoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            self.error(500)
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.headers['Server'] = gateway.SERVER_NAME
            self.response.out.write(response)

            return

        response = stream.getvalue()

        self.response.headers['Content-Type'] = remoting.CONTENT_TYPE
        self.response.headers['Content-Length'] = str(len(response))
        self.response.headers['Server'] = gateway.SERVER_NAME

        self.response.out.write(response)
Beispiel #35
0
    def post(self):
        body = self.request.body_file.read()
        stream = None

        context = pyamf.get_context(pyamf.AMF0)

        # Decode the request
        try:
            request = remoting.decode(body, context, strict=self.strict)
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "400 Bad Request\n\nThe request body was unable to " \
                "be successfully decoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            self.error(400)
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.headers['Server'] = gateway.SERVER_NAME
            self.response.out.write(response)

            return

        self.logger.debug("AMF Request: %r" % request)

        # Process the request
        try:
            response = self.getResponse(request)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be successfully processed."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            self.error(500)
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.headers['Server'] = gateway.SERVER_NAME
            self.response.out.write(response)

            return

        self.logger.debug("AMF Response: %r" % response)

        # Encode the response
        try:
            stream = remoting.encode(response, context, strict=self.strict)
        except:
            fe = gateway.format_exception()
            self.logger.exception(fe)

            response = "500 Internal Server Error\n\nThe request was " \
                "unable to be encoded."

            if self.debug:
                response += "\n\nTraceback:\n\n%s" % fe

            self.error(500)
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.headers['Server'] = gateway.SERVER_NAME
            self.response.out.write(response)

            return

        response = stream.getvalue()

        self.response.headers['Content-Type'] = remoting.CONTENT_TYPE
        self.response.headers['Content-Length'] = str(len(response))
        self.response.headers['Server'] = gateway.SERVER_NAME

        self.response.out.write(response)
Beispiel #36
0
 def setUp(self):
     self.context = pyamf.get_context(self.amf_version)
     self.stream = BufferedByteStream()
Beispiel #37
0
def decode(stream,
           context=None,
           strict=False,
           logger=None,
           timezone_offset=None):
    """
    Decodes the incoming stream as a remoting message.

    @param stream: AMF data.
    @type stream: L{BufferedByteStream<pyamf.util.BufferedByteStream>}
    @param context: Context.
    @type context: L{amf0.Context<pyamf.amf0.Context>} or
    L{amf3.Context<pyamf.amf3.Context>}
    @param strict: Enforce strict decoding. Default is C{False}.
    @type strict: C{bool}
    @param logger: Used to log interesting events whilst decoding a remoting
        message.
    @type logger: A L{logging.Logger} instance or C{None}.
    @param timezone_offset: The difference between the current timezone and
        UTC. Date/times should always be handled in UTC to avoid confusion but
        this is required for legacy systems.
    @type timezone_offset: L{datetime.timedelta}

    @raise DecodeError: Malformed stream.
    @raise RuntimeError: Decoder is unable to fully consume the
        stream buffer.

    @return: Message envelope.
    @rtype: L{Envelope}
    """
    if not isinstance(stream, util.BufferedByteStream):
        stream = util.BufferedByteStream(stream)

    if logger is not None:
        logger.debug('remoting.decode start')

    msg = Envelope()
    msg.amfVersion = stream.read_uchar()

    # see http://osflash.org/documentation/amf/envelopes/remoting#preamble
    # why we are doing this...
    if msg.amfVersion > 0x09:
        raise pyamf.DecodeError("Malformed stream (amfVersion=%d)" %
                                msg.amfVersion)

    if context is None:
        context = pyamf.get_context(pyamf.AMF0, exceptions=False)

    decoder = pyamf.get_decoder(pyamf.AMF0,
                                stream,
                                context=context,
                                strict=strict,
                                timezone_offset=timezone_offset)
    msg.clientType = stream.read_uchar()

    header_count = stream.read_ushort()

    for i in xrange(header_count):
        name, required, data = _read_header(stream, decoder, strict)
        msg.headers[name] = data

        if required:
            msg.headers.set_required(name)

    body_count = stream.read_short()

    for i in range(body_count):
        context.clear()

        target, payload = _read_body(stream, decoder, strict, logger)
        msg[target] = payload

    if strict and stream.remaining() > 0:
        raise RuntimeError("Unable to fully consume the buffer")

    if logger is not None:
        logger.debug('remoting.decode end')

    return msg