Just a second...

Connecting through an HTTP proxy

Clients can connect to the Diffusion™ server through an HTTP proxy by using the HTTP CONNECT verb to create the connection and tunneling any of the supported transports through that connection.

Figure 1. Flow of requests and responses when connecting to Diffusion through a proxy. (1) Client to proxy: HTTP CONNECT (2) Proxy to client: HTTP 401 / 407 (3) Client to proxy: HTTP CONNECT with credentials (4) Proxy to client: HTTP 200 (5) Client to Diffusion server (tunneling through the proxy): Connect over any supported transport.

Apple®, Android™, Java™, and .NET clients can connect to the Diffusion server through an HTTP proxy by specifying additional information on connection.

With no authentication at the proxy

When creating your session, add an HTTP proxy to the session by passing in the host and port number of the proxy.

JavaScript
Diffusion.sessions().httpProxy(host, port)
                    
.NET
var session = Diffusion.Sessions
   .HttpProxy( host, port )
   .Open( diffusionUrl );
                    
Apple
//  Copyright (C) 2021 Push Technology Ltd.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

import Foundation
import Diffusion

class ProxyConnection {

    func connect_no_authentication() {
        // Create an unauthenticated HTTP proxy configuration
        let proxy_configuration = PTDiffusionHTTPProxyConfiguration(host: "proxy", port: 80)

        // Create a mutable session configuration
        let configuration = PTDiffusionMutableSessionConfiguration()
        configuration.httpProxyConfiguration = proxy_configuration

        // Use the configuration to open a new session...
        PTDiffusionSession.open(with: URL(string: "wss://push.example.com")!,
                                configuration: configuration) { (session, error) in

            // Check error is `nil`, then use session as required.
            // Ensure to maintain a strong reference to the session beyond the lifetime
            // of this callback, for example by assigning it to an instance variable.

            if (session == nil) {
                print("Failed to open session: %@", error!.localizedDescription)
                return
            }

            // At this point we now have a connected session.
            print("Connected.")
        }
    }


    func connect_basic_authentication() {
        // Create an authentication provider for the HTTP proxy
        let proxy_authentication = PTDiffusionBasicHTTPProxyAuthentication(username: "user",
                                                                           password: "password")

        // Create an unauthenticated HTTP proxy configuration using the provider
        let proxy_configuration = PTDiffusionHTTPProxyConfiguration(host: "proxy",
                                                                    port: 80,
                                                                    authentication: proxy_authentication)

        // Create a mutable session configuration
        let configuration = PTDiffusionMutableSessionConfiguration()
        configuration.httpProxyConfiguration = proxy_configuration

        // Use the configuration to open a new session...
        PTDiffusionSession.open(with: URL(string: "wss://push.example.com")!,
                                configuration: configuration) { (session, error) in

            // Check error is `nil`, then use session as required.
            // Ensure to maintain a strong reference to the session beyond the lifetime
            // of this callback, for example by assigning it to an instance variable.

            if (session == nil) {
                print("Failed to open session: %@", error!.localizedDescription)
                return
            }

            // At this point we now have a connected session.
            print("Connected.")
        }
    }


}

With basic authentication at the proxy

If the proxy requires basic authentication, the client can use the implementation in the Diffusion API to authenticate.

When creating your session, add an HTTP proxy to the session by passing in the host and port number of the proxy and a proxy authentication object that provides the challenge handler for basic authentication.

.NET
var clientAuth = Diffusion.ProxyAuthentication.Basic( username, password );
var session = Diffusion.Sessions
   .HttpProxy( host, port, clientAuth )
   .Open( diffusionUrl );
                    
Java and Android
HTTPProxyAuthentication auth = Diffusion.proxyAuthentication().basic(username, password);
Diffusion.sessions().httpProxy(host, port, auth);
                    
Apple
//  Copyright (C) 2021 Push Technology Ltd.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

import Foundation
import Diffusion

class ProxyConnection {

    func connect_no_authentication() {
        // Create an unauthenticated HTTP proxy configuration
        let proxy_configuration = PTDiffusionHTTPProxyConfiguration(host: "proxy", port: 80)

        // Create a mutable session configuration
        let configuration = PTDiffusionMutableSessionConfiguration()
        configuration.httpProxyConfiguration = proxy_configuration

        // Use the configuration to open a new session...
        PTDiffusionSession.open(with: URL(string: "wss://push.example.com")!,
                                configuration: configuration) { (session, error) in

            // Check error is `nil`, then use session as required.
            // Ensure to maintain a strong reference to the session beyond the lifetime
            // of this callback, for example by assigning it to an instance variable.

            if (session == nil) {
                print("Failed to open session: %@", error!.localizedDescription)
                return
            }

            // At this point we now have a connected session.
            print("Connected.")
        }
    }


    func connect_basic_authentication() {
        // Create an authentication provider for the HTTP proxy
        let proxy_authentication = PTDiffusionBasicHTTPProxyAuthentication(username: "user",
                                                                           password: "password")

        // Create an unauthenticated HTTP proxy configuration using the provider
        let proxy_configuration = PTDiffusionHTTPProxyConfiguration(host: "proxy",
                                                                    port: 80,
                                                                    authentication: proxy_authentication)

        // Create a mutable session configuration
        let configuration = PTDiffusionMutableSessionConfiguration()
        configuration.httpProxyConfiguration = proxy_configuration

        // Use the configuration to open a new session...
        PTDiffusionSession.open(with: URL(string: "wss://push.example.com")!,
                                configuration: configuration) { (session, error) in

            // Check error is `nil`, then use session as required.
            // Ensure to maintain a strong reference to the session beyond the lifetime
            // of this callback, for example by assigning it to an instance variable.

            if (session == nil) {
                print("Failed to open session: %@", error!.localizedDescription)
                return
            }

            // At this point we now have a connected session.
            print("Connected.")
        }
    }


}

With another form of authentication at the proxy

If the proxy requires another form of authentication, the client can implement a challenge handler that the client uses to authenticate.

Implement the HTTPProxyAuthentication interface to provide a challenge handler that can handle the type of authentication your proxy uses. When creating your session, add an HTTP proxy to the session by passing in the host and port number of the proxy and a proxy authentication object that provides your challenge handler.

Note: The proxy authentication mechanism is separate from the client authentication mechanism and is transparent to the Diffusion server.