Example #1
0
    def __init__(self, path='/', base_url=None, query_string=None,
                 method='GET', input_stream=None, content_type=None,
                 content_length=None, errors_stream=None, multithread=False,
                 multiprocess=False, run_once=False, headers=None, data=None,
                 environ_base=None, environ_overrides=None, charset='utf-8'):
        path_s = make_literal_wrapper(path)
        if query_string is None and path_s('?') in path:
            path, query_string = path.split(path_s('?'), 1)
        self.charset = charset
        self.path = iri_to_uri(path)
        if base_url is not None:
            base_url = url_fix(iri_to_uri(base_url, charset), charset)
        self.base_url = base_url
        if isinstance(query_string, (bytes, str)):
            self.query_string = query_string
        else:
            if query_string is None:
                query_string = MultiDict()
            elif not isinstance(query_string, MultiDict):
                query_string = MultiDict(query_string)
            self.args = query_string
        self.method = method
        if headers is None:
            headers = Headers()
        elif not isinstance(headers, Headers):
            headers = Headers(headers)
        self.headers = headers
        if content_type is not None:
            self.content_type = content_type
        if errors_stream is None:
            errors_stream = sys.stderr
        self.errors_stream = errors_stream
        self.multithread = multithread
        self.multiprocess = multiprocess
        self.run_once = run_once
        self.environ_base = environ_base
        self.environ_overrides = environ_overrides
        self.input_stream = input_stream
        self.content_length = content_length
        self.closed = False

        if data:
            if input_stream is not None:
                raise TypeError('can\'t provide input stream and data')
            if isinstance(data, str):
                data = data.encode(self.charset)
            if isinstance(data, bytes):
                self.input_stream = BytesIO(data)
                if self.content_length is None:
                    self.content_length = len(data)
            else:
                for key, value in _iter_data(data):
                    if (
                        isinstance(value, (tuple, dict)) or
                        hasattr(value, 'read')
                    ):
                        self._add_file_from_data(key, value)
                    else:
                        self.form.setlistdefault(key).append(value)
Example #2
0
 def values(self):
     """Combined multi dict for :attr:`args` and :attr:`form`."""
     args = []
     for d in self.args, self.form:
         if not isinstance(d, MultiDict):
             d = MultiDict(d)
         args.append(d)
     return CombinedMultiDict(args)
Example #3
0
    def test_base_request(self):
        client = Client(request_demo_app, RequestTestResponse)

        # get requests
        response = client.get('/?foo=bar&foo=hehe')
        self.assertEqual(response['args'],
                         MultiDict([('foo', u'bar'), ('foo', u'hehe')]))
        self.assertEqual(response['args_as_list'],
                         [('foo', [u'bar', u'hehe'])])
        self.assertEqual(response['form'], MultiDict())
        self.assertEqual(response['form_as_list'], [])
        self.assertEqual(response['data'], b'')
        self.assert_environ(response['environ'], 'GET')

        # post requests with form data
        response = client.post(
            '/?blub=blah',
            data='foo=blub+hehe&blah=42',
            content_type='application/x-www-form-urlencoded')
        self.assertEqual(response['args'], MultiDict([('blub', u'blah')]))
        self.assertEqual(response['args_as_list'], [('blub', [u'blah'])])
        self.assertEqual(response['form'],
                         MultiDict([
                             ('foo', u'blub hehe'),
                             ('blah', u'42'),
                         ]))
        self.assertEqual(response['data'], b'')
        self.assert_environ(response['environ'], 'POST')

        # patch requests with form data
        response = client.patch(
            '/?blub=blah',
            data='foo=blub+hehe&blah=42',
            content_type='application/x-www-form-urlencoded')
        self.assertEqual(response['args'], MultiDict([('blub', u'blah')]))
        self.assertEqual(response['args_as_list'], [('blub', [u'blah'])])
        self.assertEqual(response['form'],
                         MultiDict([
                             ('foo', u'blub hehe'),
                             ('blah', u'42'),
                         ]))
        self.assertEqual(response['data'], b'')
        self.assert_environ(response['environ'], 'PATCH')

        # post requests with json data
        json = b'{"foo": "bar", "blub": "blah"}'
        response = client.post('/?a=b',
                               data=json,
                               content_type='application/json')
        self.assertEqual(response['data'], json)
        self.assertEqual(response['args'], MultiDict([('a', u'b')]))
        self.assertEqual(response['form'], MultiDict())
Example #4
0
 def _get_args(self):
     if self._query_string is not None:
         raise AttributeError('a query string is defined')
     if self._args is None:
         self._args = MultiDict()
     return self._args
Example #5
0
def stream_encode_multipart(values,
                            use_tempfile=True,
                            threshold=1024 * 500,
                            boundary=None,
                            charset='utf-8'):
    """Encode a dict of values (either strings or file descriptors or
    :class:`FileStorage` objects.) into a multipart encoded string stored
    in a file descriptor.
    """
    if boundary is None:
        boundary = '---------------WerkzeugFormPart_%s%s' % (time(), random())
    stream = BytesIO()
    total_length = 0
    on_disk = False

    if use_tempfile:

        def write_binary(string):
            nonlocal stream, total_length, on_disk
            if on_disk:
                stream.write(string)
            else:
                length = len(string)
                if length + total_length <= threshold:
                    stream.write(string)
                else:
                    new_stream = TemporaryFile('wb+')
                    new_stream.write(stream.getvalue())
                    new_stream.write(string)
                    stream = new_stream
                    on_disk = True
                total_length = total_length + length
    else:
        write_binary = stream.write

    def write(string):
        write_binary(string.encode(charset))

    if not isinstance(values, MultiDict):
        values = MultiDict(values)

    for key, values in values.lists():
        for value in values:
            write('--%s\r\nContent-Disposition: form-data; name="%s"' %
                  (boundary, key))
            reader = getattr(value, 'read', None)
            if reader is not None:
                filename = getattr(value, 'filename',
                                   getattr(value, 'name', None))
                content_type = getattr(value, 'content_type', None)
                if content_type is None and filename:
                    content_type = mimetypes.guess_type(filename)[0]
                if content_type is None:
                    content_type = 'application/octet-stream'
                if filename is not None:
                    write('; filename="%s"\r\n' % filename)
                else:
                    write('\r\n')
                write('Content-Type: %s\r\n\r\n' % content_type)
                while 1:
                    chunk = reader(16384)
                    if not chunk:
                        break
                    write_binary(chunk)
            else:
                if isinstance(value, str):
                    write(value)
                else:
                    write_binary(value)
                write('\r\n\r\n')
                write_binary(value)
            write('\r\n')
    write('--%s--\r\n' % boundary)

    length = int(stream.tell())
    stream.seek(0)
    return stream, length, boundary
Example #6
0
def stream_encode_multipart(
    values, use_tempfile=True, threshold=1024 * 500,
    boundary=None, charset='utf-8',
):
    """Encode a dict of values (either strings or file descriptors or
    :class:`FileStorage` objects.) into a multipart encoded string stored
    in a file descriptor.
    """
    if boundary is None:
        boundary = '---------------WerkzeugFormPart_%s%s' % (time(), random())
    stream = BytesIO()
    total_length = 0
    on_disk = False

    if use_tempfile:
        def write_binary(string):
            nonlocal stream, total_length, on_disk
            if on_disk:
                stream.write(string)
            else:
                length = len(string)
                if length + total_length <= threshold:
                    stream.write(string)
                else:
                    new_stream = TemporaryFile('wb+')
                    new_stream.write(stream.getvalue())
                    new_stream.write(string)
                    stream = new_stream
                    on_disk = True
                total_length = total_length + length
    else:
        write_binary = stream.write

    def write(string):
        write_binary(string.encode(charset))

    if not isinstance(values, MultiDict):
        values = MultiDict(values)

    for key, values in values.lists():
        for value in values:
            write(
                '--%s\r\nContent-Disposition: form-data; name="%s"' %
                (boundary, key),
            )
            reader = getattr(value, 'read', None)
            if reader is not None:
                filename = getattr(
                    value, 'filename', getattr(value, 'name', None),
                )
                content_type = getattr(value, 'content_type', None)
                if content_type is None and filename:
                    content_type = mimetypes.guess_type(filename)[0]
                if content_type is None:
                    content_type = 'application/octet-stream'
                if filename is not None:
                    write('; filename="%s"\r\n' % filename)
                else:
                    write('\r\n')
                write('Content-Type: %s\r\n\r\n' % content_type)
                while 1:
                    chunk = reader(16384)
                    if not chunk:
                        break
                    write_binary(chunk)
            else:
                if isinstance(value, str):
                    write(value)
                else:
                    write_binary(value)
                write('\r\n\r\n')
                write_binary(value)
            write('\r\n')
    write('--%s--\r\n' % boundary)

    length = int(stream.tell())
    stream.seek(0)
    return stream, length, boundary