Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using email module to parse multipart insteal of the deprecated cgi module #1437

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 47 additions & 14 deletions bottle.py
Expand Up @@ -69,7 +69,7 @@ def _cli_patch(cli_args): # pragma: no coverage
# Imports and Python 2/3 unification ##########################################
###############################################################################

import base64, calendar, cgi, email.utils, functools, hmac, itertools,\
import base64, calendar, email.utils, functools, hmac, itertools,\
mimetypes, os, re, tempfile, threading, time, warnings, weakref, hashlib

from types import FunctionType
Expand Down Expand Up @@ -1389,23 +1389,56 @@ def POST(self):
post[key] = value
return post

safe_env = {'QUERY_STRING': ''} # Build a safe environment for cgi
for key in ('REQUEST_METHOD', 'CONTENT_TYPE', 'CONTENT_LENGTH'):
if key in self.environ: safe_env[key] = self.environ[key]
args = dict(fp=self.body, environ=safe_env, keep_blank_values=True)
try:
import cgi

safe_env = {'QUERY_STRING': ''} # Build a safe environment for cgi
for key in ('REQUEST_METHOD', 'CONTENT_TYPE', 'CONTENT_LENGTH'):
if key in self.environ: safe_env[key] = self.environ[key]
args = dict(fp=self.body, environ=safe_env, keep_blank_values=True)

if py3k:
args['encoding'] = 'utf8'
post.recode_unicode = False
data = cgi.FieldStorage(**args)
self['_cgi.FieldStorage'] = data #http://bugs.python.org/issue18394
data = data.list or []
for item in data:
if item.filename is None:
post[item.name] = item.value
else:
post[item.name] = FileUpload(item.file, item.name,
item.filename, item.headers)
return post
except ImportError:
pass


import email.parser, io

parser = email.parser.FeedParser()
for key in ('Content-Type', 'Content-Length'):
k = key.upper().replace('-', '_')
if k not in self.environ:
continue
parser.feed("{}: {}\r\n".format(key, self.environ[k]))
parser.feed('\r\n')
parser.feed(self.body.getvalue().decode())
msg = parser.close()
if py3k:
args['encoding'] = 'utf8'
post.recode_unicode = False
data = cgi.FieldStorage(**args)
self['_cgi.FieldStorage'] = data #http://bugs.python.org/issue18394
data = data.list or []
for item in data:
if item.filename is None:
post[item.name] = item.value
for item in list(msg.walk())[1:]: # skip the multipart it self
filename = item.get_filename()
name = item.get_param('name', header='content-disposition')
if filename is None:
post[name] = item.get_payload()
else:
post[item.name] = FileUpload(item.file, item.name,
item.filename, item.headers)
headers = HeaderDict()
for k, v in item.items():
headers[k] = v
f = io.BytesIO(item.get_payload().encode())
post[name] = FileUpload(f, item.get('name'), filename,
headers)
return post

@property
Expand Down