Esempio n. 1
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);

#if !UNITY_WEBGL || UNITY_EDITOR
            this.Extensions = extensions;

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && !BESTHTTP_DISABLE_HTTP2
            if (HTTPManager.HTTP2Settings.WebSocketOverHTTP2Settings.EnableWebSocketOverHTTP2 && HTTPProtocolFactory.IsSecureProtocol(uri))
            {
                // Try to find a HTTP/2 connection that supports the connect protocol.
                var con = BestHTTP.Core.HostManager.GetHost(uri.Host).GetHostDefinition(Core.HostDefinition.GetKeyFor(new UriBuilder("https", uri.Host, uri.Port).Uri
#if !BESTHTTP_DISABLE_PROXY
                                                                                                                      , GetProxy(uri)
#endif
                                                                                                                      )).Find(c => {
                    var httpConnection = c as HTTPConnection;
                    var http2Handler   = httpConnection?.requestHandler as Connections.HTTP2.HTTP2Handler;

                    return(http2Handler != null && http2Handler.settings.RemoteSettings[Connections.HTTP2.HTTP2Settings.ENABLE_CONNECT_PROTOCOL] != 0);
                });

                if (con != null)
                {
                    HTTPManager.Logger.Information("WebSocket", "Connection with enabled Connect Protocol found!", this.Context);

                    var httpConnection = con as HTTPConnection;
                    var http2Handler   = httpConnection?.requestHandler as Connections.HTTP2.HTTP2Handler;

                    this.implementation = new OverHTTP2(this, http2Handler, uri, origin, protocol);
                }
            }
#endif

            if (this.implementation == null)
            {
                this.implementation = new OverHTTP1(this, uri, origin, protocol);
            }
#else
            this.implementation = new WebGLBrowser(this, uri, origin, protocol);
#endif

            // Under WebGL when only the WebSocket protocol is used Setup() isn't called, so we have to call it here.
            HTTPManager.Setup();
        }
Esempio n. 2
0
 public static void Awake(this DownloadComponent self, int packageLength = 1000000, int maxCount = 5, int timeOut = 20, int maxTryCount = 3)
 {
     if (!DownloadComponent.isInit)
     {
         HTTPUpdateDelegator.IsThreaded = true;
         HTTPManager.Setup();
         DownloadComponent.isInit = true;
     }
     self.packageLength       = packageLength;
     self.maxCount            = maxCount;
     self.timeOut             = timeOut;
     self.maxTryCount         = maxTryCount;
     self.StandByTasks        = new LinkedList <DownloadComponent.DownloadTask>();
     self.WriteFileTasks      = new Dictionary <string, List <DownloadComponent.DownloadingTask> >();
     self.SaveFileMap         = new Dictionary <string, string>();
     self.DownloadingTaskList = new List <DownloadComponent.DownloadingTask>();
     self.FileStreamMap       = new Dictionary <string, FileStream>();
     self.CacheInfo           = new Dictionary <string, string>();
     self.SuccessCount        = 0;
     self.FailureCount        = 0;
     self.ContinuousError     = 0;
     self.TotalBytes          = new Dictionary <string, long>();
     self.DownLoadBytes       = new Dictionary <string, long>();
 }
        /// <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();
        }