Starscream: Using with System Proxy on Simulator

Created on 25 Aug 2016  路  19Comments  路  Source: daltoniam/Starscream

It seems that when using this framework on a simulator (I've been using it for a while now, but never on the simulator), the connection request ignores the system proxy. Other network requests (e.g. REST API calls using Alamofire) are handled appropriately and routed through the proxy. IS there a way to set the proxy for this framework or have others experienced this issue?

Most helpful comment

@iandundas Nope, it does not work for me on a real device (iPhone 7, iOS 11.2.2). I get the same Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" error.

It's actually what I expected because of the usage of CFNetworkCopySystemProxySettings as explained in an earlier post.

All 19 comments

I haven't heard of any issues with proxies. I would assume since proxies are suppose to be transparent and we are relying the Apple networking APIs just like AlamoFire does, it should work fine.

So, after hours of exploring, researching, and testing, I've got it working with the following:

//WebSocket.swift
//This was already here
inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()
//Added code below        
let proxyDict = CFNetworkCopySystemProxySettings()
let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue());

CFWriteStreamSetProperty(outputStream, kCFStreamPropertySOCKSProxy, socksConfig);
CFReadStreamSetProperty(inputStream, kCFStreamPropertySOCKSProxy, socksConfig);

This picks up the system wide proxy settings. Additionally, it seems that it only observes the SOCKS proxy setting. I've been able to get it working by running Charles Proxy on the host machine with External Proxy settings only set for HTTP/HTTPS.

Ah great work and thanks for taking the time to figure this out. Seems like the system proxy settings should be already be applied to the NSStream, but Cocoa APIs 馃槃. I'll make sure to look at this when I do the Swift 3 stuff. Thanks again.

Is this implemented?

The above code may run on the simulator (I didn't check TBH) but will not work on a real iOS device. The reason is that you can not specify a SOCK5 server in the iOS setting. Therefore CFNetworkCopySystemProxySettings() will return a dictionary that only contains HTTP proxy information.

Unfortunately the HTTP proxy is completely useless in this case as it will be ignore. You would have to create the socket using CFReadStreamCreateForHTTPRequest() (which is deprecated by the ways) as far as I understand it. Also it only gives you the response stream (somewhat like NSURLSession) which means it is not sufficient to create a WebSocket connection.

I think the easiest and simplest solution for everybody would be if you could set the sock5 proxy information on the WebSocket instand yourself before you call connect(). Somewhat like this:

        self.webSocket = WebSocket(url: encodedURLRequest.url!)
        self.webSocket!.delegate = self
        self.webSocket!.setSocks5ProxyInformation(host: "192.168.1.4", port: "8889")
        self.webSocket!.useSocks5Proxy = true
        self.webSocket!.connect()

If will create a pull request if I find the time.

3.0.3 released with #423!

@skerkewitz does this work on the device also? It works great for me on the simulator, but on device I see:

Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo={_kCFStreamErrorCodeKey=22, _kCFStreamErrorDomainKey=1}

Just wondering if it was intended to work also on device (or maybe there's something amiss at my end).

Thanks

Using:

var request = URLRequest(url: url)
request.timeoutInterval = 5
let stream = FoundationStream()
stream.enableSOCKSProxy = true

let rawSocket: WebSocket = WebSocket(request: request, stream: stream)

@iandundas Nope, it does not work for me on a real device (iPhone 7, iOS 11.2.2). I get the same Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" error.

It's actually what I expected because of the usage of CFNetworkCopySystemProxySettings as explained in an earlier post.

I confirm it doesn't work on real device (ios12)

error same to me

+1 would love to be able to work this out.

For now you can do something like that. Find if enableSOCKSProxy { section and replace it with

if enableSOCKSProxy {  
    let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, CFNetworkCopySystemProxySettings()!.takeRetainedValue())
    let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
    let dict = socksConfig as? [String: Any]
    if let ip = dict?["HTTPSProxy"]  as? String, let port = dict?["HTTPSPort"] as? Int {
        let customSocksConfig = ["SOCKSProxy": ip, "SOCKSPort": port + 1, "SOCKSEnable": 1] as CFDictionary?
        CFWriteStreamSetProperty(outputStream, propertyKey, customSocksConfig)
        CFReadStreamSetProperty(inputStream, propertyKey, customSocksConfig)
    }
 }

To adjust socks proxy turn on in charles https & socks proxy simultaneously. Socks we will use to sniff the traffic, http proxy will help other network services work properly. And we will use default proxy setting UI in ios preferences.
Then device proxy setting fill in with proper ip and http proxy port (eg 8888). Socks proxy port by default will listen on 8889 port.
On simulator all should work without any additional changes.

Thanks, but sadly it doesn't work 馃槥

@dai-cb You did something wrong, because i am case it's working solution

Is this on device? You can't set iOS proxy settings in Simulator.

@dai-cb It's in both case. Simulator uses proxy setting of mac os - so the computer which is running your simulator

sacred0x01's code is working for a device. Thanks! Didn't test on simulator yet.

This solution is not in work code now. But why? And how to intercept traffic by CharlesProxy from real device now?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dessmith picture dessmith  路  5Comments

francos picture francos  路  3Comments

fassko picture fassko  路  6Comments

blajivskiy picture blajivskiy  路  6Comments

LondonAtlas picture LondonAtlas  路  3Comments