Example #1
0
 def _parse_uri(self):
     """Parse the request URI."""
     uri = self.m_iface.uri()
     docroot = self.m_iface.options()['documentroot']
     protocol, host, path, args = urilib.parse_uri(uri)
     directory, filename, pathinfo = urilib.resolve_path_uri(path, docroot)
     self.m_docroot = docroot
     self.m_directory = directory
     self.m_filename = filename
     self.m_pathinfo = [ pi for pi in pathinfo.split('/') if pi ]
     self.m_args = {}
     args = urilib.parse_query(args)
     self._add_args(args)
     if self.m_iface.method() == 'POST':
         ctype = self.header('content-type')
         if ctype is not None:
             value, options = http.parse_header_options(ctype)
             if value in ('application/x-www-form-urlencoded',
                          'multipart/form-data'):
                 args = http.parse_post(self.headers(), self)
                 self._add_args(args)
     self.m_basename, self.m_extension = os.path.splitext(self.filename())
     self.m_extension = self.m_extension[1:]
Example #2
0
def parse_post(headers, input):
    """Parse POST style query string.

    The `headers' arguments must be a dictionary of HTTP headers,
    `input' must be a file-like object with read() and readline()
    methods.

    Exceptions: HTTPError
    """
    try:
        ctype = headers['content-type'][0]
    except KeyError:
        type = 'application/x-www-form-urlencoded'
    try:
        clen = int(headers['content-length'][0])
    except (KeyError, ValueError):
        raise HTTPError, HTTP_LENGTH_REQUIRED
    ctype, options = parse_header_options(ctype)

    # Traditional POST requests
    if ctype == 'application/x-www-form-urlencoded':
        data = input.read(clen)
        args = parse_query(data)
        return args

    # Newer POST requests with support for file uploads
    elif ctype.startswith('multipart/'):
        try:
            boundary = options['boundary'][0]
        except KeyError:
            raise HTTPError, HTTP_BAD_REQUEST
        boundary = '--' + boundary
        skip_until_boundary(input, boundary)

        args = {}
        while True:
            subheaders = parse_headers(input)
            try:
                cdisp = subheaders['content-disposition'][0]
            except KeyError:
                raise HTTPError, HTTP_BAD_REQUEST
            cdisp, dispoptions = parse_header_options(cdisp)
            try:
                name = dispoptions['name'][0]
            except KeyError:
                raise HTTPError, HTTP_BAD_REQUEST
            try:
                filename = dispoptions['filename'][0]
            except KeyError:
                filename = None
            if filename:
                output = tempfile.TemporaryFile()
            else:
                output = cStringIO.StringIO()
            atend = read_until_boundary(input, output, boundary)
            if filename:
                output.seek(0)
                try:
                    subctype = subheaders['content-type'][0]
                except KeyError:
                    raise HTTPError, HTTP_BAD_REQUEST
                value = FileUpload(name, output, subctype, filename)
            else:
                value = output.getvalue().decode('utf-8')
            if name in args:
                args[name].append(value)
            else:
                args[name] = [value]
            if atend:
                break
        return args

    else:
        raise HTTPError, HTTP_BAD_REQUEST
Example #3
0
 def test_parse_query(self):
     for query,args in self.data:
         assert urimod.parse_query(query) == args