def _get_params(method, encoding, fields, params=None):
    """
    Separate the params into the various types.
    """
    if params is None:
        return empty_params

    field_map = {field.name: field for field in fields}

    path = {}
    query = {}
    data = {}
    files = {}

    errors = {}

    # Ensure graceful behavior in edge-case where both location='body' and
    # location='form' fields are present.
    seen_body = False

    for key, value in params.items():
        if key not in field_map or not field_map[key].location:
            # Default is 'query' for 'GET' and 'DELETE', and 'form' for others.
            location = 'query' if method in ('GET', 'DELETE') else 'form'
        else:
            location = field_map[key].location

        if location == 'form' and encoding == 'application/octet-stream':
            # Raw uploads should always use 'body', not 'form'.
            location = 'body'

        try:
            if location == 'path':
                path[key] = utils.validate_path_param(value)
            elif location == 'query':
                query[key] = utils.validate_query_param(value)
            elif location == 'body':
                data = utils.validate_body_param(value, encoding=encoding)
                seen_body = True
            elif location == 'form':
                if not seen_body:
                    data[key] = utils.validate_form_param(value,
                                                          encoding=encoding)
        except exceptions.ParameterError as exc:
            errors[key] = exc.message

    if errors:
        raise exceptions.ParameterError(errors)

    # Move any files from 'data' into 'files'.
    if isinstance(data, dict):
        for key, value in list(data.items()):
            if is_file(data[key]):
                files[key] = data.pop(key)

    return Params(path, query, data, files)
示例#2
0
def test_validate_form_data():
    # Valid JSON
    data = {
        'string': 'abc',
        'integer': 123,
        'number': 123.456,
        'boolean': True,
        'null': None,
        'array': [1, 2, 3],
        'object': {
            'a': 1,
            'b': 2,
            'c': 3
        }
    }
    assert utils.validate_form_param(data, 'application/json') == data
    assert utils.validate_body_param(data, 'application/json') == data

    # Invalid JSON
    data = datetime.datetime.now()
    with pytest.raises(exceptions.ParameterError):
        utils.validate_form_param(data, 'application/json')
    with pytest.raises(exceptions.ParameterError):
        utils.validate_body_param(data, 'application/json')

    data = utils.File('abc.txt', None)
    with pytest.raises(exceptions.ParameterError):
        utils.validate_form_param(data, 'application/json')
    with pytest.raises(exceptions.ParameterError):
        utils.validate_body_param(data, 'application/json')

    # URL Encoded
    assert utils.validate_form_param(
        123, 'application/x-www-form-urlencoded') == '123'
    assert utils.validate_body_param({'a': 123},
                                     'application/x-www-form-urlencoded') == {
                                         'a': '123'
                                     }
    with pytest.raises(exceptions.ParameterError):
        utils.validate_form_param({'a': {
            'foo': 'bar'
        }}, 'application/x-www-form-urlencoded')
    with pytest.raises(exceptions.ParameterError):
        utils.validate_body_param(123, 'application/x-www-form-urlencoded')
    with pytest.raises(exceptions.ParameterError):
        utils.validate_form_param(utils.File('abc.txt', None),
                                  'application/x-www-form-urlencoded')
    with pytest.raises(exceptions.ParameterError):
        utils.validate_body_param({'a': utils.File('abc.txt', None)},
                                  'application/x-www-form-urlencoded')

    # Multipart
    assert utils.validate_form_param(123, 'multipart/form-data') == '123'
    assert utils.validate_form_param(utils.File('abc.txt', None),
                                     'multipart/form-data') == utils.File(
                                         'abc.txt', None)
    assert utils.validate_body_param({'a': 123}, 'multipart/form-data') == {
        'a': '123'
    }
    assert utils.validate_body_param({'a': utils.File('abc.txt', None)},
                                     'multipart/form-data') == {
                                         'a': utils.File('abc.txt', None)
                                     }
    with pytest.raises(exceptions.ParameterError):
        utils.validate_form_param({'a': {'foo': 'bar'}}, 'multipart/form-data')
    with pytest.raises(exceptions.ParameterError):
        utils.validate_body_param(123, 'multipart/form-data')

    # Raw upload
    with pytest.raises(exceptions.ParameterError):
        utils.validate_body_param(123, 'application/octet-stream')

    # Invalid encoding on outgoing request
    with pytest.raises(exceptions.NetworkError):
        assert utils.validate_form_param(123, 'invalid/media-type')
    with pytest.raises(exceptions.NetworkError):
        assert utils.validate_form_param(123, '')
    with pytest.raises(exceptions.NetworkError):
        assert utils.validate_body_param(123, 'invalid/media-type')