Skip to content

Commit

Permalink
feat: Enable SOCKS proxy support (#3076)
Browse files Browse the repository at this point in the history
  • Loading branch information
tahirmt authored Jun 15, 2023
1 parent 077430a commit f80aadb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 2 deletions.
25 changes: 24 additions & 1 deletion Sources/ApolloWebSocket/DefaultImplementation/WebSocket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public struct SSLSettings {

//WebSocket implementation

public final class WebSocket: NSObject, WebSocketClient, StreamDelegate, WebSocketStreamDelegate {
public final class WebSocket: NSObject, WebSocketClient, StreamDelegate, WebSocketStreamDelegate, SOCKSProxyable {

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

public var respondToPingWithPong: Bool = true

/// Determines whether a SOCKS proxy is enabled on the underlying request.
/// Mostly useful for debugging with tools like Charles Proxy.
/// Note: Will return `false` from the getter and no-op the setter for implementations that do not conform to `SOCKSProxyable`.
public var enableSOCKSProxy: Bool {
get {
guard let stream = stream as? SOCKSProxyable else {
// If it's not proxyable, then the proxy can't be enabled
return false
}

return stream.enableSOCKSProxy
}

set {
guard var stream = stream as? SOCKSProxyable else {
// If it's not proxyable, there's nothing to do here.
return
}

stream.enableSOCKSProxy = newValue
}
}

// MARK: - Private

private struct CompressionState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ protocol WebSocketStreamDelegate: AnyObject {
func streamDidError(error: Error?)
}

public protocol SOCKSProxyable {
/// Determines whether a SOCKS proxy is enabled on the underlying request.
/// Mostly useful for debugging with tools like Charles Proxy.
var enableSOCKSProxy: Bool { get set }
}

// This protocol is to allow custom implemention of the underlining stream.
// This way custom socket libraries (e.g. linux) can be used
protocol WebSocketStream {
Expand All @@ -36,7 +42,7 @@ protocol WebSocketStream {
#endif
}

class FoundationStream : NSObject, WebSocketStream, StreamDelegate {
class FoundationStream : NSObject, WebSocketStream, StreamDelegate, SOCKSProxyable {
private let workQueue = DispatchQueue(label: "com.apollographql.websocket", attributes: [])
private var inputStream: InputStream?
private var outputStream: OutputStream?
Expand Down
23 changes: 23 additions & 0 deletions Sources/ApolloWebSocket/WebSocketTransport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,29 @@ public class WebSocketTransport {
}
}

/// Determines whether a SOCKS proxy is enabled on the underlying request.
/// Mostly useful for debugging with tools like Charles Proxy.
/// Note: Will return `false` from the getter and no-op the setter for implementations that do not conform to `SOCKSProxyable`.
public var enableSOCKSProxy: Bool {
get {
guard let websocket = websocket as? SOCKSProxyable else {
// If it's not proxyable, then the proxy can't be enabled
return false
}

return websocket.enableSOCKSProxy
}

set {
guard var websocket = websocket as? SOCKSProxyable else {
// If it's not proxyable, there's nothing to do here.
return
}

websocket.enableSOCKSProxy = newValue
}
}

/// Designated initializer
///
/// - Parameters:
Expand Down
4 changes: 4 additions & 0 deletions Tests/ApolloInternalTestHelpers/MockWebSocket.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ public class MockWebSocket: WebSocketClient {
public func connect() {
}
}

public class ProxyableMockWebSocket: MockWebSocket, SOCKSProxyable {
public var enableSOCKSProxy: Bool = false
}
24 changes: 24 additions & 0 deletions Tests/ApolloTests/WebSocket/WebSocketTransportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,28 @@ class WebSocketTransportTests: XCTestCase {
XCTFail("Delay interrupted")
}
}

func testSocksProxyable_whenNotProxyable() {
let request = URLRequest(url: TestURL.mockServer.url)
self.webSocketTransport = WebSocketTransport(
websocket: MockWebSocket(request: request, protocol: .graphql_ws),
store: ApolloStore()
)

self.webSocketTransport.enableSOCKSProxy = true

XCTAssertEqual(self.webSocketTransport.enableSOCKSProxy, false)
}

func testSocksProxyable() {
let request = URLRequest(url: TestURL.mockServer.url)
self.webSocketTransport = WebSocketTransport(
websocket: ProxyableMockWebSocket(request: request, protocol: .graphql_ws),
store: ApolloStore()
)

self.webSocketTransport.enableSOCKSProxy = true

XCTAssertEqual(self.webSocketTransport.enableSOCKSProxy, true)
}
}

0 comments on commit f80aadb

Please sign in to comment.