Skip to content

Commit 9640d5b

Browse files
authored
fix(api): add user-agent header to appsync websocket handshake request (#3586)
* fix(api): add user-agent header to appsync websocket handshake request * fix broken integ test cases
1 parent 014d9b1 commit 9640d5b

File tree

4 files changed

+18
-8
lines changed

4 files changed

+18
-8
lines changed

AmplifyPlugins/API/Sources/AWSAPIPlugin/SubscriptionFactory/AppSyncRealTimeClientFactory.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ actor AppSyncRealTimeClientFactory: AppSyncRealTimeClientFactoryProtocol {
6161
requestInterceptor: authInterceptor,
6262
webSocketClient: WebSocketClient(
6363
url: Self.appSyncRealTimeEndpoint(endpoint),
64-
protocols: ["graphql-ws"],
64+
handshakeHttpHeaders: [
65+
URLRequestConstants.Header.webSocketSubprotocols: "graphql-ws",
66+
URLRequestConstants.Header.userAgent: AmplifyAWSServiceConfiguration.userAgentLib
67+
],
6568
interceptor: authInterceptor
6669
)
6770
)

AmplifyPlugins/API/Sources/AWSAPIPlugin/Support/Constants/URLRequestConstants.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct URLRequestConstants {
1818
static let userAgent = "User-Agent"
1919
static let xApiKey = "x-api-key"
2020
static let host = "Host"
21+
static let webSocketSubprotocols = "Sec-WebSocket-Protocol"
2122
}
2223

2324
struct ContentType {

AmplifyPlugins/API/Tests/APIHostApp/AWSAPIPluginFunctionalTests/AppSyncRealTimeClientTests.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ class AppSyncRealTimeClientTests: XCTestCase {
4747

4848
let webSocketClient = WebSocketClient(
4949
url: AppSyncRealTimeClientFactory.appSyncRealTimeEndpoint(URL(string: endpoint)!),
50-
protocols: ["graphql-ws"],
50+
handshakeHttpHeaders: [
51+
URLRequestConstants.Header.webSocketSubprotocols: "graphql-ws",
52+
URLRequestConstants.Header.userAgent: AmplifyAWSServiceConfiguration.userAgentLib + " (intg-test)"
53+
],
5154
interceptor: APIKeyAuthInterceptor(apiKey: apiKey)
5255
)
5356
appSyncRealTimeClient = AppSyncRealTimeClient(

AmplifyPlugins/Core/AWSPluginsCore/WebSocket/WebSocketClient.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public final actor WebSocketClient: NSObject {
2323

2424
/// WebSocket server endpoint
2525
private let url: URL
26-
/// WebSocket subprotocols
27-
private let protocols: [String]
26+
/// Additional Header for WebSocket handshake http request
27+
private let handshakeHttpHeaders: [String: String]
2828
/// Interceptor for appending additional info before makeing the connection
2929
private var interceptor: WebSocketInterceptor?
3030
/// Internal wriable WebSocketEvent data stream
@@ -68,12 +68,12 @@ public final actor WebSocketClient: NSObject {
6868
*/
6969
public init(
7070
url: URL,
71-
protocols: [String] = [],
71+
handshakeHttpHeaders: [String: String] = [:],
7272
interceptor: WebSocketInterceptor? = nil,
7373
networkMonitor: WebSocketNetworkMonitorProtocol = AmplifyNetworkMonitor()
7474
) {
7575
self.url = Self.useWebSocketProtocolScheme(url: url)
76-
self.protocols = protocols
76+
self.handshakeHttpHeaders = handshakeHttpHeaders
7777
self.interceptor = interceptor
7878
self.autoConnectOnNetworkStatusChange = false
7979
self.autoRetryOnConnectionFailure = false
@@ -156,9 +156,12 @@ public final actor WebSocketClient: NSObject {
156156
}
157157

158158
private func createWebSocketConnection() async -> URLSessionWebSocketTask {
159-
let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
160159
let decoratedURL = (await self.interceptor?.interceptConnection(url: self.url)) ?? self.url
161-
return urlSession.webSocketTask(with: decoratedURL, protocols: self.protocols)
160+
var urlRequest = URLRequest(url: decoratedURL)
161+
self.handshakeHttpHeaders.forEach { urlRequest.setValue($0.value, forHTTPHeaderField: $0.key) }
162+
163+
let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
164+
return urlSession.webSocketTask(with: urlRequest)
162165
}
163166

164167
private func createConnectionAndRead() async {

0 commit comments

Comments
 (0)