Ejemplo n.º 1
0
    def _parse_arg_list(self):
        """Parse the supplied request parameters into a list of
        `(name, value)` tuples.
        """
        fp = self.environ['wsgi.input']

        # Avoid letting cgi.FieldStorage consume the input stream when the
        # request does not contain form data
        ctype = self.get_header('Content-Type')
        if ctype:
            ctype, options = cgi.parse_header(ctype)
        if ctype not in ('application/x-www-form-urlencoded',
                         'multipart/form-data'):
            fp = StringIO('')

        # Python 2.6 introduced a backwards incompatible change for
        # FieldStorage where QUERY_STRING is no longer ignored for POST
        # requests. We'll keep the pre 2.6 behaviour for now...
        if self.method == 'POST':
            qs_on_post = self.environ.pop('QUERY_STRING', '')
        try:
            fs = _FieldStorage(fp,
                               environ=self.environ,
                               keep_blank_values=True)
        except IOError as e:
            if is_client_disconnect_exception(e):
                raise HTTPBadRequest(
                    _("Exception caught while reading request: %(msg)s",
                      msg=exception_to_unicode(e)))
            raise
        if self.method == 'POST':
            self.environ['QUERY_STRING'] = qs_on_post

        def raise_if_null_bytes(value):
            if value and '\x00' in value:
                raise HTTPBadRequest(_("Invalid request arguments."))

        args = []
        for value in fs.list or ():
            name = value.name
            raise_if_null_bytes(name)
            try:
                if name is not None:
                    name = unicode(name, 'utf-8')
                if value.filename:
                    raise_if_null_bytes(value.filename)
                else:
                    value = value.value
                    raise_if_null_bytes(value)
                    value = unicode(value, 'utf-8')
            except UnicodeDecodeError as e:
                raise HTTPBadRequest(
                    _("Invalid encoding in form data: %(msg)s",
                      msg=exception_to_unicode(e)))
            args.append((name, value))
        return args
Ejemplo n.º 2
0
 def _is_client_disconnected(self, e):
     if is_client_disconnect_exception(e):
         return True
     # Note that mod_wsgi raises an IOError with only a message
     # if the client disconnects
     if 'mod_wsgi.version' in self.environ:
         return e.args[0] in ('failed to write data',
                              'client connection closed',
                              'request data read error')
     return False
Ejemplo n.º 3
0
    def write(self, data):
        """Write the given data to the response body.

        *data* **must** be a `str` string or an iterable instance
        which iterates `str` strings, encoded with the charset which
        has been specified in the ``'Content-Type'`` header or UTF-8
        otherwise.

        Note that when the ``'Content-Length'`` header is specified,
        its value either corresponds to the length of *data*, or, if
        there are multiple calls to `write`, to the cumulative length
        of the *data* arguments.
        """
        if not self._write:
            self.end_headers()
        try:
            chunk_size = self.CHUNK_SIZE
            bufsize = 0
            buf = []
            buf_append = buf.append
            if isinstance(data, basestring):
                data = [data]
            for chunk in data:
                if isinstance(chunk, unicode):
                    raise ValueError("Can't send unicode content")
                if not chunk:
                    continue
                bufsize += len(chunk)
                buf_append(chunk)
                if bufsize >= chunk_size:
                    self._write(''.join(buf))
                    bufsize = 0
                    buf[:] = ()
            if bufsize > 0:
                self._write(''.join(buf))
        except IOError as e:
            if is_client_disconnect_exception(e):
                raise RequestDone
            raise