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)
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)
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())
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
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
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