def parse_uri(uri, parse_query=True): scheme, authority, path = parse_request_uri(uri) if path is None: raise HTTPSimpleResponse(http_client.BAD_REQUEST, "No path component") if b'#' in path: raise HTTPSimpleResponse(http_client.BAD_REQUEST, "Illegal #fragment in Request-URI.") if scheme: try: scheme = scheme.decode('ascii') except ValueError: raise HTTPSimpleResponse(http_client.BAD_REQUEST, 'Un-decodeable scheme') path, qs = path.partition(b'?')[::2] if parse_query: try: query = MultiDict.create_from_query_string(qs) except Exception: raise HTTPSimpleResponse(http_client.BAD_REQUEST, 'Unparseable query string') else: query = None try: path = '%2F'.join( unquote(x).decode('utf-8') for x in quoted_slash.split(path)) except ValueError as e: raise HTTPSimpleResponse(http_client.BAD_REQUEST, as_unicode(e)) path = tuple(filter(None, (x.replace('%2F', '/') for x in path.split('/')))) return scheme, path, query
def parse_uri(uri, parse_query=True): scheme, authority, path = parse_request_uri(uri) if b'#' in path: raise HTTPSimpleResponse(httplib.BAD_REQUEST, "Illegal #fragment in Request-URI.") if scheme: try: scheme = scheme.decode('ascii') except ValueError: raise HTTPSimpleResponse(httplib.BAD_REQUEST, 'Un-decodeable scheme') path, qs = path.partition(b'?')[::2] if parse_query: try: query = MultiDict.create_from_query_string(qs) except Exception: raise HTTPSimpleResponse(httplib.BAD_REQUEST, 'Unparseable query string') else: query = None try: path = '%2F'.join(unquote(x).decode('utf-8') for x in quoted_slash.split(path)) except ValueError as e: raise HTTPSimpleResponse(httplib.BAD_REQUEST, as_unicode(e)) path = tuple(filter(None, (x.replace('%2F', '/') for x in path.split('/')))) return scheme, path, query
def parse_request_line(self, buf, event, first=False): # {{{ line = self.readline(buf) if line is None: return if line == b'\r\n': # Ignore a single leading empty line, as per RFC 2616 sec 4.1 if first: return self.set_state(READ, self.parse_request_line, Accumulator()) return self.simple_response(httplib.BAD_REQUEST, 'Multiple leading empty lines not allowed') try: method, uri, req_protocol = line.strip().split(b' ', 2) rp = int(req_protocol[5]), int(req_protocol[7]) self.method = method.decode('ascii').upper() except Exception: return self.simple_response(httplib.BAD_REQUEST, "Malformed Request-Line") if self.method not in HTTP_METHODS: return self.simple_response(httplib.BAD_REQUEST, "Unknown HTTP method") try: self.request_protocol = protocol_map[rp] except KeyError: return self.simple_response(httplib.HTTP_VERSION_NOT_SUPPORTED) self.response_protocol = protocol_map[min((1, 1), rp)] scheme, authority, path = parse_request_uri(uri) if b'#' in path: return self.simple_response(httplib.BAD_REQUEST, "Illegal #fragment in Request-URI.") if scheme: try: self.scheme = scheme.decode('ascii') except ValueError: return self.simple_response(httplib.BAD_REQUEST, 'Un-decodeable scheme') qs = b'' if b'?' in path: path, qs = path.split(b'?', 1) try: self.query = MultiDict.create_from_query_string(qs) except Exception: return self.simple_response(httplib.BAD_REQUEST, 'Unparseable query string') try: path = '%2F'.join(unquote(x).decode('utf-8') for x in quoted_slash.split(path)) except ValueError as e: return self.simple_response(httplib.BAD_REQUEST, as_unicode(e)) self.path = tuple(filter(None, (x.replace('%2F', '/') for x in path.split('/')))) self.header_line_too_long_error_code = httplib.REQUEST_ENTITY_TOO_LARGE self.request_line = line.rstrip() self.set_state(READ, self.parse_header_line, HTTPHeaderParser(), Accumulator())
def parse_request_line(self, buf, event, first=False): # {{{ line = self.readline(buf) if line is None: return if line == b'\r\n': # Ignore a single leading empty line, as per RFC 2616 sec 4.1 if first: return self.set_state(READ, self.parse_request_line, Accumulator()) return self.simple_response( httplib.BAD_REQUEST, 'Multiple leading empty lines not allowed') try: method, uri, req_protocol = line.strip().split(b' ', 2) rp = int(req_protocol[5]), int(req_protocol[7]) self.method = method.decode('ascii').upper() except Exception: return self.simple_response(httplib.BAD_REQUEST, "Malformed Request-Line") if self.method not in HTTP_METHODS: return self.simple_response(httplib.BAD_REQUEST, "Unknown HTTP method") try: self.request_protocol = protocol_map[rp] except KeyError: return self.simple_response(httplib.HTTP_VERSION_NOT_SUPPORTED) self.response_protocol = protocol_map[min((1, 1), rp)] scheme, authority, path = parse_request_uri(uri) if b'#' in path: return self.simple_response(httplib.BAD_REQUEST, "Illegal #fragment in Request-URI.") if scheme: try: self.scheme = scheme.decode('ascii') except ValueError: return self.simple_response(httplib.BAD_REQUEST, 'Un-decodeable scheme') qs = b'' if b'?' in path: path, qs = path.split(b'?', 1) try: self.query = MultiDict.create_from_query_string(qs) except Exception: return self.simple_response(httplib.BAD_REQUEST, 'Unparseable query string') try: path = '%2F'.join( unquote(x).decode('utf-8') for x in quoted_slash.split(path)) except ValueError as e: return self.simple_response(httplib.BAD_REQUEST, as_unicode(e)) self.path = tuple( filter(None, (x.replace('%2F', '/') for x in path.split('/')))) self.header_line_too_long_error_code = httplib.REQUEST_ENTITY_TOO_LARGE self.request_line = line.rstrip() self.set_state(READ, self.parse_header_line, HTTPHeaderParser(), Accumulator())
def read_request_line(self): request_line = self.conn.socket_file.readline(maxsize=self.max_header_line_size) # Set started_request to True so http_communicate() knows to send 408 # from here on out. self.started_request = True if not request_line: return False if request_line == b'\r\n': # RFC 2616 sec 4.1: "...if the server is reading the protocol # stream at the beginning of a message and receives a CRLF # first, it should ignore the CRLF." # But only ignore one leading line! else we enable a DoS. request_line = self.conn.socket_file.readline(maxsize=self.max_header_line_size) if not request_line: return False if not request_line.endswith(b'\r\n'): self.simple_response( httplib.BAD_REQUEST, "HTTP requires CRLF terminators") return False self.request_line = request_line try: method, uri, req_protocol = request_line.strip().split(b' ', 2) rp = int(req_protocol[5]), int(req_protocol[7]) self.method = method.decode('ascii') except (ValueError, IndexError): self.simple_response(httplib.BAD_REQUEST, "Malformed Request-Line") return False try: self.request_protocol = protocol_map[rp] except KeyError: self.simple_response(httplib.HTTP_VERSION_NOT_SUPPORTED) return False scheme, authority, path = parse_request_uri(uri) if b'#' in path: self.simple_response(httplib.BAD_REQUEST, "Illegal #fragment in Request-URI.") return False if scheme: try: self.scheme = scheme.decode('ascii') except ValueError: self.simple_response(httplib.BAD_REQUEST, 'Un-decodeable scheme') return False qs = b'' if b'?' in path: path, qs = path.split(b'?', 1) try: self.qs = MultiDict.create_from_query_string(qs) except Exception: self.simple_response(httplib.BAD_REQUEST, "Malformed Request-Line", 'Unparseable query string') return False try: path = '%2F'.join(unquote(x).decode('utf-8') for x in quoted_slash.split(path)) except ValueError as e: self.simple_response(httplib.BAD_REQUEST, as_unicode(e)) return False self.path = tuple(x.replace('%2F', '/') for x in path.split('/')) self.response_protocol = protocol_map[min((1, 1), rp)] return True