Ejemplo n.º 1
0
        internal Proxy GetProxy(Uri uri)
        {
            // WebSocket is not a request-response based protocol, so we need a 'tunnel' through the proxy
            HTTPProxy proxy = HTTPManager.Proxy as HTTPProxy;

            if (proxy != null && proxy.UseProxyForAddress(uri))
            {
                proxy = new HTTPProxy(proxy.Address,
                                      proxy.Credentials,
                                      false, /*turn on 'tunneling'*/
                                      false, /*sendWholeUri*/
                                      proxy.NonTransparentForHTTPS);
            }

            return(proxy);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a WebSocket instance from the given uri, protocol and origin.
        /// </summary>
        /// <param name="uri">The uri of the WebSocket server</param>
        /// <param name="origin">Servers that are not intended to process input from any web page but only for certain sites SHOULD verify the |Origin| field is an origin they expect.
        /// If the origin indicated is unacceptable to the server, then it SHOULD respond to the WebSocket handshake with a reply containing HTTP 403 Forbidden status code.</param>
        /// <param name="protocol">The application-level protocol that the client want to use(eg. "chat", "leaderboard", etc.). Can be null or empty string if not used.</param>
        /// <param name="extensions">Optional IExtensions implementations</param>
        public WebSocket(Uri uri, string origin, string protocol
#if !UNITY_WEBGL || UNITY_EDITOR
                         , params IExtension[] extensions
#endif
                         )

        {
            this.Context = new LoggingContext(this);

            string scheme = HTTPProtocolFactory.IsSecureProtocol(uri) ? "wss" : "ws";
            int    port   = uri.Port != -1 ? uri.Port : (scheme.Equals("wss", StringComparison.OrdinalIgnoreCase) ? 443 : 80);

            // Somehow if i use the UriBuilder it's not the same as if the uri is constructed from a string...
            //uri = new UriBuilder(uri.Scheme, uri.Host, uri.Scheme.Equals("wss", StringComparison.OrdinalIgnoreCase) ? 443 : 80, uri.PathAndQuery).Uri;
            uri = new Uri(scheme + "://" + uri.Host + ":" + port + uri.GetRequestPathAndQueryURL());

#if !UNITY_WEBGL || UNITY_EDITOR
            // Set up some default values.
            this.PingFrequency        = 1000;
            this.CloseAfterNoMesssage = TimeSpan.FromSeconds(2);

            InternalRequest = new HTTPRequest(uri, OnInternalRequestCallback);

            InternalRequest.Context.Add("WebSocket", this.Context);

            // Called when the regular GET request is successfully upgraded to WebSocket
            InternalRequest.OnUpgraded = OnInternalRequestUpgraded;

            //http://tools.ietf.org/html/rfc6455#section-4

            // The request MUST contain an |Upgrade| header field whose value MUST include the "websocket" keyword.
            InternalRequest.SetHeader("Upgrade", "websocket");

            // The request MUST contain a |Connection| header field whose value MUST include the "Upgrade" token.
            InternalRequest.SetHeader("Connection", "Upgrade");

            // The request MUST include a header field with the name |Sec-WebSocket-Key|.  The value of this header field MUST be a nonce consisting of a
            // randomly selected 16-byte value that has been base64-encoded (see Section 4 of [RFC4648]).  The nonce MUST be selected randomly for each connection.
            InternalRequest.SetHeader("Sec-WebSocket-Key", GetSecKey(new object[] { this, InternalRequest, uri, new object() }));

            // The request MUST include a header field with the name |Origin| [RFC6454] if the request is coming from a browser client.
            // If the connection is from a non-browser client, the request MAY include this header field if the semantics of that client match the use-case described here for browser clients.
            // More on Origin Considerations: http://tools.ietf.org/html/rfc6455#section-10.2
            if (!string.IsNullOrEmpty(origin))
            {
                InternalRequest.SetHeader("Origin", origin);
            }

            // The request MUST include a header field with the name |Sec-WebSocket-Version|.  The value of this header field MUST be 13.
            InternalRequest.SetHeader("Sec-WebSocket-Version", "13");

            if (!string.IsNullOrEmpty(protocol))
            {
                InternalRequest.SetHeader("Sec-WebSocket-Protocol", protocol);
            }

            // Disable caching
            InternalRequest.SetHeader("Cache-Control", "no-cache");
            InternalRequest.SetHeader("Pragma", "no-cache");

            this.Extensions = extensions;

#if !BESTHTTP_DISABLE_CACHING
            InternalRequest.DisableCache = true;
#endif

#if !BESTHTTP_DISABLE_PROXY
            // WebSocket is not a request-response based protocol, so we need a 'tunnel' through the proxy
            HTTPProxy httpProxy = HTTPManager.Proxy as HTTPProxy;
            if (httpProxy != null)
            {
                InternalRequest.Proxy = new HTTPProxy(httpProxy.Address,
                                                      httpProxy.Credentials,
                                                      false, /*turn on 'tunneling'*/
                                                      false, /*sendWholeUri*/
                                                      httpProxy.NonTransparentForHTTPS);
            }
#endif
#else
            this.Uri      = uri;
            this.Protocol = protocol;
#endif

            // Under WebGL when only the WebSocket protocol is used Setup() isn't called, so we have to call it here.
            HTTPManager.Setup();
        }