parent
7fc53ae78a
commit
257753841b
@ -43,6 +43,7 @@ class UrlPattern:
|
|||||||
|
|
||||||
Class attributes:
|
Class attributes:
|
||||||
DEFAULT_PORTS: The default ports used for schemes which support ports.
|
DEFAULT_PORTS: The default ports used for schemes which support ports.
|
||||||
|
_SCHEMES_WITHOUT_HOST: Schemes which don't need a host.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
_pattern: The given pattern as string.
|
_pattern: The given pattern as string.
|
||||||
@ -59,6 +60,7 @@ class UrlPattern:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
DEFAULT_PORTS = {'https': 443, 'http': 80, 'ftp': 21}
|
DEFAULT_PORTS = {'https': 443, 'http': 80, 'ftp': 21}
|
||||||
|
_SCHEMES_WITHOUT_HOST = ['about', 'file', 'data', 'javascript']
|
||||||
|
|
||||||
def __init__(self, pattern):
|
def __init__(self, pattern):
|
||||||
# Make sure all attributes are initialized if we exit early.
|
# Make sure all attributes are initialized if we exit early.
|
||||||
@ -120,6 +122,10 @@ class UrlPattern:
|
|||||||
if pattern.startswith('*:'): # Any scheme, but *:// is unparseable
|
if pattern.startswith('*:'): # Any scheme, but *:// is unparseable
|
||||||
pattern = 'any:' + pattern[2:]
|
pattern = 'any:' + pattern[2:]
|
||||||
|
|
||||||
|
schemes = tuple(s + ':' for s in self._SCHEMES_WITHOUT_HOST)
|
||||||
|
if '://' not in pattern and not pattern.startswith(schemes):
|
||||||
|
pattern = 'any://' + pattern
|
||||||
|
|
||||||
# Chromium handles file://foo like file:///foo
|
# Chromium handles file://foo like file:///foo
|
||||||
# FIXME This doesn't actually strip the hostname correctly.
|
# FIXME This doesn't actually strip the hostname correctly.
|
||||||
if (pattern.startswith('file://') and
|
if (pattern.startswith('file://') and
|
||||||
@ -129,15 +135,24 @@ class UrlPattern:
|
|||||||
return pattern
|
return pattern
|
||||||
|
|
||||||
def _init_scheme(self, parsed):
|
def _init_scheme(self, parsed):
|
||||||
if not parsed.scheme:
|
"""Parse the scheme from the given URL.
|
||||||
raise ParseError("No scheme given")
|
|
||||||
elif parsed.scheme == 'any':
|
Deviation from Chromium:
|
||||||
|
- We assume * when no scheme has been given.
|
||||||
|
"""
|
||||||
|
assert parsed.scheme, parsed
|
||||||
|
if parsed.scheme == 'any':
|
||||||
self._scheme = None
|
self._scheme = None
|
||||||
return
|
return
|
||||||
|
|
||||||
self._scheme = parsed.scheme
|
self._scheme = parsed.scheme
|
||||||
|
|
||||||
def _init_path(self, parsed):
|
def _init_path(self, parsed):
|
||||||
|
"""Parse the path from the given URL.
|
||||||
|
|
||||||
|
Deviation from Chromium:
|
||||||
|
- We assume * when no path has been given.
|
||||||
|
"""
|
||||||
if self._scheme == 'about' and not parsed.path.strip():
|
if self._scheme == 'about' and not parsed.path.strip():
|
||||||
raise ParseError("Pattern without path")
|
raise ParseError("Pattern without path")
|
||||||
|
|
||||||
@ -157,7 +172,7 @@ class UrlPattern:
|
|||||||
- http://:1234/ is not a valid URL because it has no host.
|
- http://:1234/ is not a valid URL because it has no host.
|
||||||
"""
|
"""
|
||||||
if parsed.hostname is None or not parsed.hostname.strip():
|
if parsed.hostname is None or not parsed.hostname.strip():
|
||||||
if self._scheme not in ['about', 'file', 'data', 'javascript']:
|
if self._scheme not in self._SCHEMES_WITHOUT_HOST:
|
||||||
raise ParseError("Pattern without host")
|
raise ParseError("Pattern without host")
|
||||||
assert self._host is None
|
assert self._host is None
|
||||||
return
|
return
|
||||||
|
@ -43,11 +43,11 @@ from qutebrowser.utils import urlmatch
|
|||||||
|
|
||||||
@pytest.mark.parametrize('pattern, error', [
|
@pytest.mark.parametrize('pattern, error', [
|
||||||
# Chromium: PARSE_ERROR_MISSING_SCHEME_SEPARATOR
|
# Chromium: PARSE_ERROR_MISSING_SCHEME_SEPARATOR
|
||||||
("http", "No scheme given"),
|
# ("http", "No scheme given"),
|
||||||
("http:", "Pattern without host"),
|
("http:", "Invalid port: Port is empty"),
|
||||||
("http:/", "Pattern without host"),
|
("http:/", "Invalid port: Port is empty"),
|
||||||
("about://", "Pattern without path"),
|
("about://", "Pattern without path"),
|
||||||
("http:/bar", "Pattern without host"),
|
("http:/bar", "Invalid port: Port is empty"),
|
||||||
|
|
||||||
# Chromium: PARSE_ERROR_EMPTY_HOST
|
# Chromium: PARSE_ERROR_EMPTY_HOST
|
||||||
("http://", "Pattern without host"),
|
("http://", "Pattern without host"),
|
||||||
@ -114,7 +114,6 @@ def test_port(pattern, port):
|
|||||||
|
|
||||||
@pytest.mark.parametrize('pattern, path', [
|
@pytest.mark.parametrize('pattern, path', [
|
||||||
("http://foo/", '/'),
|
("http://foo/", '/'),
|
||||||
("http://foo", None),
|
|
||||||
("http://foo/*", None),
|
("http://foo/*", None),
|
||||||
])
|
])
|
||||||
def test_parse_path(pattern, path):
|
def test_parse_path(pattern, path):
|
||||||
@ -122,6 +121,24 @@ def test_parse_path(pattern, path):
|
|||||||
assert up._path == path
|
assert up._path == path
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('pattern, scheme, host, path', [
|
||||||
|
("http://example.com", 'http', 'example.com', None), # no path
|
||||||
|
("example.com/path", None, 'example.com', '/path'), # no scheme
|
||||||
|
("example.com", None, 'example.com', None), # no scheme and no path
|
||||||
|
("example.com:1234", None, 'example.com', None), # no scheme/path but port
|
||||||
|
("data:monkey", 'data', None, 'monkey'), # existing scheme
|
||||||
|
])
|
||||||
|
def test_lightweight_patterns(pattern, scheme, host, path):
|
||||||
|
"""Make sure we can leave off parts of an URL.
|
||||||
|
|
||||||
|
This is a deviation from Chromium to make patterns more user-friendly.
|
||||||
|
"""
|
||||||
|
up = urlmatch.UrlPattern(pattern)
|
||||||
|
assert up._scheme == scheme
|
||||||
|
assert up._host == host
|
||||||
|
assert up._path == path
|
||||||
|
|
||||||
|
|
||||||
class TestMatchAllPagesForGivenScheme:
|
class TestMatchAllPagesForGivenScheme:
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -264,7 +281,7 @@ class TestMatchChromeUrls:
|
|||||||
|
|
||||||
class TestMatchAnything:
|
class TestMatchAnything:
|
||||||
|
|
||||||
@pytest.fixture(params=['*://*/*', '*://*:*/*', '<all_urls>'])
|
@pytest.fixture(params=['*://*/*', '*://*:*/*', '<all_urls>', '*://*'])
|
||||||
def up(self, request):
|
def up(self, request):
|
||||||
return urlmatch.UrlPattern(request.param)
|
return urlmatch.UrlPattern(request.param)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user