Skip to content

Commit fe20686

Browse files
committed
Support app-specific user-agents
* application user-agent can be set with UpdaterConfig object * Setting will affect the default fetcher only * the application user-agent will be prefixed to the ngclient default user-agent Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
1 parent c625687 commit fe20686

3 files changed

Lines changed: 22 additions & 5 deletions

File tree

tuf/ngclient/_internal/requests_fetcher.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# can be moved out of _internal once sigstore-python 1.0 is not relevant.
1111

1212
import logging
13-
from typing import Dict, Iterator, Tuple
13+
from typing import Dict, Iterator, Optional, Tuple
1414
from urllib import parse
1515

1616
# Imports
@@ -35,7 +35,10 @@ class RequestsFetcher(FetcherInterface):
3535
"""
3636

3737
def __init__(
38-
self, socket_timeout: int = 30, chunk_size: int = 400000
38+
self,
39+
socket_timeout: int = 30,
40+
chunk_size: int = 400000,
41+
app_user_agent: Optional[str] = None,
3942
) -> None:
4043
# http://docs.python-requests.org/en/master/user/advanced/#session-objects:
4144
#
@@ -56,6 +59,7 @@ def __init__(
5659
# Default settings
5760
self.socket_timeout: int = socket_timeout # seconds
5861
self.chunk_size: int = chunk_size # bytes
62+
self.app_user_agent = app_user_agent
5963

6064
def _fetch(self, url: str) -> Iterator[bytes]:
6165
"""Fetch the contents of HTTP/HTTPS url from a remote server.
@@ -138,6 +142,8 @@ def _get_session(self, url: str) -> requests.Session:
138142
self._sessions[session_index] = session
139143

140144
ua = f"tuf/{tuf.__version__} {session.headers['User-Agent']}"
145+
if self.app_user_agent is not None:
146+
ua = f"{self.app_user_agent} {ua}"
141147
session.headers["User-Agent"] = ua
142148

143149
logger.debug("Made new session %s", session_index)

tuf/ngclient/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from dataclasses import dataclass
77
from enum import Flag, unique
8+
from typing import Optional
89

910

1011
@unique
@@ -39,6 +40,8 @@ class UpdaterConfig:
3940
envelope_type: Configures deserialization and verification mode of TUF
4041
metadata. Per default, it is treated as traditional canonical JSON
4142
-based TUF Metadata.
43+
app_user_agent: Application user agent, e.g. "MyApp/1.0.0". This will be
44+
prefixed to ngclient user agent when the default fetcher is used.
4245
"""
4346

4447
max_root_rotations: int = 32
@@ -49,3 +52,4 @@ class UpdaterConfig:
4952
targets_max_length: int = 5000000 # bytes
5053
prefix_targets_with_hash: bool = True
5154
envelope_type: EnvelopeType = EnvelopeType.METADATA
55+
app_user_agent: Optional[str] = None

tuf/ngclient/updater.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,25 @@ def __init__(
9393
else:
9494
self._target_base_url = _ensure_trailing_slash(target_base_url)
9595

96-
# Read trusted local root metadata
97-
data = self._load_local_metadata(Root.type)
98-
self._fetcher = fetcher or requests_fetcher.RequestsFetcher()
9996
self.config = config or UpdaterConfig()
10097

98+
if fetcher is not None:
99+
self._fetcher = fetcher
100+
else:
101+
self._fetcher = requests_fetcher.RequestsFetcher(
102+
app_user_agent=self.config.app_user_agent
103+
)
104+
101105
supported_envelopes = [EnvelopeType.METADATA, EnvelopeType.SIMPLE]
102106
if self.config.envelope_type not in supported_envelopes:
103107
raise ValueError(
104108
f"config: envelope_type must be one of {supported_envelopes}, "
105109
f"got '{self.config.envelope_type}'"
106110
)
107111

112+
# Read trusted local root metadata
113+
data = self._load_local_metadata(Root.type)
114+
108115
self._trusted_set = trusted_metadata_set.TrustedMetadataSet(
109116
data, self.config.envelope_type
110117
)

0 commit comments

Comments
 (0)