Ejemplo n.º 1
0
def parse(server_spec: str) -> ServerSpec:
    """
    Parses a server mode specification, e.g.:

        - http://example.com/
        - example.org
        - example.com:443

    Raises:
        ValueError, if the server specification is invalid.
    """
    m = server_spec_re.match(server_spec)
    if not m:
        raise ValueError(f"Invalid server specification: {server_spec}")

    # defaulting to https/port 443 may annoy some folks, but it's secure-by-default.
    scheme = m.group("scheme") or "https"
    if scheme not in ("http", "https"):
        raise ValueError(f"Invalid server scheme: {scheme}")

    host = m.group("host")
    # IPv6 brackets
    if host.startswith("[") and host.endswith("]"):
        host = host[1:-1]
    if not check.is_valid_host(host.encode("idna")):
        raise ValueError(f"Invalid hostname: {host}")

    if m.group("port"):
        port = int(m.group("port"))
    else:
        port = {"http": 80, "https": 443}[scheme]
    if not check.is_valid_port(port):
        raise ValueError(f"Invalid port: {port}")

    return ServerSpec(scheme, (host, port))
Ejemplo n.º 2
0
def parse_authority(authority: AnyStr, check: bool) -> Tuple[str, Optional[int]]:
    """Extract the host and port from host header/authority information

    Raises:
        ValueError, if check is True and the authority information is malformed.
    """
    try:
        if isinstance(authority, bytes):
            authority_str = authority.decode("idna")
        else:
            authority_str = authority
        m = _authority_re.match(authority_str)
        if not m:
            raise ValueError

        host = m.group("host")
        if host.startswith("[") and host.endswith("]"):
            host = host[1:-1]
        if not is_valid_host(host):
            raise ValueError

        if m.group("port"):
            port = int(m.group("port"))
            if not is_valid_port(port):
                raise ValueError
            return host, port
        else:
            return host, None

    except ValueError:
        if check:
            raise
        else:
            return always_str(authority, "utf-8", "surrogateescape"), None
Ejemplo n.º 3
0
def parse(url):
    """
        URL-parsing function that checks that
            - port is an integer 0-65535
            - host is a valid IDNA-encoded hostname with no null-bytes
            - path is valid ASCII

        Args:
            A URL (as bytes or as unicode)

        Returns:
            A (scheme, host, port, path) tuple

        Raises:
            ValueError, if the URL is not properly formatted.
    """
    parsed = urllib.parse.urlparse(url)

    if not parsed.hostname:
        raise ValueError("No hostname given")

    if isinstance(url, bytes):
        host = parsed.hostname

        # this should not raise a ValueError,
        # but we try to be very forgiving here and accept just everything.
        # decode_parse_result(parsed, "ascii")
    else:
        host = parsed.hostname.encode("idna")
        parsed = encode_parse_result(parsed, "ascii")

    port = parsed.port
    if not port:
        port = 443 if parsed.scheme == b"https" else 80

    full_path = urllib.parse.urlunparse(
        (b"", b"", parsed.path, parsed.params, parsed.query, parsed.fragment)
    )
    if not full_path.startswith(b"/"):
        full_path = b"/" + full_path

    if not check.is_valid_host(host):
        raise ValueError("Invalid Host")
    if not check.is_valid_port(port):
        raise ValueError("Invalid Port")

    return parsed.scheme, host, port, full_path
Ejemplo n.º 4
0
def parse(url):
    """
        URL-parsing function that checks that
            - port is an integer 0-65535
            - host is a valid IDNA-encoded hostname with no null-bytes
            - path is valid ASCII

        Args:
            A URL (as bytes or as unicode)

        Returns:
            A (scheme, host, port, path) tuple

        Raises:
            ValueError, if the URL is not properly formatted.
    """
    parsed = urllib.parse.urlparse(url)

    if not parsed.hostname:
        raise ValueError("No hostname given")

    if isinstance(url, bytes):
        host = parsed.hostname

        # this should not raise a ValueError,
        # but we try to be very forgiving here and accept just everything.
        # decode_parse_result(parsed, "ascii")
    else:
        host = parsed.hostname.encode("idna")
        parsed = encode_parse_result(parsed, "ascii")

    port = parsed.port
    if not port:
        port = 443 if parsed.scheme == b"https" else 80

    full_path = urllib.parse.urlunparse(
        (b"", b"", parsed.path, parsed.params, parsed.query, parsed.fragment)
    )
    if not full_path.startswith(b"/"):
        full_path = b"/" + full_path

    if not check.is_valid_host(host):
        raise ValueError("Invalid Host")
    if not check.is_valid_port(port):
        raise ValueError("Invalid Port")

    return parsed.scheme, host, port, full_path
Ejemplo n.º 5
0
def _parse_authority_form(hostport):
    """
        Returns (host, port) if hostport is a valid authority-form host specification.
        http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 section 3.1

        Raises:
            ValueError, if the input is malformed
    """
    try:
        host, port = hostport.split(b":")
        port = int(port)
        if not check.is_valid_host(host) or not check.is_valid_port(port):
            raise ValueError()
    except ValueError:
        raise exceptions.HttpSyntaxException("Invalid host specification: {}".format(hostport))

    return host, port
Ejemplo n.º 6
0
def _parse_authority_form(hostport):
    """
        Returns (host, port) if hostport is a valid authority-form host specification.
        http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 section 3.1

        Raises:
            ValueError, if the input is malformed
    """
    try:
        host, port = hostport.split(b":")
        port = int(port)
        if not check.is_valid_host(host) or not check.is_valid_port(port):
            raise ValueError()
    except ValueError:
        raise exceptions.HttpSyntaxException(
            "Invalid host specification: {}".format(hostport))

    return host, port
Ejemplo n.º 7
0
def parse(server_spec: str) -> ServerSpec:
    """
    Parses a server mode specification, e.g.:

        - http://example.com/
        - example.org
        - example.com:443

    Raises:
        ValueError, if the server specification is invalid.
    """
    m = server_spec_re.match(server_spec)
    if not m:
        raise ValueError(f"Invalid server specification: {server_spec}")

    if m.group("scheme"):
        scheme = m.group("scheme")
    else:
        scheme = "https" if m.group("port") in ("443", None) else "http"
    if scheme not in ("http", "https"):
        raise ValueError(f"Invalid server scheme: {scheme}")

    host = m.group("host")
    # IPv6 brackets
    if host.startswith("[") and host.endswith("]"):
        host = host[1:-1]
    if not check.is_valid_host(host):
        raise ValueError(f"Invalid hostname: {host}")

    if m.group("port"):
        port = int(m.group("port"))
    else:
        port = {
            "http": 80,
            "https": 443
        }[scheme]
    if not check.is_valid_port(port):
        raise ValueError(f"Invalid port: {port}")

    return ServerSpec(scheme, (host, port))  # type: ignore
Ejemplo n.º 8
0
def parse(server_spec: str) -> ServerSpec:
    """
    Parses a server mode specification, e.g.:

        - http://example.com/
        - example.org
        - example.com:443

    Raises:
        ValueError, if the server specification is invalid.
    """
    m = server_spec_re.match(server_spec)
    if not m:
        raise ValueError("Invalid server specification: {}".format(server_spec))

    # defaulting to https/port 443 may annoy some folks, but it's secure-by-default.
    scheme = m.group("scheme") or "https"
    if scheme not in ("http", "https"):
        raise ValueError("Invalid server scheme: {}".format(scheme))

    host = m.group("host")
    # IPv6 brackets
    if host.startswith("[") and host.endswith("]"):
        host = host[1:-1]
    if not check.is_valid_host(host.encode("idna")):
        raise ValueError("Invalid hostname: {}".format(host))

    if m.group("port"):
        port = int(m.group("port"))
    else:
        port = {
            "http": 80,
            "https": 443
        }[scheme]
    if not check.is_valid_port(port):
        raise ValueError("Invalid port: {}".format(port))

    return ServerSpec(scheme, (host, port))
Ejemplo n.º 9
0
def _load_webpack_config() -> WebpackConfig:
	log.debug(f'Getting config from webpack config using {GET_CONFIG_SCRIPT_PATH}.')
	proc = run(['node', GET_CONFIG_SCRIPT_PATH], stdout=PIPE)
	log.debug(f'Output: {proc.stdout}.')
	config = loads(proc.stdout)

	dev_server_host = config.get('dev_server_host', None)
	assert isinstance(dev_server_host, str), f'dev_server_host must be a string, got {dev_server_host}.'
	assert is_valid_host(dev_server_host), f'dev_server_host must be a valid IP or hostname, got {dev_server_host}.'
	if dev_server_host == '0.0.0.0':
		dev_server_host = '127.0.0.1'
	log.debug(f'Local dev server will use host {dev_server_host}.')

	dev_server_port = config.get('dev_server_port', None)
	if isinstance(dev_server_port, str):
		try:
			dev_server_port = int(dev_server_port, 10)
		except ValueError:
			pass
	assert isinstance(dev_server_port, int), f'dev_server_port must be a number, got {dev_server_port}.'
	assert is_valid_port(dev_server_port), f'dev_server_port must be a valid port, got {dev_server_port}.'
	log.debug(f'Local dev server will use port {dev_server_port}.')

	build_dir = config.get('build_dir', None)
	assert isinstance(build_dir, str), f'build_dir must be a string, got {build_dir}.'
	build_dir = Path(build_dir)
	log.debug(f'Local builds will be in {build_dir}.')

	upstream_url = config.get('upstream_url', None)
	assert isinstance(upstream_url, str), f'upstream_url must be a string, got {upstream_url}.'
	try:
		parse_url(upstream_url)
	except ValueError as e:
		assert False, f'upstream_url must be a valid URL, got {upstream_url} ({e}).'
	log.debug(f'Upstream builds will be at {upstream_url}.')

	return WebpackConfig(dev_server_host, dev_server_port, build_dir, upstream_url)