From 5aba80d0a063d403ed68d6d4bce4945ff4d8e2e7 Mon Sep 17 00:00:00 2001 From: vsarunas <3808892+vsarunas@users.noreply.github.com> Date: Mon, 25 Nov 2024 12:06:22 +0300 Subject: [PATCH 1/3] read proxy from env --- Sources/SwiftlyCore/HTTPClient.swift | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftlyCore/HTTPClient.swift b/Sources/SwiftlyCore/HTTPClient.swift index b34d0211..11b80d73 100644 --- a/Sources/SwiftlyCore/HTTPClient.swift +++ b/Sources/SwiftlyCore/HTTPClient.swift @@ -11,8 +11,40 @@ public protocol HTTPRequestExecutor { /// An `HTTPRequestExecutor` backed by the shared `HTTPClient`. internal struct HTTPRequestExecutorImpl: HTTPRequestExecutor { + let httpClient: HTTPClient + + public init() { + var proxy: HTTPClient.Configuration.Proxy? + + func getProxyFromEnv(keys: [String]) -> HTTPClient.Configuration.Proxy? { + let environment = ProcessInfo.processInfo.environment + for key in keys { + if let proxyString = environment[key], + let url = URL(string: proxyString), + let host = url.host, + let port = url.port { + return .server(host: host, port: port) + } + } + return nil + } + + if let httpProxy = getProxyFromEnv(keys: ["http_proxy", "HTTP_PROXY"]) { + proxy = httpProxy + } + if let httpsProxy = getProxyFromEnv(keys: ["https_proxy", "HTTPS_PROXY"]) { + proxy = httpsProxy + } + + if proxy != nil { + self.httpClient = HTTPClient(eventLoopGroupProvider: .singleton, configuration: HTTPClient.Configuration(proxy: proxy)) + } else { + self.httpClient = HTTPClient.shared + } + } + public func execute(_ request: HTTPClientRequest, timeout: TimeAmount) async throws -> HTTPClientResponse { - try await HTTPClient.shared.execute(request, timeout: timeout) + try await httpClient.execute(request, timeout: timeout) } } From 0afc01643017331ae4176643a6a9bf5440039633 Mon Sep 17 00:00:00 2001 From: Sarunas <3808892+vsarunas@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:36:19 +0300 Subject: [PATCH 2/3] remove custom http proxy use in tests --- Sources/SwiftlyCore/HTTPClient.swift | 13 ++++++-- Tests/SwiftlyTests/SwiftlyTests.swift | 44 --------------------------- 2 files changed, 10 insertions(+), 47 deletions(-) diff --git a/Sources/SwiftlyCore/HTTPClient.swift b/Sources/SwiftlyCore/HTTPClient.swift index 11b80d73..c3d00a50 100644 --- a/Sources/SwiftlyCore/HTTPClient.swift +++ b/Sources/SwiftlyCore/HTTPClient.swift @@ -10,7 +10,7 @@ public protocol HTTPRequestExecutor { } /// An `HTTPRequestExecutor` backed by the shared `HTTPClient`. -internal struct HTTPRequestExecutorImpl: HTTPRequestExecutor { +internal class HTTPRequestExecutorImpl: HTTPRequestExecutor { let httpClient: HTTPClient public init() { @@ -22,7 +22,8 @@ internal struct HTTPRequestExecutorImpl: HTTPRequestExecutor { if let proxyString = environment[key], let url = URL(string: proxyString), let host = url.host, - let port = url.port { + let port = url.port + { return .server(host: host, port: port) } } @@ -43,8 +44,14 @@ internal struct HTTPRequestExecutorImpl: HTTPRequestExecutor { } } + deinit { + if httpClient !== HTTPClient.shared { + try? httpClient.syncShutdown() + } + } + public func execute(_ request: HTTPClientRequest, timeout: TimeAmount) async throws -> HTTPClientResponse { - try await httpClient.execute(request, timeout: timeout) + try await self.httpClient.execute(request, timeout: timeout) } } diff --git a/Tests/SwiftlyTests/SwiftlyTests.swift b/Tests/SwiftlyTests/SwiftlyTests.swift index cc59daee..1616cf51 100644 --- a/Tests/SwiftlyTests/SwiftlyTests.swift +++ b/Tests/SwiftlyTests/SwiftlyTests.swift @@ -17,51 +17,7 @@ struct SwiftlyTestError: LocalizedError { let message: String } -var proxyExecutorInstalled = false - -/// An `HTTPRequestExecutor` backed by an `HTTPClient` that can take http proxy -/// information from the environment in either HTTP_PROXY or HTTPS_PROXY -class ProxyHTTPRequestExecutorImpl: HTTPRequestExecutor { - let httpClient: HTTPClient - public init() { - var proxy: HTTPClient.Configuration.Proxy? - - let environment = ProcessInfo.processInfo.environment - let httpProxy = environment["HTTP_PROXY"] - if let httpProxy, let url = URL(string: httpProxy), let host = url.host, let port = url.port { - proxy = .server(host: host, port: port) - } - - let httpsProxy = environment["HTTPS_PROXY"] - if let httpsProxy, let url = URL(string: httpsProxy), let host = url.host, let port = url.port { - proxy = .server(host: host, port: port) - } - - if proxy != nil { - self.httpClient = HTTPClient(eventLoopGroupProvider: .singleton, configuration: HTTPClient.Configuration(proxy: proxy)) - } else { - self.httpClient = HTTPClient.shared - } - } - - public func execute(_ request: HTTPClientRequest, timeout: TimeAmount) async throws -> HTTPClientResponse { - try await self.httpClient.execute(request, timeout: timeout) - } - - deinit { - if httpClient !== HTTPClient.shared { - try? httpClient.syncShutdown() - } - } -} - class SwiftlyTests: XCTestCase { - override class func setUp() { - if !proxyExecutorInstalled { - SwiftlyCore.httpRequestExecutor = ProxyHTTPRequestExecutorImpl() - } - } - override class func tearDown() { #if os(Linux) let deleteTestGPGKeys = Process() From ca23a6f9abed21bca7af11c3a7275a335657de06 Mon Sep 17 00:00:00 2001 From: vsarunas <3808892+vsarunas@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:55:03 +0300 Subject: [PATCH 3/3] Document proxy env --- Documentation/SwiftlyDocs.docc/getting-started.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/SwiftlyDocs.docc/getting-started.md b/Documentation/SwiftlyDocs.docc/getting-started.md index b66d50e3..422f7852 100644 --- a/Documentation/SwiftlyDocs.docc/getting-started.md +++ b/Documentation/SwiftlyDocs.docc/getting-started.md @@ -58,6 +58,17 @@ Uninstall this toolchain after you're finished with it: $ swiftly uninstall main-snapshot ``` +# Proxy + +Swiftly downloads a list of toolchains from https://www.swift.org/ and retrieves them from Apple/Akamai CDN via https://download.swift.org. +If your environment requires a proxy, Swiftly will attempt to use the standard environment variables `http_proxy`, `HTTP_PROXY`, `https_proxy` or `HTTPS_PROXY` to determine which proxy server to use instead of making a direct connection. + +To download latest nightly snapshot using a proxy: +``` +$ export https_proxy=http://proxy:3128 +$ swiftly install main-snapshot +``` + # See Also: - [Install Toolchains](install-toolchains)