+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", ""))
+ if ctype == "application/x-www-form-urlencoded":
+ try:
+ rbody = req.input.read(2 ** 20)
+ except IOError as exc:
+ return exc
+ if len(rbody) >= 2 ** 20:
+ return ValueError("x-www-form-urlencoded data is absurdly long")
+ buf.update(urllib.parse.parse_qsl(rbody.decode("latin1"), encoding=ctpars.get("charset", "utf-8"), keep_blank_values=True))
+ return buf
+
+class badmultipart(IOError):
+ pass
+
+class formpart(object):
+ def __init__(self, form):
+ self.form = form
+ self.buf = b""
+ self.eof = False
+ self.head = {}
+
+ def parsehead(self):
+ pass
+
+ def fillbuf(self, sz):
+ req = self.form.req
+ mboundary = b"\r\n--" + self.form.boundary + b"\r\n"
+ lboundary = b"\r\n--" + self.form.boundary + b"--\r\n"
+ while not self.eof:
+ p = self.form.buf.find(mboundary)
+ if p >= 0:
+ self.buf += self.form.buf[:p]
+ self.form.buf = self.form.buf[p + len(mboundary):]
+ self.eof = True
+ break
+ p = self.form.buf.find(lboundary)
+ if p >= 0:
+ self.buf += self.form.buf[:p]
+ self.form.buf = self.form.buf[p + len(lboundary):]
+ self.eof = True
+ self.form.eof = True
+ break
+ self.buf += self.form.buf[:-len(lboundary)]
+ self.form.buf = self.form.buf[-len(lboundary):]
+ if sz >= 0 and len(self.buf) >= sz:
+ break
+ while len(self.form.buf) <= len(lboundary):
+ ret = req.input.read(8192)
+ if ret == b"":
+ raise badmultipart("Missing last multipart boundary")
+ self.form.buf += ret
+
+ def read(self, limit=-1):
+ self.fillbuf(limit)
+ if limit >= 0:
+ ret = self.buf[:limit]
+ self.buf = self.buf[limit:]