Merge branch 'master' into python3
authorFredrik Tolf <fredrik@dolda2000.com>
Thu, 3 Apr 2014 03:33:34 +0000 (05:33 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Thu, 3 Apr 2014 03:33:34 +0000 (05:33 +0200)
Conflicts:
wrw/form.py

1  2 
wrw/form.py

diff --combined wrw/form.py
@@@ -1,41 -1,17 +1,17 @@@
- import cgi
 -import urlparse
 -import proto
++import urllib.parse
 +from . import proto
  
  __all__ = ["formdata"]
  
- class formwrap(object):
-     def __init__(self, req):
-         if req.ihead.get("Content-Type") == "application/x-www-form-urlencoded":
-             self.cf = cgi.parse(environ = req.env, fp = req.input)
-         else:
-             self.cf = cgi.parse(environ = req.env)
-     def __getitem__(self, key):
-         return self.cf[key][0]
-     def get(self, key, default=""):
-         if key in self:
-             return self.cf[key][0]
-         return default
-     def __contains__(self, key):
-         return key in self.cf and len(self.cf[key]) > 0
-     def __iter__(self):
-         return iter(self.cf)
-     def items(self):
-         def iter():
-             for key, list in self.cf.items():
-                 for val in list:
-                     yield key, val
-         return list(iter())
-     def keys(self):
-         return list(self.cf.keys())
-     def values(self):
-         return [val for key, val in self.items()]
+ def formparse(req):
+     buf = {}
 -    buf.update(urlparse.parse_qsl(req.query))
++    buf.update(urllib.parse.parse_qsl(req.query))
+     if req.ihead.get("Content-Type") == "application/x-www-form-urlencoded":
+         if req.input.limit > 2 ** 20:
+             raise ValueError("x-www-form-urlencoded data is absurdly long")
+         rbody = req.input.read()
 -        buf.update(urlparse.parse_qsl(rbody))
++        buf.update(urllib.parse.parse_qsl(rbody))
+     return buf
  
  class badmultipart(Exception):
      pass
@@@ -43,7 -19,7 +19,7 @@@
  class formpart(object):
      def __init__(self, form):
          self.form = form
 -        self.buf = ""
 +        self.buf = b""
          self.eof = False
          self.head = {}
  
@@@ -52,8 -28,8 +28,8 @@@
  
      def fillbuf(self, sz):
          req = self.form.req
 -        mboundary = "\r\n--" + self.form.boundary + "\r\n"
 -        lboundary = "\r\n--" + self.form.boundary + "--\r\n"
 +        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:
@@@ -91,7 -67,7 +67,7 @@@
      def readline(self, limit=-1):
          last = 0
          while True:
 -            p = self.buf.find('\n', last)
 +            p = self.buf.find(b'\n', last)
              if p < 0:
                  if self.eof:
                      ret = self.buf
          self.close()
          return False
  
 -    def parsehead(self):
 +    def parsehead(self, charset):
          def headline():
              ln = self.readline(256)
 -            if ln[-1] != '\n':
 +            if ln[-1] != ord(b'\n'):
                  raise badmultipart("Too long header line in part")
 -            return ln.rstrip()
 +            try:
 +                return ln.decode(charset).rstrip()
 +            except UnicodeError:
 +                raise badmultipart("Form part header is not in assumed charset")
  
          ln = headline()
          while True:
              raise badmultipart("Form part uses unexpected transfer encoding: %r" % encoding)
  
  class multipart(object):
 -    def __init__(self, req):
 +    def __init__(self, req, charset):
          val, par = proto.pmimehead(req.ihead.get("Content-Type", ""))
          if req.method != "POST" or val != "multipart/form-data":
              raise badmultipart("Request is not a multipart form")
          if "boundary" not in par:
              raise badmultipart("Multipart form lacks boundary")
 -        self.boundary = par["boundary"]
 +        try:
 +            self.boundary = par["boundary"].encode("us-ascii")
 +        except UnicodeError:
 +            raise badmultipart("Multipart boundary must be ASCII string")
          self.req = req
 -        self.buf = "\r\n"
 +        self.buf = b"\r\n"
          self.eof = False
 +        self.headcs = charset
          self.lastpart = formpart(self)
          self.lastpart.close()
  
      def __iter__(self):
          return self
  
 -    def next(self):
 +    def __next__(self):
          if not self.lastpart.eof:
              raise RuntimeError("All form parts must be read entirely")
          if self.eof:
              raise StopIteration()
          self.lastpart = formpart(self)
 -        self.lastpart.parsehead()
 +        self.lastpart.parsehead(self.headcs)
          return self.lastpart
  
  def formdata(req):
-     return req.item(formwrap)
+     return req.item(formparse)