Shalon
public class Shalon : NSObject, StreamDelegate
With this class you can connect to a target through a Shalon proxy. Connections to the proxy and connections to the target will each be encrypted using TLS. This means that your ISP or other people in your network cannot observe to which target you connect, because they only see connections to the proxy. The proxy itself does not see the content of your requests to the target. The target will only see the proxy’s IP address (except if the IP address is otherwise embedded into the request).
This implementation supports multiple hops. Simply add other layers.
In order to use Shalon proxies with your URLSession
connections, please
take look at ShalonURLProtocol
.
Examples
let proxy1 = Target(withHostname: "shalon1.jondonym.net", andPort: 443)!
let proxy2 = Target(withHostname: "shalon2.jondonym.net", andPort: 443)!
let proxy3 = Target(withHostname: "shalon3.jondonym.net", andPort: 443)!
let target = Target(withHostname: "www.example.com", andPort: 443)!
let shalon = Shalon(withTarget: target)
shalon.addLayer(proxy3)
shalon.addLayer(proxy2)
shalon.addLayer(proxy1)
shalon.issue(request: Request(withMethod: .head, andUrl: url)!) {
optionalResponse, optionalError in
// TODO Do something
}
This will establish a nested tunnel, where proxy1
cannot see what the
client
sends to proxy2
, as depicted:
client proxy1 proxy2 proxy3 target
| | | | |
+----------------+ | | |
| CONNECT proxy2 | | | |
+---------------------------------+ | |
| CONNECT proxy3 | | |
+--------------------------------------------------+ |
| CONNECT proxy4 | |
+------------------------------------------------------------------+
| HEAD / |
+------------------------------------------------------------------+
| | |
+--------------------------------------------------+ |
| | | |
+---------------------------------+ | |
| | | | |
+----------------+ | | |
| | | | |
-
A helper type for our callbacks, a function that gets either a HTTP response or an error.
Declaration
Swift
public typealias CompletionHandler = (Http.Response?, Error?) -> Void
-
Construct a Shalon object with a given target. After calling this, proxies can be added by calling
addLayer(_:)
.Warning
If no layer is added, a direct connection will be made. Which means that the IP address of the current device will be visible to the target.
Declaration
Swift
public init(withTarget target: Target)
Parameters
target
The address of the server, to which requests should be issued.
-
This adds a proxy, which is connected before each other layer that was previously added, i.e., the last layer added will be the layer the initial conenction is made to.
Declaration
Swift
public func addLayer(_ target: Target)
Parameters
target
A proxy address.
-
Issue an HTTP request. The request is send through a TLS tunnel via proxy servers added with
addLayer(_:)
.Warning
If no layer was added with
addLayer(_:)
, a direct connection to the target will be established. Which means that the IP address of the current device will be visible to the target.Postcondition
Either the response or the error parameter of the
completionHandler
is set, the other one isnil
.Declaration
Swift
public func issue(request: Http.Request, completionHandler: @escaping CompletionHandler)
Parameters
request
The HTTP request.
completionHandler
A callback function. Its parameters are either an optional HTTP response or an error.
-
Implementation of the
StreamDelegate
protocol.Declaration
Swift
public func stream(_ stream: Stream, handle eventCode: Stream.Event)
Parameters
stream
The stream on which streamEvent occurred.
handle
The stream event that occurred.