Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,34 @@ import GRPC
import NIO
import NIOHPACK

/// Attaches a `User-Agent` header to every outgoing gRPC request.
///
/// The product name is derived from the RPC method path so that each
/// backend receives the user agent it expects:
/// - OCP server (`/ocp.*`) → `OpenCodeProtocol/iOS/{version}`
/// - Flipcash server → `Flipcash/iOS/{version}`
class UserAgentInterceptor<Request, Response>: ClientInterceptor<Request, Response>, @unchecked Sendable {
override func send(_ part: GRPCClientRequestPart<Request>, promise: EventLoopPromise<Void>?, context: ClientInterceptorContext<Request, Response>) {
var modifiedPart = part
switch modifiedPart {
case .metadata(var headers):
headers.add(.userAgent, value: "Flipcash/iOS/\(AppMeta.version)")
let product = Self.productName(for: context.path)
headers.add(.userAgent, value: "\(product)/iOS/\(AppMeta.version)")
modifiedPart = .metadata(headers)
default:
break
}
context.send(modifiedPart, promise: promise)
}

/// Returns the product name for the `User-Agent` header based on
/// the gRPC method path (e.g. `/ocp.transaction.v1.Transaction/SubmitIntent`).
private static func productName(for path: String) -> String {
if path.hasPrefix("/ocp.") {
return "OpenCodeProtocol"
}
return "Flipcash"
}
}

// MARK: - App -
Expand Down