def load(req):
    """Reads request body, raising an exception if it is not JSON.

    :param req: The request object to read from
    :type req: falcon.Request
    :return: a dictionary decoded from the JSON stream
    :rtype: dict
    :raises: wsgi_errors.HTTPBadRequestBody
    """
    try:
        return json_utils.read_json(req.stream, req.content_length)
    except (json_utils.MalformedJSON, json_utils.OverflowedJSONInteger) as ex:
        LOG.exception(ex)
        raise wsgi_errors.HTTPBadRequestBody('JSON could not be parsed.')
Exemple #2
0
def load(req):
    """Reads request body, raising an exception if it is not JSON.

    :param req: The request object to read from
    :type req: falcon.Request
    :return: a dictionary decoded from the JSON stream
    :rtype: dict
    :raises: wsgi_errors.HTTPBadRequestBody
    """
    try:
        return json_utils.read_json(req.stream, req.content_length)
    except (json_utils.MalformedJSON, json_utils.OverflowedJSONInteger) as ex:
        LOG.exception(ex)
        raise wsgi_errors.HTTPBadRequestBody(
            'JSON could not be parsed.'
        )
def filter_stream(stream, len, spec=None, doctype=JSONObject):
    """Reads, deserializes, and validates a document from a stream.

    :param stream: file-like object from which to read an object or
        array of objects.
    :param len: number of bytes to read from stream
    :param spec: (Default None) Iterable describing expected fields,
        yielding tuples with the form of:

            (field_name, value_type).

        Note that value_type may either be a Python type, or the
        special string '*' to accept any type. If spec is None, the
        incoming documents will not be validated.
    :param doctype: type of document to expect; must be either
        JSONObject or JSONArray.
    :raises: HTTPBadRequest, HTTPServiceUnavailable
    :returns: A sanitized, filtered version of the document list read
        from the stream. If the document contains a list of objects,
        each object will be filtered and returned in a new list. If,
        on the other hand, the document is expected to contain a
        single object, that object will be filtered and returned as
        a single-element iterable.
    """

    if len is None:
        description = _(u'Request body can not be empty')
        raise errors.HTTPBadRequestBody(description)

    try:
        # TODO(kgriffs): read_json should stream the resulting list
        # of messages, returning a generator rather than buffering
        # everything in memory (bp/streaming-serialization).
        document = utils.read_json(stream, len)

    except utils.MalformedJSON as ex:
        LOG.debug(ex)
        description = _(u'Request body could not be parsed.')
        raise errors.HTTPBadRequestBody(description)

    except utils.OverflowedJSONInteger as ex:
        LOG.debug(ex)
        description = _(u'JSON contains integer that is too large.')
        raise errors.HTTPBadRequestBody(description)

    except Exception as ex:
        # Error while reading from the network/server
        LOG.exception(ex)
        description = _(u'Request body could not be read.')
        raise errors.HTTPServiceUnavailable(description)

    if doctype is JSONObject:
        if not isinstance(document, JSONObject):
            raise errors.HTTPDocumentTypeNotSupported()

        return (document, ) if spec is None else (filter(document, spec), )

    if doctype is JSONArray:
        if not isinstance(document, JSONArray):
            raise errors.HTTPDocumentTypeNotSupported()

        if spec is None:
            return document

        return [filter(obj, spec) for obj in document]

    raise TypeError('doctype must be either a JSONObject or JSONArray')
Exemple #4
0
def filter_stream(stream, len, spec=None, doctype=JSONObject):
    """Reads, deserializes, and validates a document from a stream.

    :param stream: file-like object from which to read an object or
        array of objects.
    :param len: number of bytes to read from stream
    :param spec: (Default None) Iterable describing expected fields,
        yielding tuples with the form of:

            (field_name, value_type).

        Note that value_type may either be a Python type, or the
        special string '*' to accept any type. If spec is None, the
        incoming documents will not be validated.
    :param doctype: type of document to expect; must be either
        JSONObject or JSONArray.
    :raises: HTTPBadRequest, HTTPServiceUnavailable
    :returns: A sanitized, filtered version of the document list read
        from the stream. If the document contains a list of objects,
        each object will be filtered and returned in a new list. If,
        on the other hand, the document is expected to contain a
        single object, that object will be filtered and returned as
        a single-element iterable.
    """

    if len is None:
        description = _(u'Request body can not be empty')
        raise errors.HTTPBadRequestBody(description)

    try:
        # TODO(kgriffs): read_json should stream the resulting list
        # of messages, returning a generator rather than buffering
        # everything in memory (bp/streaming-serialization).
        document = utils.read_json(stream, len)

    except utils.MalformedJSON as ex:
        LOG.debug(ex)
        description = _(u'Request body could not be parsed.')
        raise errors.HTTPBadRequestBody(description)

    except utils.OverflowedJSONInteger as ex:
        LOG.debug(ex)
        description = _(u'JSON contains integer that is too large.')
        raise errors.HTTPBadRequestBody(description)

    except Exception as ex:
        # Error while reading from the network/server
        LOG.exception(ex)
        description = _(u'Request body could not be read.')
        raise errors.HTTPServiceUnavailable(description)

    if doctype is JSONObject:
        if not isinstance(document, JSONObject):
            raise errors.HTTPDocumentTypeNotSupported()

        return (document,) if spec is None else (filter(document, spec),)

    if doctype is JSONArray:
        if not isinstance(document, JSONArray):
            raise errors.HTTPDocumentTypeNotSupported()

        if spec is None:
            return document

        return [filter(obj, spec) for obj in document]

    raise TypeError('doctype must be either a JSONObject or JSONArray')