0

I've been looking at Apple's WWWDC 2015 Session 711: "Networking with NSURLSession". Towards the end, the speaker mentions URLSessionStreamTask, which can be used for direct socket I/O. And he mentions how a (HTTP) proxy connection can be transitioned to a stream-task.

A slide contains:

NSURLSessionStreamTask
DataTask conversion

NSURLSessionDataTask may be converted to a stream task
• Use NSURLSession to get through HTTP proxies
Conversion can occur when response is received

And the next slide has partial sample code:

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask,
                    didReceiveResponse response: NSURLResponse,
                              completionHandler: (NSURLSessionResponseDisposition) -> Void) {
    completionHandler(.BecomeStream)
}

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask,
                 didBecomeStreamTask streamTask: NSURLSessionStreamTask) {
}

I want to know how to create the proxy connection in the first place. And using the data from the "System Preferences" : Network : Advanced : Proxies panel if possible. (Not just the "HTTP" proxy, but any of the other 4 with the same format.)

And since they usually use HTTP instead of HTTPS, do such connections trigger ATS (App Transport Security)?

CTMacUser
  • 1,996
  • 1
  • 16
  • 27

1 Answers1

0

What they're talking about is support for the WebSocket protocol, which allows you to open a connection to a web server, then upgrade that connection to a web socket, thus allowing you to communicate directly with whatever script or CGI program is on the other end without having to conform to the traditional request-response style.

What I think they were trying to say was that if you are sending HTTP (ick) requests via a proxy that actually supports WebSocket communications, iOS knows how to ask the proxies to upgrade the connection properly. This same upgrade mechanism is often used for making an HTTPS request through an HTTP proxy, where supported, and if you make an HTTPS connection, the subsequent WebSockets upgrade should work in spite of the proxy no matter what, because the proxy is already just passing bits back and forth by that point.

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • I'm asking about the old-school 1990s proxies, which I think used HTTP CONNECT. Those are still in use today, I think. The link you provided on WebSocket mentions HTTP-CONNECT too. – CTMacUser Sep 04 '17 at 06:12
  • Are you asking how to use that directly to talk to an arbitrary server that doesn't speak HTTP/HTTPS? I don't think you can do that without implementing your own custom HTTP library. The NSURLSession/Connection code does, however, use that command automatically when needed to establish an HTTPS connection through a proxy that the user has configured for systemwide use. – dgatwood Sep 04 '17 at 19:35
  • Isn't the proxy process: 1--use HTTP CONNECT to the proxy server with the target server's hostname and port along with any username/password needed for the proxy. 2--if the proxy server returns an OK code, use the connection with the desired protocol, right? I'm asking how to build the URLRequest needed for (1). – CTMacUser Sep 05 '17 at 02:32
  • As I understand it, from an app's perspective, the process is A. connect to the target server's hostname. The NSURL machinery recognizes that it is configured to use a proxy, and it connects to the proxy server, sends the appropriate request to ask for a tunnel to the desired server, then opens an HTTPS connection over that link. If the server then asks for an upgrade from that to a stream, it happens later. Your app doesn't talk to the proxy directly at all. – dgatwood Sep 05 '17 at 05:54
  • If you need to configure a proxy dictionary to specify what server you use, see this link: https://stackoverflow.com/questions/28101582/how-to-programmatically-add-a-proxy-to-an-nsurlsession – dgatwood Sep 05 '17 at 05:54
  • Yes, if you're using the top layer of the NSURL machinery, proxy support is automatic. But I'm writing code at the lower level; I have to provide that "automatic" machinery myself for everyone else. So I have to do the proxy stuff manually. I'm asking how to get started with that. – CTMacUser Sep 10 '17 at 00:03
  • With NSURL machinery at *any* level, proxy support is automatic (though you can change which proxy to use, as described in the link above). With NSURL* APIs, you *can't* make a connection *to* a proxy. That's just not the way proxies work. You make a connection to the desired HTTP/HTTPS server, and the OS transparently asks the proxy, if configured, to forward the traffic. And that's the way non-web proxies work, too. – dgatwood Sep 10 '17 at 02:01
  • If you're trying to do something else (e.g. use a web proxy for non-web traffic), you'll have to write custom code to talk to the proxy using bare TCP sockets (e.g. `getStreamsToHost:port:inputStream:outputStream`). And that's way beyond the scope of a SO question. The best I can do there is point you at RFC 2817: https://www.ietf.org/rfc/rfc2817.txt – dgatwood Sep 10 '17 at 02:03
  • Are you sure about *any* level? Note in my OP I'm using `NSSessionStreamTask`, which takes a hostname & port instead of a URL. It can't automatically use a proxy since there's no scheme given so the system doesn't know which proxy settings to reference. The very essence of this query is for a "web proxy for non-web traffic." I don't see why it would be beyond the scope of SO. – CTMacUser Sep 10 '17 at 21:42
  • Yes, at any level. If what they said at the WWDC talk is accurate, then the API you're describing is supposed to automatically use whatever proxy is configured on the session. If that isn't happening, I'd call that a bug. To be clear, what I was saying is beyond the scope of SO is the source code for a full web proxy client (likely thousands of lines of code). :-) – dgatwood Sep 11 '17 at 06:12