summaryrefslogtreecommitdiff
path: root/DomainDig/HTTPHeadersService.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-20 15:28:12 -0500
committerChristian Cleberg <[email protected]>2026-04-20 15:28:12 -0500
commitee2520f2c0c2d806fd284c3d6b8a81a3822f5270 (patch)
tree0680550a1071e01546ba074c2f20b1bf5a452238 /DomainDig/HTTPHeadersService.swift
parent4e94ee723cd19c964b1cf37792931e0c7c4614f4 (diff)
downloaddomain-dig-ee2520f2c0c2d806fd284c3d6b8a81a3822f5270.tar.gz
domain-dig-ee2520f2c0c2d806fd284c3d6b8a81a3822f5270.tar.bz2
domain-dig-ee2520f2c0c2d806fd284c3d6b8a81a3822f5270.zip
feat(v1.8): improve result structure, history, and consistency
- normalize sections and add summary card - fix resolver usage in reverse DNS - include custom port scans in history/export - standardize error handling - decompose ContentView into smaller views
Diffstat (limited to 'DomainDig/HTTPHeadersService.swift')
-rw-r--r--DomainDig/HTTPHeadersService.swift61
1 files changed, 33 insertions, 28 deletions
diff --git a/DomainDig/HTTPHeadersService.swift b/DomainDig/HTTPHeadersService.swift
index 51e7b5b..4bf175a 100644
--- a/DomainDig/HTTPHeadersService.swift
+++ b/DomainDig/HTTPHeadersService.swift
@@ -35,41 +35,46 @@ struct HTTPHeadersResult {
}
struct HTTPHeadersService {
- static func fetch(domain: String) async throws -> HTTPHeadersResult {
+ static func fetch(domain: String) async -> ServiceResult<HTTPHeadersResult> {
let url = URL(string: "https://\(domain)")!
var request = URLRequest(url: url, timeoutInterval: 10)
request.httpMethod = "HEAD"
let metricsDelegate = TaskMetricsDelegate()
let startTime = Date()
- let (_, response) = try await URLSession.shared.data(for: request, delegate: metricsDelegate)
- let responseTimeMs = max(0, Int(Date().timeIntervalSince(startTime) * 1000))
-
- guard let httpResponse = response as? HTTPURLResponse else {
- throw URLError(.badServerResponse)
- }
-
- let headers = httpResponse.allHeaderFields.compactMap { entry -> HTTPHeader? in
- guard let name = entry.key as? String,
- let value = entry.value as? String else { return nil }
- return HTTPHeader(name: name, value: value)
+ do {
+ let (_, response) = try await URLSession.shared.data(for: request, delegate: metricsDelegate)
+ let responseTimeMs = max(0, Int(Date().timeIntervalSince(startTime) * 1000))
+
+ guard let httpResponse = response as? HTTPURLResponse else {
+ return .error(URLError(.badServerResponse).localizedDescription)
+ }
+
+ let headers = httpResponse.allHeaderFields.compactMap { entry -> HTTPHeader? in
+ guard let name = entry.key as? String,
+ let value = entry.value as? String else { return nil }
+ return HTTPHeader(name: name, value: value)
+ }
+ .sorted { $0.name.lowercased() < $1.name.lowercased() }
+
+ let networkProtocolName = metricsDelegate.metrics?.transactionMetrics
+ .compactMap { $0.networkProtocolName }
+ .last
+ let detectedProtocol = protocolLabel(for: networkProtocolName)
+ let altSvcValue = headerValue(named: "alt-svc", in: httpResponse)
+ let http3Advertised = altSvcValue?.localizedCaseInsensitiveContains("h3") == true
+ let result = HTTPHeadersResult(
+ headers: headers,
+ statusCode: httpResponse.statusCode,
+ responseTimeMs: responseTimeMs,
+ httpProtocol: detectedProtocol,
+ http3Advertised: http3Advertised
+ )
+
+ return headers.isEmpty ? .empty("No HTTP headers returned") : .success(result)
+ } catch {
+ return .error(error.localizedDescription)
}
- .sorted { $0.name.lowercased() < $1.name.lowercased() }
-
- let networkProtocolName = metricsDelegate.metrics?.transactionMetrics
- .compactMap { $0.networkProtocolName }
- .last
- let detectedProtocol = protocolLabel(for: networkProtocolName)
- let altSvcValue = headerValue(named: "alt-svc", in: httpResponse)
- let http3Advertised = altSvcValue?.localizedCaseInsensitiveContains("h3") == true
-
- return HTTPHeadersResult(
- headers: headers,
- statusCode: httpResponse.statusCode,
- responseTimeMs: responseTimeMs,
- httpProtocol: detectedProtocol,
- http3Advertised: http3Advertised
- )
}
private static func protocolLabel(for networkProtocolName: String?) -> String? {