def application(environ, start_response): response_headers = [('Content-type', 'application/octet-stream')] stream, form, files = parse_form_data(environ) stream, form, files = parse_form_data(environ) try: start_response('200 OK', response_headers) return files['file'].stream except: start_response('400 BAD REQUEST', response_headers) return [environ['PATH_INFO']]
def test_broken(self): data = ( "--foo\r\n" 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n' "Content-Transfer-Encoding: base64\r\n" "Content-Type: text/plain\r\n\r\n" "broken base 64" "--foo--" ) _, form, files = formparser.parse_form_data( create_environ( data=data, method="POST", content_type="multipart/form-data; boundary=foo", ) ) assert not files assert not form pytest.raises( ValueError, formparser.parse_form_data, create_environ( data=data, method="POST", content_type="multipart/form-data; boundary=foo", ), silent=False, )
def decompose_incoming_envelope(self, prot, ctx, message): """This function is only called by the HttpRpc protocol to have the wsgi environment parsed into ``ctx.in_body_doc`` and ``ctx.in_header_doc``. """ if self.has_patterns: from werkzeug.exceptions import NotFound if self._map_adapter is None: self.generate_map_adapter(ctx) try: #If PATH_INFO matches a url, Set method_request_string to mrs mrs, params = self._map_adapter.match(ctx.in_document["PATH_INFO"], ctx.in_document["REQUEST_METHOD"]) ctx.method_request_string = mrs except NotFound: # Else set method_request_string normally params = {} ctx.method_request_string = '{%s}%s' % (prot.app.interface.get_tns(), ctx.in_document['PATH_INFO'].split('/')[-1]) else: params = {} ctx.method_request_string = '{%s}%s' % (prot.app.interface.get_tns(), ctx.in_document['PATH_INFO'].split('/')[-1]) logger.debug("%sMethod name: %r%s" % (LIGHT_GREEN, ctx.method_request_string, END_COLOR)) ctx.in_header_doc = _get_http_headers(ctx.in_document) ctx.in_body_doc = parse_qs(ctx.in_document['QUERY_STRING']) for k,v in params.items(): if k in ctx.in_body_doc: ctx.in_body_doc[k].append(v) else: ctx.in_body_doc[k] = [v] if ctx.in_document['REQUEST_METHOD'].upper() in ('POST', 'PUT', 'PATCH'): stream, form, files = parse_form_data(ctx.in_document, stream_factory=prot.stream_factory) for k, v in form.lists(): val = ctx.in_body_doc.get(k, []) val.extend(v) ctx.in_body_doc[k] = val for k, v in files.items(): val = ctx.in_body_doc.get(k, []) mime_type = v.headers.get('Content-Type', 'application/octet-stream') path = getattr(v.stream, 'name', None) if path is None: val.append(File.Value(name=v.filename, type=mime_type, data=[v.stream.getvalue()])) else: v.stream.seek(0) val.append(File.Value(name=v.filename, type=mime_type, path=path, handle=v.stream)) ctx.in_body_doc[k] = val
def generate_formdata(req, resp, params): """sets prarams['form'] to pass to every endpoint. """ #print "here" form = dict() files = dict() if req.method == 'GET': di = parse_query_string(req.query_string) form = dict(di) params['form'], params['files'] = dict(form), dict(files) else: if 'json' in req.get_header('content-type', None): form = json.load(req.stream) params['form'], params['files'] = dict(form), dict(files) else: mimetype, options = parse_options_header(req.get_header('content-type')) data = req.stream.read() environ = {'wsgi.input': StringIO(data), 'CONTENT_LENGTH': str(len(data)), 'CONTENT_TYPE': req.get_header('content-type'), 'REQUEST_METHOD': 'POST'} stream, tempform, tempfiles = parse_form_data(environ) for item in tempform: form[item] = tempform[item] di = parse_query_string(req.query_string) for item in di: form[item] = di[item] for item in tempfiles: files[item] = tempfiles[item] params['form'], params['files'] = dict(form), dict(files) return True
def decompose_incoming_envelope(self, ctx): ctx.method_request_string = '{%s}%s' % (self.app.interface.get_tns(), ctx.in_document['PATH_INFO'].split('/')[-1]) logger.debug("\033[92mMethod name: %r\033[0m" % ctx.method_request_string) ctx.in_header_doc = _get_http_headers(ctx.in_document) ctx.in_body_doc = parse_qs(ctx.in_document['QUERY_STRING']) if ctx.transport.req_env['REQUEST_METHOD'].lower() in ('post', 'put', 'patch'): stream, form, files = parse_form_data(ctx.transport.req_env) for k, v in form.lists(): val = ctx.in_body_doc.get(k, []) val.extend(v) ctx.in_body_doc[k] = val for k, v in files.items(): val = ctx.in_body_doc.get(k, []) val.append(yield_stream(v.stream)) ctx.in_body_doc[k] = val # FIXME: some proper variable matching is needed here. k2 = k + "_name" val = ctx.in_body_doc.get(k2, []) val.append(v.filename) ctx.in_body_doc[k2] = val k2 = k + "_type" val = ctx.in_body_doc.get(k2, []) val.append(v.headers.get('Content-Type','application/octet-stream')) ctx.in_body_doc[k2] = val logger.debug('\theader : %r' % (ctx.in_header_doc)) logger.debug('\tbody : %r' % (ctx.in_body_doc))
def media(self): if self._media is not None: return self._media if (self.method in ('POST', 'PUT', 'PATCH') and any(ct in (self.content_type or '') for ct in ('application/x-www-form-urlencoded', 'application/x-url-encoded', 'multipart/form-data'))): try: _, form, files = parse_form_data( environ=self.env, stream_factory=self._stream_factory, max_form_memory_size=self.options.max_form_memory_size) except RequestEntityTooLarge: raise FalconHeavyRequestEntityTooLarge() self._media = form.to_dict(flat=False) self._media.update(files.to_dict(flat=False)) for k, v in iteritems(self._media): if len(self._media[k]) == 1: self._media[k] = v[0] return self._media return super(FalconHeavyRequest, self).media
def test_parse_form_data_get_without_content(self): env = create_environ('/foo', 'http://example.org/', method='GET') stream, form, files = formparser.parse_form_data(env) strict_eq(stream.read(), b'') strict_eq(len(form), 0) strict_eq(len(files), 0)
def _load_form_data(self): if "stream" in self.__dict__: return if self.shallow: raise RuntimeError( "A shallow request tried to consume form data. If you really want to do that, set `shallow` to False." ) data = None stream = _empty_stream if self.environ["REQUEST_METHOD"] in ("POST", "PUT"): try: data = parse_form_data( self.environ, self._get_file_stream, self.charset, self.encoding_errors, self.max_form_memory_size, self.max_content_length, cls=self.parameter_storage_class, silent=False, ) except ValueError as e: self._form_parsing_failed(e) else: content_length = self.headers.get("content-length", type=int) if content_length is not None: stream = LimitedStream(self.environ["wsgi.input"], content_length) if data is None: data = (stream, self.parameter_storage_class(), self.parameter_storage_class()) d = self.__dict__ d["stream"], d["form"], d["files"] = data
def _is_single_sign_out(self, environ): logging.debug("Testing for SLO") if environ['REQUEST_METHOD'] == 'POST': current_url = environ.get('PATH_INFO','') origin = self._entry_page logging.debug("Testing for SLO:" + current_url + " vs " + origin) if current_url == origin: try: form = parse_form_data(environ)[1] request_body = form['logoutRequest'] request_body = unquote_plus(request_body).decode('utf8') logging.debug("POST:" + str(request_body)) logging.debug("POST:" + str(environ)) dom = xml.dom.minidom.parseString(request_body) nodes = dom.getElementsByTagNameNS(self.samlpNamespaceUri, 'SessionIndex') if nodes: sessionNode = nodes[0] if sessionNode.firstChild is not None: sessionId = sessionNode.firstChild.nodeValue logging.info("Received SLO request for:" + sessionId) self._remove_session_by_ticket(sessionId) return True except (Exception): logging.warning("Exception parsing post") logging.exception("Exception parsing post:" + request_body) return False
def test_parse_form_data_get_without_content(self): env = create_environ("/foo", "http://example.org/", method="GET") stream, form, files = formparser.parse_form_data(env) assert stream.read() == b"" assert len(form) == 0 assert len(files) == 0
def __call__(self, environ, start_response): request = Request(environ) response = Response('') self._get_session(request) request_method = environ['REQUEST_METHOD'] form = parse_form_data(environ)[1] path = environ.get('PATH_INFO', '') request_url = request.url params = request.args resp = self._process_request(request_method, request_url, path, params, form) logging.debug(str(resp)) if resp: if 'set_values' in resp: self._set_values(environ) return self._application(environ, start_response) if 'ignore_callback' in resp and resp['ignore_callback'] == True: return self._ignored_callback(environ, start_response) if 'status' in resp: response.status = resp['status'] for name in ['Location', 'Content-Type', 'WWW-Authenticate']: if name in resp['headers']: response.headers[name] = resp['headers'][name] if 'data' in resp: response.data = resp['data'] response.set_cookie(self.CAS_COOKIE_NAME, value=self._session.sid, max_age=None, expires=None) return response(environ, start_response) else: return self._application(environ, start_response)
def __call__(self, environ, start_response): request = Request(environ) response = Response('') self._get_session(request) request_method = environ['REQUEST_METHOD'] form = parse_form_data(environ)[1] path = environ.get('PATH_INFO','') request_url = request.url params = request.args resp = self._process_request(request_method, request_url, path, params, form) logging.debug(str(resp)) if resp: if 'set_values' in resp: self._set_values(environ) return self._application(environ, start_response) if 'ignore_callback' in resp and resp['ignore_callback'] == True: return self._ignored_callback(environ, start_response) if 'status' in resp: response.status = resp['status'] for name in ['Location', 'Content-Type', 'WWW-Authenticate']: if name in resp['headers']: response.headers[name] = resp['headers'][name] if 'data' in resp: response.data = resp['data'] response.set_cookie(self.CAS_COOKIE_NAME, value = self._session.sid, max_age = None, expires = None) return response(environ, start_response) else: return self._application(environ, start_response)
def decompose_incoming_envelope(self, ctx): ctx.method_request_string = '{%s}%s' % (self.app.interface.get_tns(), ctx.in_document['PATH_INFO'].split('/')[-1]) logger.debug("\033[92mMethod name: %r\033[0m" % ctx.method_request_string) ctx.in_header_doc = _get_http_headers(ctx.in_document) ctx.in_body_doc = parse_qs(ctx.in_document['QUERY_STRING']) if ctx.transport.req_env['REQUEST_METHOD'].lower() in ('post', 'put', 'patch'): stream, form, files = parse_form_data(ctx.transport.req_env, stream_factory=self.stream_factory) for k, v in form.lists(): val = ctx.in_body_doc.get(k, []) val.extend(v) ctx.in_body_doc[k] = val for k, v in files.items(): val = ctx.in_body_doc.get(k, []) mime_type = v.headers.get('Content-Type', 'application/octet-stream') path = getattr(v.stream, 'name', None) if path is None: val.append(File(name=v.filename, type=mime_type, data=[v.stream.getvalue()])) else: v.stream.seek(0) val.append(File(name=v.filename, type=mime_type, path=path, handle=v.stream)) ctx.in_body_doc[k] = val logger.debug('\theader : %r' % (ctx.in_header_doc)) logger.debug('\tbody : %r' % (ctx.in_body_doc))
def __init__(self, env, registry): self.env = env self.headers = dict(self.headers_from_env(env)) self.registry = registry self._out_headers = [] self._out_status = 200 self._response = None self.method = self.env['REQUEST_METHOD'] # `self.vars` setup, will contain keys 'cookie', 'get' and 'post' self.vars = { 'cookie': dict((name, value.value) for name, value in Cookie( self.env.get('HTTP_COOKIE')).items()), 'get': PostDictionary(cgi.parse_qs(self.env.get('QUERY_STRING'))), 'post': PostDictionary() } self.env['host'] = self.headers.get('Host', '') if self.method == 'POST': stream, form, files = parse_form_data(self.env) if self.env['CONTENT_TYPE'] == 'application/json': try: request_body_size = int(self.env.get('CONTENT_LENGTH', 0)) except (ValueError): request_body_size = 0 request_body = self.env['wsgi.input'].read(request_body_size) data = json.loads(request_body) self.vars['post'] = PostDictionary(MultiDict(data)) else: self.vars['post'] = PostDictionary(form) for f in files: self.vars['post'][f] = files.get(f)
def generate_formdata(req, resp, params): form = dict() files = dict() if req.method == 'GET': di = parse_query_string(req.query_string) form = dict(di) params['form'], params['files'] = dict(form), dict(files) else: if 'json' in req.get_header('content-type', None): #if the method type is post "form" variable below can contain #only either the post body or the quer parameter at once, modify #umcomment the below commented line to store query parameters in "form" form = json.load(req.stream) #form = dict(parse_query_string(req.query_string)) params['form'], params['files'] = dict(form), dict(files) else: mimetype, options = parse_options_header(req.get_header('content-type')) data = req.stream.read() environ = {'wsgi.input':StringIO(data), 'CONTENT_LENGTH': str(len(data)), 'CONTENT_TYPE': req.get_header('content-type'), 'REQUEST_METHOD': 'POST'} stream, tempform, tempfiles = parse_form_data(environ) for item in tempform: form[item] = tempform[item] di = parse_query_string(req.query_string) for item in di: form[item] = di[item] for item in tempfiles: files[item] = tempfiles[item] params['form'], params['files'] = dict(form), dict(files) #print form #print params return True
def test_parse_form_data_get_without_content(self): env = create_environ("/foo", "http://example.org/", method="GET") stream, form, files = formparser.parse_form_data(env) strict_eq(stream.read(), b"") strict_eq(len(form), 0) strict_eq(len(files), 0)
def test_parse_form_data_get_without_content(self): env = create_environ('/foo', 'http://example.org/', method='GET') del env['CONTENT_TYPE'] del env['CONTENT_LENGTH'] stream, form, files = formparser.parse_form_data(env) self.assert_equal(stream.read(), '') self.assert_equal(len(form), 0) self.assert_equal(len(files), 0)
def test_parse_form_data_get_without_content(self): env = create_environ("/foo", "http://example.org/", method="GET") del env["CONTENT_TYPE"] del env["CONTENT_LENGTH"] stream, form, files = formparser.parse_form_data(env) self.assert_equal(stream.read(), "") self.assert_equal(len(form), 0) self.assert_equal(len(files), 0)
def test_parse_form_data_get_without_content(self): env = create_environ('/foo', 'http://example.org/', method='GET') del env['CONTENT_TYPE'] del env['CONTENT_LENGTH'] stream, form, files = formparser.parse_form_data(env) self.assert_strict_equal(stream.read(), b'') self.assert_strict_equal(len(form), 0) self.assert_strict_equal(len(files), 0)
def __call__(self, environ, start_response): if environ["REQUEST_METHOD"].upper() == "POST": environ["wsgi.input"] = stream = \ BytesIO(get_input_stream(environ).read()) formdata = parse_form_data(environ)[1] stream.seek(0) method = formdata.get('_method', '').upper() if method in ('GET', 'POST', 'PUT', 'DELETE'): environ['REQUEST_METHOD'] = method return self.app(environ, start_response)
def test_parse_form_data_get_without_content(self): """GET requests without data, content type and length returns no data""" env = create_environ('/foo', 'http://example.org/', method='GET') del env['CONTENT_TYPE'] del env['CONTENT_LENGTH'] stream, form, files = formparser.parse_form_data(env) self.assert_equal(stream.read(), '') self.assert_equal(len(form), 0) self.assert_equal(len(files), 0)
def test_parse_form_data_get_without_content(): """GET requests without data, content type and length returns no data""" env = create_environ('/foo', 'http://example.org/', method='GET') del env['CONTENT_TYPE'] del env['CONTENT_LENGTH'] stream, form, files = parse_form_data(env) assert stream.read() == "" assert len(form) == 0 assert len(files) == 0
def parse(self, context): """Parse the request content """ try: stream, form, files = parse_form_data(context.request.environ) return FormData(form, stream, files) except: # Failed to decode the content self.logger.error('Failed to decode request content') # Raise raise BadRequestError
def test_environ_builder_stream_switch(self): d = MultiDict(dict(foo=u'bar', blub=u'blah', hu=u'hum')) for use_tempfile in False, True: stream, length, boundary = stream_encode_multipart( d, use_tempfile, threshold=150) assert isinstance(stream, OutputType) != use_tempfile form = parse_form_data({'wsgi.input': stream, 'CONTENT_LENGTH': str(length), 'CONTENT_TYPE': 'multipart/form-data; boundary="%s"' % boundary})[1] assert form == d
def test_environ_builder_stream_switch(self): d = MultiDict(dict(foo=u'bar', blub=u'blah', hu=u'hum')) for use_tempfile in False, True: stream, length, boundary = stream_encode_multipart( d, use_tempfile, threshold=150) self.assert_true(isinstance(stream, BytesIO) != use_tempfile) form = parse_form_data({'wsgi.input': stream, 'CONTENT_LENGTH': str(length), 'CONTENT_TYPE': 'multipart/form-data; boundary="%s"' % boundary})[1] self.assert_strict_equal(form, d) stream.close()
def test_empty_multipart(self): environ = {} data = b'--boundary--' environ['REQUEST_METHOD'] = 'POST' environ['CONTENT_TYPE'] = 'multipart/form-data; boundary=boundary' environ['CONTENT_LENGTH'] = str(len(data)) environ['wsgi.input'] = BytesIO(data) stream, form, files = parse_form_data(environ, silent=False) rv = stream.read() assert rv == b'' assert form == MultiDict() assert files == MultiDict()
def __call__(self, environ, start_response): if environ['REQUEST_METHOD'].upper() == 'POST': environ['wsgi.input'] = stream = \ BytesIO(get_input_stream(environ).read()) formdata = parse_form_data(environ)[1] stream.seek(0) method = formdata.get('_method', '').upper() if method in ('GET', 'POST', 'PUT', 'DELETE'): environ['REQUEST_METHOD'] = method return self.app(environ, start_response)
def test_empty_multipart(self): environ = {} data = b"--boundary--" environ["REQUEST_METHOD"] = "POST" environ["CONTENT_TYPE"] = "multipart/form-data; boundary=boundary" environ["CONTENT_LENGTH"] = str(len(data)) environ["wsgi.input"] = io.BytesIO(data) stream, form, files = parse_form_data(environ, silent=False) rv = stream.read() assert rv == b"" assert form == MultiDict() assert files == MultiDict()
def demo2(environ, start_response): result = ['<title>Greeter</title>'] if environ['REQUEST_METHOD'] == 'POST': form = parse_form_data(environ)[1] result.append('<h1>what %s!</h1>' % escape(form['name'])) result.append(''' <form action="" method="post"> <p>Name: <input type="text" name="name" size="20"> <input type="submit" value="Greet me"> </form> ''') start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')]) return [''.join(result)]
def test_parse_form_data_put_without_content(self): # A PUT without a Content-Type header returns empty data # Both rfc1945 and rfc2616 (1.0 and 1.1) say "Any HTTP/[1.0/1.1] message # containing an entity-body SHOULD include a Content-Type header field # defining the media type of that body." In the case where either # headers are omitted, parse_form_data should still work. env = create_environ('/foo', 'http://example.org/', method='PUT') stream, form, files = formparser.parse_form_data(env) strict_eq(stream.read(), b'') strict_eq(len(form), 0) strict_eq(len(files), 0)
def parse_form_data(cls, self): if not self.body: return None, None, {} environ = { 'wsgi.input': io.BytesIO(self.body), 'CONTENT_LENGTH': len(self.body), 'CONTENT_TYPE': self.parsed_headers.get('content-type', ''), 'REQUEST_METHOD': 'POST', } stream, form, files = parse_form_data(environ, silent=False) for f in files.values(): f.name = f.filename return stream, form, files
def parse_form_data(cls, self): if not self.body: return None, None, {} environ = { 'wsgi.input': io.BytesIO(self.body), 'CONTENT_LENGTH': len(self.body), 'CONTENT_TYPE': self.headers.get('content-type', ''), 'REQUEST_METHOD': 'POST', } stream, form, files = parse_form_data(environ, silent=False) wrapped_files = { k: FileLike(_stream=f, name=f.filename) for k, f in files.items() } return stream, form, wrapped_files
def test_environ_builder_stream_switch(): d = MultiDict(dict(foo=u"bar", blub=u"blah", hu=u"hum")) for use_tempfile in False, True: stream, length, boundary = stream_encode_multipart(d, use_tempfile, threshold=150) assert isinstance(stream, BytesIO) != use_tempfile form = parse_form_data( { "wsgi.input": stream, "CONTENT_LENGTH": str(length), "CONTENT_TYPE": 'multipart/form-data; boundary="%s"' % boundary, } )[1] strict_eq(form, d) stream.close()
def test_parse_form_data_put_without_content(self): # A PUT without a Content-Type header returns empty data # Both rfc1945 and rfc2616 (1.0 and 1.1) say "Any HTTP/[1.0/1.1] message # containing an entity-body SHOULD include a Content-Type header field # defining the media type of that body." In the case where either # headers are omitted, parse_form_data should still work. env = create_environ("/foo", "http://example.org/", method="PUT") del env["CONTENT_TYPE"] del env["CONTENT_LENGTH"] stream, form, files = formparser.parse_form_data(env) self.assert_equal(stream.read(), "") self.assert_equal(len(form), 0) self.assert_equal(len(files), 0)
def low_hello_world(environ, start_response): result = ['<title>Greeter</title>'] if environ['REQUEST_METHOD'] == 'POST': form = parse_form_data(environ)[1] result.append('<h1>Hello %s!' % escape(form['name'])) result.append(''' <form action="" method="post"> Name: <input type="text" size="20" name="name"> <input type="submit"> </form> ''') start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')]) return [ ''.join([bytes(i) for i in result]) ] #TODO 中文提交 UnicodeEncodeError 原文[''.join(result)] AssertionError: applications must write bytes
def application(environ, start_response): from werkzeug.formparser import parse_form_data stream, form, file = parse_form_data(environ) inputData = file['file'].read() # Return body (with no exception) response_headers = [('Content-type', 'text/plain')] try: response_body = str(processFile(inputData) + "\n") status = "200 OK" except Exception as e: status = "400 Bad Request" response_body = str(e) + "\n" start_response(status, response_headers) return [response_body]
def test_parse_form_data_put_without_content(self): """A PUT without a Content-Type header returns empty data Both rfc1945 and rfc2616 (1.0 and 1.1) say "Any HTTP/[1.0/1.1] message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body." In the case where either headers are omitted, parse_form_data should still work. """ env = create_environ('/foo', 'http://example.org/', method='PUT') del env['CONTENT_TYPE'] del env['CONTENT_LENGTH'] stream, form, files = formparser.parse_form_data(env) self.assert_equal(stream.read(), '') self.assert_equal(len(form), 0) self.assert_equal(len(files), 0)
def __init__(self, environ: WSGIEnvironment) -> None: self.environ = environ method: str = environ.get("REQUEST_METHOD", "GET") args: MultiDict[str, Any] files: MultiDict[str, Any] if method in _GET_METHODS: qs: str = environ.get("QUERY_STRING", "") args = MultiDict(parse_qs(qs, keep_blank_values=True)) files = MultiDict() elif method in _FORM_METHODS: _, args, files = parse_form_data(environ) else: raise ValueError("unsupported method: '{}'".format(method)) self._arguments = _create_arg_dict(args, files) self._not_found = {a for a in self._arguments}
def test_parse_form_data_put_without_content(): """A PUT without a Content-Type header returns empty data Both rfc1945 and rfc2616 (1.0 and 1.1) say "Any HTTP/[1.0/1.1] message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body." In the case where either headers are omitted, parse_form_data should still work. """ env = create_environ('/foo', 'http://example.org/', method='PUT') del env['CONTENT_TYPE'] del env['CONTENT_LENGTH'] stream, form, files = parse_form_data(env) assert stream.read() == "" assert len(form) == 0 assert len(files) == 0
def __init__(self, environ): self.environ = environ self.host = environ.get('HTTP_HOST', 'localhost') self.path = environ.get('PATH_INFO', '/') self.method = environ.get('REQUEST_METHOD', 'GET') self.ssl = environ.get('HTTPS', False) is not False self.ip_address = environ.get('REMOTE_ADDR', None) self.accept_type = environ.get('HTTP_ACCEPT', '') self.content_type = environ.get('CONTENT_TYPE', '') self.want_json = 'application/json' in self.accept_type self.want_html = 'text/html' in self.accept_type if 'wsgi.input' in environ: stream, form, files = parse_form_data(environ) self.query = flatten_multidict(url_decode( environ.get('QUERY_STRING', ''))) self.form = flatten_multidict(form) self.files = flatten_multidict(files, lambda v: len(v.filename), FileStorage.from_original) else: stream = None self.query = dict() self.form = dict() self.files = dict() self.cookies = parse_cookie(environ) if 'application/json' in self.content_type and stream: try: self.json = json.loads(stream.read().decode('utf-8')) except ValueError: self.json = None else: self.json = None self.params = dict() self.params.update(self.query) self.params.update(self.form) self.params.update(self.files) if self.json: self.params.update(self.json)
async def _parse_form_data(self): if not self.is_form: msg = ( 'The request no form data, or missing form ' 'content-type header, eg: application/x-www-form-urlencoded') raise BadRequest(msg) if not self.body or self.method not in {'POST', 'PUT', 'PATCH'}: self._form = self._files = None return content = await self.content() environ = { 'wsgi.input': BytesIO(content), 'CONTENT_LENGTH': str(len(content)), 'CONTENT_TYPE': self.content_type, 'REQUEST_METHOD': self.method } __, self._form, self._files = parse_form_data(environ)
def test_environ_builder_stream_switch(): d = MultiDict(dict(foo="bar", blub="blah", hu="hum")) for use_tempfile in False, True: stream, length, boundary = stream_encode_multipart( d, use_tempfile, threshold=150 ) assert isinstance(stream, BytesIO) != use_tempfile form = parse_form_data( { "wsgi.input": stream, "CONTENT_LENGTH": str(length), "CONTENT_TYPE": f'multipart/form-data; boundary="{boundary}"', } )[1] assert form == d stream.close()
def get_urlencoded_body(self, data, header, method): # http://werkzeug.pocoo.org/docs/quickstart/#wsgi-environment environ = { "wsgi.input": StringIO(data), "CONTENT_LENGTH": str(len(data)), "CONTENT_TYPE": header, "REQUEST_METHOD": method, } stream, form, files = parse_form_data(environ) d = [] for k, v in form.iteritems(): o = {"key": k, "value": v, "type": "text"} d.append(o) return d
def file_arguments__umlauts(self) -> None: request = create_request("PUT", "/foo") request.add_argument('f"öo', "bär") request.add_file_argument( 'f"öle', b"", "text/plain", filename="ä\"'bc" ) environ = request.to_environment() assert_not_in("QUERY_STRING", environ) content_type, boundary = environ["CONTENT_TYPE"].split(";") assert_equal("multipart/form-data", content_type) _, args, files = parse_form_data(environ) assert_equal(1, len(args)) assert_equal(args["f%22%C3%B6o"], "bär") assert_equal(1, len(files)) file = files["f%22%C3%B6le"] assert_equal("text/plain", file.mimetype) assert_equal("ä\"'bc", file.filename) assert_equal(b"", file.stream.read())
def get_urlencoded_body(self, data, header, method): # http://werkzeug.pocoo.org/docs/quickstart/#wsgi-environment environ = { 'wsgi.input': StringIO(data), 'CONTENT_LENGTH': str(len(data)), 'CONTENT_TYPE': header, 'REQUEST_METHOD': method } stream, form, files = parse_form_data(environ) d = [] for k, v in form.iteritems(): o = {'key': k, 'value': v, 'type': 'text'} d.append(o) return d
def test_broken_multipart(): """Broken multipart does not break the applicaiton""" data = ( '--foo\r\n' 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n' 'Content-Transfer-Encoding: base64\r\n' 'Content-Type: text/plain\r\n\r\n' 'broken base 64' '--foo--' ) _, form, files = parse_form_data(create_environ(data=data, method='POST', content_type='multipart/form-data; boundary=foo')) assert not files assert not form assert_raises(ValueError, parse_form_data, create_environ(data=data, method='POST', content_type='multipart/form-data; boundary=foo'), silent=False)
def test_broken(self): data = ( '--foo\r\n' 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n' 'Content-Transfer-Encoding: base64\r\n' 'Content-Type: text/plain\r\n\r\n' 'broken base 64' '--foo--' ) _, form, files = formparser.parse_form_data(create_environ(data=data, method='POST', content_type='multipart/form-data; boundary=foo')) self.assert_(not files) self.assert_(not form) self.assert_raises(ValueError, formparser.parse_form_data, create_environ(data=data, method='POST', content_type='multipart/form-data; boundary=foo'), silent=False)
def test_broken(self): data = ( '--foo\r\n' 'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n' 'Content-Transfer-Encoding: base64\r\n' 'Content-Type: text/plain\r\n\r\n' 'broken base 64' '--foo--' ) _, form, files = formparser.parse_form_data(create_environ(data=data, method='POST', content_type='multipart/form-data; boundary=foo')) self.assert_true(not files) self.assert_true(not form) self.assert_raises(ValueError, formparser.parse_form_data, create_environ(data=data, method='POST', content_type='multipart/form-data; boundary=foo'), silent=False)
def test_environ_builder_unicode_file_mix(): for use_tempfile in False, True: f = FileStorage(BytesIO(u"\N{SNOWMAN}".encode("utf-8")), "snowman.txt") d = MultiDict(dict(f=f, s=u"\N{SNOWMAN}")) stream, length, boundary = stream_encode_multipart(d, use_tempfile, threshold=150) assert isinstance(stream, BytesIO) != use_tempfile _, form, files = parse_form_data( { "wsgi.input": stream, "CONTENT_LENGTH": str(length), "CONTENT_TYPE": 'multipart/form-data; boundary="%s"' % boundary, } ) strict_eq(form["s"], u"\N{SNOWMAN}") strict_eq(files["f"].name, "f") strict_eq(files["f"].filename, u"snowman.txt") strict_eq(files["f"].read(), u"\N{SNOWMAN}".encode("utf-8")) stream.close()
def test_environ_builder_unicode_file_mix(self): for use_tempfile in False, True: f = FileStorage(BytesIO(u'\N{SNOWMAN}'.encode('utf-8')), 'snowman.txt') d = MultiDict(dict(f=f, s=u'\N{SNOWMAN}')) stream, length, boundary = stream_encode_multipart( d, use_tempfile, threshold=150) self.assert_true(isinstance(stream, BytesIO) != use_tempfile) _, form, files = parse_form_data({ 'wsgi.input': stream, 'CONTENT_LENGTH': str(length), 'CONTENT_TYPE': 'multipart/form-data; boundary="%s"' % boundary }) self.assert_strict_equal(form['s'], u'\N{SNOWMAN}') self.assert_strict_equal(files['f'].name, 'f') self.assert_strict_equal(files['f'].filename, u'snowman.txt') self.assert_strict_equal(files['f'].read(), u'\N{SNOWMAN}'.encode('utf-8')) stream.close()
def _load_form_data(self): if 'stream' in self.__dict__: return if self.shallow: raise RuntimeError('A shallow request tried to consume form data. If you really want to do that, set `shallow` to False.') data = None stream = _empty_stream if self.environ['REQUEST_METHOD'] in ('POST', 'PUT'): try: data = parse_form_data(self.environ, self._get_file_stream, self.charset, self.encoding_errors, self.max_form_memory_size, self.max_content_length, cls=self.parameter_storage_class, silent=False) except ValueError as e: self._form_parsing_failed(e) else: content_length = self.headers.get('content-length', type=int) if content_length is not None: stream = LimitedStream(self.environ['wsgi.input'], content_length) if data is None: data = (stream, self.parameter_storage_class(), self.parameter_storage_class()) d = self.__dict__ d['stream'], d['form'], d['files'] = data
def generate_formdata(req, resp, params): """sets params['form'], params['files'], params['stream'] to pass to every endpoint. """ if req.method != 'GET': mimetype, options = parse_options_header(req.get_header('content-type')) data = req.stream.read() environ = {'wsgi.input': StringIO(data), 'CONTENT_LENGTH': str(len(data)), 'CONTENT_TYPE': '%s; boundary=%s' % (mimetype, options['boundary']), 'REQUEST_METHOD': 'POST'} stream, form, files = parse_form_data(environ) params['stream'], params['form'], params['files'] = stream, dict(form),\ dict(files) return True else: di = urlparse.parse_qsl(req.query_string) params['form'] = dict(di) params['stream'] = LimitedStream() params['files'] = dict() return True
def get_urlencoded_body(self, data, header, method): # http://werkzeug.pocoo.org/docs/quickstart/#wsgi-environment environ = { 'wsgi.input': StringIO(data), 'CONTENT_LENGTH': str(len(data)), 'CONTENT_TYPE': header, 'REQUEST_METHOD': method } stream, form, files = parse_form_data(environ) d = [] for k, v in form.iteritems(): o = { 'key': k, 'value': v, 'type': 'text' } d.append(o) return d