mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-11-15 15:28:12 +00:00
Two small leaks from going through the open CodeQL alerts (code scanning alerts 100 and 123). The local download route returned `str(e)` on an OSError, and for a missing or unreadable file that text is the file's path on the server (`[Errno 2] No such file or directory: '/audiobooks/Author/Title.epub'`). #1422 cuts a non-admin's download path down to the file name everywhere else, so this put it back. The route now answers "Could not read the file" and the detail stays in the log. `should_bypass_proxy` logged the whole request URL at debug when it could not be parsed. URLs can carry credentials, so it logs only the exception now. Each change has a test that fails without it. The full non-e2e suite, ruff and basedpyright pass.
78 lines
2.5 KiB
Python
78 lines
2.5 KiB
Python
"""Tests for proxy selection and NO_PROXY bypass handling."""
|
|
|
|
|
|
def _set_proxy_config(monkeypatch, **values):
|
|
import shelfmark.download.network as network
|
|
|
|
def fake_get(key, default=""):
|
|
return values.get(key, default)
|
|
|
|
monkeypatch.setattr(network.app_config, "get", fake_get)
|
|
return network
|
|
|
|
|
|
def test_get_proxies_bypasses_exact_and_wildcard_no_proxy_hosts(monkeypatch):
|
|
network = _set_proxy_config(
|
|
monkeypatch,
|
|
PROXY_MODE="http",
|
|
HTTP_PROXY="http://proxy.local:8080",
|
|
HTTPS_PROXY="https://secure-proxy.local:8443",
|
|
NO_PROXY="LOCALHOST, *.Internal, 10.*",
|
|
)
|
|
|
|
assert network.should_bypass_proxy("https://localhost:8080") is True
|
|
assert network.should_bypass_proxy("https://API.Internal/path") is True
|
|
assert network.should_bypass_proxy("https://10.1.2.3/file") is True
|
|
assert network.should_bypass_proxy("https://example.com") is False
|
|
|
|
assert network.get_proxies("https://localhost:8080") == {}
|
|
assert network.get_proxies("https://example.com") == {
|
|
"http": "http://proxy.local:8080",
|
|
"https": "https://secure-proxy.local:8443",
|
|
}
|
|
|
|
|
|
def test_get_proxies_falls_back_to_http_proxy_for_https(monkeypatch):
|
|
network = _set_proxy_config(
|
|
monkeypatch,
|
|
PROXY_MODE="http",
|
|
HTTP_PROXY="http://proxy.local:8080",
|
|
HTTPS_PROXY="",
|
|
NO_PROXY="",
|
|
)
|
|
|
|
assert network.get_proxies("https://example.com") == {
|
|
"http": "http://proxy.local:8080",
|
|
"https": "http://proxy.local:8080",
|
|
}
|
|
|
|
|
|
def test_get_proxies_returns_socks_proxy_for_both_schemes(monkeypatch):
|
|
network = _set_proxy_config(
|
|
monkeypatch,
|
|
PROXY_MODE="socks5",
|
|
SOCKS5_PROXY="socks5://proxy.local:1080",
|
|
NO_PROXY="",
|
|
)
|
|
|
|
assert network.get_proxies("https://example.com") == {
|
|
"http": "socks5://proxy.local:1080",
|
|
"https": "socks5://proxy.local:1080",
|
|
}
|
|
|
|
|
|
def test_a_url_that_fails_to_parse_is_not_written_to_the_log(monkeypatch):
|
|
"""The proxy check logs why a URL did not parse, never the URL itself."""
|
|
from unittest.mock import patch
|
|
|
|
network = _set_proxy_config(monkeypatch, NO_PROXY="localhost")
|
|
# An unterminated IPv6 literal makes urlparse raise ValueError.
|
|
url = "http://user:s3cret@[::1/path?apikey=s3cret"
|
|
|
|
with patch.object(network.logger, "debug") as debug:
|
|
assert network.should_bypass_proxy(url) is False
|
|
|
|
logged = " ".join(str(arg) for call in debug.call_args_list for arg in call.args)
|
|
assert "Failed to parse URL" in logged
|
|
assert "s3cret" not in logged
|