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:]
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
def test_parse_query(self): for query,args in self.data: assert urimod.parse_query(query) == args