aboutsummaryrefslogtreecommitdiff
path: root/Hutch
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-15 15:29:57 -0500
committerChristian Cleberg <[email protected]>2026-04-15 15:30:40 -0500
commit06c36c4352f47655cb39a5042a7e5fd475c118e1 (patch)
tree448054ebc937a258c694ed2338a7c2f7edbd17f2 /Hutch
parent3727afa0fdb6e7b9884bbe00b9aed3e994952c5a (diff)
downloadhutch-06c36c4352f47655cb39a5042a7e5fd475c118e1.tar.gz
hutch-06c36c4352f47655cb39a5042a7e5fd475c118e1.tar.bz2
hutch-06c36c4352f47655cb39a5042a7e5fd475c118e1.zip
feat: add custom hutch user-agent to api calls
Implements: https://todo.sr.ht/~ccleberg/hutch/64
Diffstat (limited to 'Hutch')
-rw-r--r--Hutch/Extensions/Bundle+UserAgent.swift14
-rw-r--r--Hutch/Networking/HutchStatsService.swift5
-rw-r--r--Hutch/Networking/ManPageService.swift4
-rw-r--r--Hutch/Networking/SRHTClient.swift5
-rw-r--r--Hutch/Networking/SystemStatusService.swift9
5 files changed, 27 insertions, 10 deletions
diff --git a/Hutch/Extensions/Bundle+UserAgent.swift b/Hutch/Extensions/Bundle+UserAgent.swift
new file mode 100644
index 0000000..2200576
--- /dev/null
+++ b/Hutch/Extensions/Bundle+UserAgent.swift
@@ -0,0 +1,14 @@
+import Foundation
+
+extension Bundle {
+ /// The HTTP `User-Agent` string sent with all Hutch network requests.
+ ///
+ /// Format: `Hutch/<version>`
+ var hutchUserAgent: String {
+ let name = (object(forInfoDictionaryKey: "CFBundleDisplayName") as? String)
+ ?? (object(forInfoDictionaryKey: "CFBundleName") as? String)
+ ?? "Hutch"
+ let version = (object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String) ?? "dev"
+ return "\(name)/\(version)"
+ }
+}
diff --git a/Hutch/Networking/HutchStatsService.swift b/Hutch/Networking/HutchStatsService.swift
index aead9c6..fbac5be 100644
--- a/Hutch/Networking/HutchStatsService.swift
+++ b/Hutch/Networking/HutchStatsService.swift
@@ -54,9 +54,12 @@ struct HutchStatsService: ContributionCalendarServing {
throw URLError(.badURL)
}
+ var request = URLRequest(url: url)
+ request.setValue(Bundle.main.hutchUserAgent, forHTTPHeaderField: "User-Agent")
+
let (data, response): (Data, URLResponse)
do {
- (data, response) = try await session.data(from: url)
+ (data, response) = try await session.data(for: request)
} catch {
throw SRHTError.networkError(error)
}
diff --git a/Hutch/Networking/ManPageService.swift b/Hutch/Networking/ManPageService.swift
index 07d5c2d..4453572 100644
--- a/Hutch/Networking/ManPageService.swift
+++ b/Hutch/Networking/ManPageService.swift
@@ -18,7 +18,9 @@ struct ManPageService {
throw URLError(.badURL)
}
- let (data, response) = try await URLSession.shared.data(from: url)
+ var request = URLRequest(url: url)
+ request.setValue(Bundle.main.hutchUserAgent, forHTTPHeaderField: "User-Agent")
+ let (data, response) = try await URLSession.shared.data(for: request)
if let http = response as? HTTPURLResponse,
!(200...299).contains(http.statusCode) {
throw URLError(.badServerResponse)
diff --git a/Hutch/Networking/SRHTClient.swift b/Hutch/Networking/SRHTClient.swift
index 70c7650..b4f8ee0 100644
--- a/Hutch/Networking/SRHTClient.swift
+++ b/Hutch/Networking/SRHTClient.swift
@@ -66,6 +66,7 @@ final class SRHTClient: Sendable {
// Build request
var request = URLRequest(url: service.url)
request.httpMethod = "POST"
+ request.setValue(Bundle.main.hutchUserAgent, forHTTPHeaderField: "User-Agent")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
@@ -181,6 +182,7 @@ final class SRHTClient: Sendable {
var request = URLRequest(url: service.url)
request.httpMethod = "POST"
+ request.setValue(Bundle.main.hutchUserAgent, forHTTPHeaderField: "User-Agent")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
@@ -315,6 +317,7 @@ final class SRHTClient: Sendable {
var request = URLRequest(url: service.url)
request.httpMethod = "POST"
+ request.setValue(Bundle.main.hutchUserAgent, forHTTPHeaderField: "User-Agent")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
@@ -436,6 +439,7 @@ final class SRHTClient: Sendable {
var request = URLRequest(url: service.url)
request.httpMethod = "POST"
+ request.setValue(Bundle.main.hutchUserAgent, forHTTPHeaderField: "User-Agent")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
@@ -535,6 +539,7 @@ final class SRHTClient: Sendable {
}
var request = URLRequest(url: url)
+ request.setValue(Bundle.main.hutchUserAgent, forHTTPHeaderField: "User-Agent")
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
let (data, response): (Data, URLResponse)
diff --git a/Hutch/Networking/SystemStatusService.swift b/Hutch/Networking/SystemStatusService.swift
index ec2d233..35b82a1 100644
--- a/Hutch/Networking/SystemStatusService.swift
+++ b/Hutch/Networking/SystemStatusService.swift
@@ -60,14 +60,7 @@ struct SystemStatusService: Sendable {
return data
}
- private var userAgent: String {
- let bundle = Bundle.main
- let name = (bundle.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String)
- ?? (bundle.object(forInfoDictionaryKey: "CFBundleName") as? String)
- ?? "Hutch"
- let version = (bundle.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String) ?? "dev"
- return "\(name)/\(version) (System Status)"
- }
+ private var userAgent: String { Bundle.main.hutchUserAgent }
}
extension SystemStatusService: SystemStatusServing {}