+def formparse(req):
+ buf = {}
+ buf.update(urllib.parse.parse_qsl(req.query, keep_blank_values=True))
+ ctype, ctpars = proto.pmimehead(req.ihead.get("Content-Type", ""))
+ limit = 2 ** 20
+ if ctype == "application/x-www-form-urlencoded":
+ try:
+ rbody = req.input.read(limit)
+ except IOError as exc:
+ return exc
+ if len(rbody) >= limit:
+ return IOError("x-www-form-urlencoded data is absurdly long")
+ buf.update(urllib.parse.parse_qsl(rbody.decode("latin1"), encoding=getcharset(ctpars.get("charset", ""), "utf-8"), keep_blank_values=True))
+ elif ctype == "multipart/form-data":
+ tlen = 0
+ for part in multipart(req):
+ with part:
+ left = limit - tlen
+ pbody = part.read(left)
+ if len(pbody) >= left:
+ raise IOError("multipart/form-data body is absurdly long")
+ tlen += len(pbody)
+ buf[part.name] = trydecode(pbody, part.form.bodycs)
+ return buf
+