Skip to content

Commit 3a3ea57

Browse files
committed
Make SOCKS proxy support public
1 parent ff49bec commit 3a3ea57

5 files changed

Lines changed: 82 additions & 2 deletions

File tree

Sources/ApolloWebSocket/DefaultImplementation/WebSocket.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public struct SSLSettings {
4040

4141
//WebSocket implementation
4242

43-
public final class WebSocket: NSObject, WebSocketClient, StreamDelegate, WebSocketStreamDelegate {
43+
public final class WebSocket: NSObject, WebSocketClient, StreamDelegate, WebSocketStreamDelegate, SOCKSProxyable {
4444

4545
public enum OpCode : UInt8 {
4646
case continueFrame = 0x0
@@ -166,6 +166,29 @@ public final class WebSocket: NSObject, WebSocketClient, StreamDelegate, WebSock
166166

167167
public var respondToPingWithPong: Bool = true
168168

169+
/// Determines whether a SOCKS proxy is enabled on the underlying request.
170+
/// Mostly useful for debugging with tools like Charles Proxy.
171+
/// Note: Will return `false` from the getter and no-op the setter for implementations that do not conform to `SOCKSProxyable`.
172+
public var enableSOCKSProxy: Bool {
173+
get {
174+
guard let stream = stream as? SOCKSProxyable else {
175+
// If it's not proxyable, then the proxy can't be enabled
176+
return false
177+
}
178+
179+
return stream.enableSOCKSProxy
180+
}
181+
182+
set {
183+
guard var stream = stream as? SOCKSProxyable else {
184+
// If it's not proxyable, there's nothing to do here.
185+
return
186+
}
187+
188+
stream.enableSOCKSProxy = newValue
189+
}
190+
}
191+
169192
// MARK: - Private
170193

171194
private struct CompressionState {

Sources/ApolloWebSocket/DefaultImplementation/WebSocketStream.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ protocol WebSocketStreamDelegate: AnyObject {
1515
func streamDidError(error: Error?)
1616
}
1717

18+
public protocol SOCKSProxyable {
19+
/// Determines whether a SOCKS proxy is enabled on the underlying request.
20+
/// Mostly useful for debugging with tools like Charles Proxy.
21+
var enableSOCKSProxy: Bool { get set }
22+
}
23+
1824
// This protocol is to allow custom implemention of the underlining stream.
1925
// This way custom socket libraries (e.g. linux) can be used
2026
protocol WebSocketStream {
@@ -36,7 +42,7 @@ protocol WebSocketStream {
3642
#endif
3743
}
3844

39-
class FoundationStream : NSObject, WebSocketStream, StreamDelegate {
45+
class FoundationStream : NSObject, WebSocketStream, StreamDelegate, SOCKSProxyable {
4046
private let workQueue = DispatchQueue(label: "com.apollographql.websocket", attributes: [])
4147
private var inputStream: InputStream?
4248
private var outputStream: OutputStream?

Sources/ApolloWebSocket/WebSocketTransport.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,29 @@ public class WebSocketTransport {
125125
}
126126
}
127127

128+
/// Determines whether a SOCKS proxy is enabled on the underlying request.
129+
/// Mostly useful for debugging with tools like Charles Proxy.
130+
/// Note: Will return `false` from the getter and no-op the setter for implementations that do not conform to `SOCKSProxyable`.
131+
public var enableSOCKSProxy: Bool {
132+
get {
133+
guard let websocket = websocket as? SOCKSProxyable else {
134+
// If it's not proxyable, then the proxy can't be enabled
135+
return false
136+
}
137+
138+
return websocket.enableSOCKSProxy
139+
}
140+
141+
set {
142+
guard var websocket = websocket as? SOCKSProxyable else {
143+
// If it's not proxyable, there's nothing to do here.
144+
return
145+
}
146+
147+
websocket.enableSOCKSProxy = newValue
148+
}
149+
}
150+
128151
/// Designated initializer
129152
///
130153
/// - Parameters:

Tests/ApolloInternalTestHelpers/MockWebSocket.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ public class MockWebSocket: WebSocketClient {
3535
public func connect() {
3636
}
3737
}
38+
39+
public class ProxyableMockWebSocket: MockWebSocket, SOCKSProxyable {
40+
public var enableSOCKSProxy: Bool = false
41+
}

Tests/ApolloTests/WebSocket/WebSocketTransportTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,28 @@ class WebSocketTransportTests: XCTestCase {
8484
XCTFail("Delay interrupted")
8585
}
8686
}
87+
88+
func testSocksProxyable_whenNotProxyable() {
89+
let request = URLRequest(url: TestURL.mockServer.url)
90+
self.webSocketTransport = WebSocketTransport(
91+
websocket: MockWebSocket(request: request, protocol: .graphql_ws),
92+
store: ApolloStore()
93+
)
94+
95+
self.webSocketTransport.enableSOCKSProxy = true
96+
97+
XCTAssertEqual(self.webSocketTransport.enableSOCKSProxy, false)
98+
}
99+
100+
func testSocksProxyable() {
101+
let request = URLRequest(url: TestURL.mockServer.url)
102+
self.webSocketTransport = WebSocketTransport(
103+
websocket: ProxyableMockWebSocket(request: request, protocol: .graphql_ws),
104+
store: ApolloStore()
105+
)
106+
107+
self.webSocketTransport.enableSOCKSProxy = true
108+
109+
XCTAssertEqual(self.webSocketTransport.enableSOCKSProxy, true)
110+
}
87111
}

0 commit comments

Comments
 (0)