diff --git a/docs/environment-variables.md b/docs/environment-variables.md index a6624365..ac20fc52 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -2311,7 +2311,7 @@ How long to keep cached search results before they expire. | `QBITTORRENT_DOWNLOAD_DIR_BOOK` | Server-side directory where book torrents are downloaded (optional, uses qBittorrent default if not specified) | string | _none_ | | `QBITTORRENT_DOWNLOAD_DIR_AUDIOBOOK` | Server-side directory where audiobook torrents are downloaded (optional, uses qBittorrent default if not specified) | string | _none_ | | `QBITTORRENT_TAG` | Tag(s) to assign to qBittorrent downloads. Leave empty for no tags. | string (comma-separated) | _empty list_ | -| `TRANSMISSION_URL` | URL of your Transmission instance (use https:// for TLS) | string | _none_ | +| `TRANSMISSION_URL` | URL of your Transmission instance (use https:// for TLS). Without a port, https uses 443 and http uses 9091, so add :9091 to an https URL served on 9091 | string | _none_ | | `TRANSMISSION_USERNAME` | Transmission RPC username (if authentication enabled) | string | _none_ | | `TRANSMISSION_PASSWORD` | Transmission RPC password | string (secret) | _none_ | | `TRANSMISSION_CATEGORY` | Label to assign to book downloads in Transmission | string | `books` | @@ -2516,7 +2516,7 @@ Tag(s) to assign to qBittorrent downloads. Leave empty for no tags. **Transmission URL** -URL of your Transmission instance (use https:// for TLS) +URL of your Transmission instance (use https:// for TLS). Without a port, https uses 443 and http uses 9091, so add :9091 to an https URL served on 9091 - **Type:** string - **Default:** _none_ diff --git a/shelfmark/download/clients/settings.py b/shelfmark/download/clients/settings.py index 67a62a7a..35b9dfb8 100644 --- a/shelfmark/download/clients/settings.py +++ b/shelfmark/download/clients/settings.py @@ -815,7 +815,10 @@ def prowlarr_clients_settings() -> list[SettingsField]: TextField( key="TRANSMISSION_URL", label="Transmission URL", - description="URL of your Transmission instance (use https:// for TLS)", + description=( + "URL of your Transmission instance (use https:// for TLS). Without a port, " + "https uses 443 and http uses 9091, so add :9091 to an https URL served on 9091" + ), placeholder="http://transmission:9091", show_when={"field": "PROWLARR_TORRENT_CLIENT", "value": "transmission"}, ), diff --git a/shelfmark/download/clients/torrent_utils.py b/shelfmark/download/clients/torrent_utils.py index a1b270d4..d72c1a9a 100644 --- a/shelfmark/download/clients/torrent_utils.py +++ b/shelfmark/download/clients/torrent_utils.py @@ -382,7 +382,9 @@ def parse_transmission_url(url: str) -> tuple[str, str, int, str]: if protocol not in ("http", "https"): protocol = "http" host = parsed.hostname or "localhost" - port = parsed.port or 9091 + # An omitted port is scheme-specific: HTTPS behind a reverse proxy is 443, + # while HTTP (including the empty-URL default) stays on Transmission's RPC port. + port = parsed.port if parsed.port is not None else (443 if protocol == "https" else 9091) path = parsed.path or "/transmission/rpc" # Ensure path ends with /rpc diff --git a/tests/prowlarr/test_torrent_utils.py b/tests/prowlarr/test_torrent_utils.py index 8d9a3be7..985019df 100644 --- a/tests/prowlarr/test_torrent_utils.py +++ b/tests/prowlarr/test_torrent_utils.py @@ -87,6 +87,14 @@ class TestParseTransmissionUrl: assert port == 9091 assert path == "/transmission/rpc" + def test_parse_https_url_without_port_uses_443(self): + """Test an HTTPS URL with no port uses the implicit HTTPS port.""" + protocol, host, port, path = parse_transmission_url("https://transmission.myserver.org") + assert protocol == "https" + assert host == "transmission.myserver.org" + assert port == 443 + assert path == "/transmission/rpc" + def test_parse_url_with_ip_address(self): """Test parsing URL with IP address.""" protocol, host, port, path = parse_transmission_url("http://192.168.1.100:9091")