I am trying to use a proxy with auth in Swift. I finally got it working using NWConnection. And I can see from my proxy server that it's actually getting the request from my iOS app when I call this function. However I get the error response below. I am assuming something about my request to httpbin.org is wrong but I have not been able to figure it out. The proxy in the array is working and feel free to use it if you want to test.
Connected to proxy: resi.wealthproxies.comResponse from proxy resi.wealthproxies.com: HTTP/1.1 400 Bad RequestServer: awselb/2.0Date: Thu, 13 Feb 2025 21:31:28 GMTContent-Type: text/htmlContent-Length: 122Connection: close<html><head><title>400 Bad Request</title></head><body><center><h1>400 Bad Request</h1></center></body></html>func averageProxyGroupSpeed(proxies: [String], completion: @escaping (Int, String) -> Void) { let numProxies = proxies.count if numProxies == 0 { completion(0, "No proxies") return } var totalTime: Int64 = 0 var successCount = 0 let group = DispatchGroup() let queue = DispatchQueue(label: "proxyQueue", attributes: .concurrent) let lock = NSLock() let shuffledProxies = proxies.shuffled() let selectedProxies = ["resi.wealthproxies.com:8000:akzaidan:x0if46jo-country-US-session-niwtz2y7-duration-60"] for proxy in selectedProxies { group.enter() queue.async { let proxyDetails = proxy.split(separator: ":").map(String.init) guard proxyDetails.count == 4, let port = UInt16(proxyDetails[1]) else { completion(0, "Invalid proxy format") group.leave() return } let proxyEndpoint = NWEndpoint.hostPort(host: .init(proxyDetails[0]), port: NWEndpoint.Port(integerLiteral: port)) let proxyConfig = ProxyConfiguration(httpCONNECTProxy: proxyEndpoint, tlsOptions: nil) proxyConfig.applyCredential(username: proxyDetails[2], password: proxyDetails[3]) let parameters = NWParameters.tcp let privacyContext = NWParameters.PrivacyContext(description: "ProxyConfig") privacyContext.proxyConfigurations = [proxyConfig] parameters.setPrivacyContext(privacyContext) let connection = NWConnection(to: .hostPort(host: "httpbin.org", port: 80), using: parameters) let start = Date() connection.stateUpdateHandler = { state in switch state { case .ready: print("Connected to proxy: \(proxyDetails[0])") let httpRequest = """ GET http://httpbin.org/get HTTP/1.1\r\n Host: httpbin.org\r\n Connection: close\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n Accept-Encoding: gzip, deflate\r\n Accept-Language: en-US,en;q=0.9\r\n Upgrade-Insecure-Requests: 1\r\n User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15\r\n \r\n""" connection.send(content: httpRequest.data(using: .utf8), completion: .contentProcessed({ error in if let error = error { print("Failed to send request: \(error)") group.leave() } else { // Receive the response connection.receive(minimumIncompleteLength: 1, maximumLength: 4096) { data, _, isComplete, error in defer { group.leave() } if let error = error { print("Failed to receive response: \(error)") } else if isComplete { print("complete") if let data { let responseString = String(data: data, encoding: .utf8) ?? "" print("Response from proxy \(proxyDetails[0]): \(responseString)") } else { print("data len is \(data?.count ?? -6)") } let duration = Date().timeIntervalSince(start) * 1000 // Convert to milliseconds lock.lock() totalTime += Int64(duration) successCount += 1 lock.unlock() } else if let data { let responseString = String(data: data, encoding: .utf8) ?? "" print("Response from proxy \(proxyDetails[0]): \(responseString)") } else { print("Not complete") } } } })) case .failed(let error): print("Connection failed for proxy \(proxyDetails[0]): \(error)") group.leave() case .cancelled: print("Connection cancelled for proxy \(proxyDetails[0])") group.leave() case .waiting(let error): print("Connection waiting for proxy \(proxyDetails[0]): \(error)") group.leave() default: break } } connection.start(queue: queue) } } group.notify(queue: DispatchQueue.main) { if successCount == 0 { completion(0, "Proxies Failed") } else { let averageTime = Int(Double(totalTime) / Double(successCount)) completion(averageTime, "") } }}