Exemple #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EtpServer"/> class.
        /// </summary>
        /// <param name="webSocket">The web socket.</param>
        /// <param name="application">The server application name.</param>
        /// <param name="version">The server application version.</param>
        /// <param name="headers">The WebSocket or HTTP headers.</param>
        public EtpServer(WebSocket webSocket, string application, string version, IDictionary <string, string> headers)
            : base(EtpWebSocketValidation.GetEtpVersion(webSocket.SubProtocol), webSocket, application, version, headers, false)
        {
            var etpVersion = EtpWebSocketValidation.GetEtpVersion(Socket.SubProtocol);

            SessionId = Guid.NewGuid().ToString();
        }
Exemple #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EtpClient"/> class.
        /// </summary>
        /// <param name="uri">The ETP server URI.</param>
        /// <param name="application">The client application name.</param>
        /// <param name="version">The client application version.</param>
        /// <param name="etpSubProtocol">The ETP sub protocol.</param>
        /// <param name="headers">The WebSocket headers.</param>
        public EtpClient(string uri, string application, string version, string etpSubProtocol, IDictionary <string, string> headers)
            : base(EtpWebSocketValidation.GetEtpVersion(etpSubProtocol), application, version, headers, true)
        {
            var headerItems = Headers.Union(BinaryHeaders.Where(x => !Headers.ContainsKey(x.Key))).ToList();

            _socket = new WebSocket(uri,
                                    subProtocol: etpSubProtocol,
                                    cookies: null,
                                    customHeaderItems: headerItems,
                                    userAgent: application);
        }
Exemple #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EtpClient"/> class.
        /// </summary>
        /// <param name="uri">The ETP server URI.</param>
        /// <param name="application">The client application name.</param>
        /// <param name="version">The client application version.</param>
        /// <param name="etpSubProtocol">The ETP sub protocol.</param>
        /// <param name="headers">The WebSocket headers.</param>
        public EtpClient(string uri, string application, string version, string etpSubProtocol, IDictionary <string, string> headers)
            : base(EtpWebSocketValidation.GetEtpVersion(etpSubProtocol), new ClientWebSocket(), application, version, headers, true)
        {
            var headerItems = Headers.Union(BinaryHeaders.Where(x => !Headers.ContainsKey(x.Key))).ToList();

            ClientSocket.Options.AddSubProtocol(etpSubProtocol);
            foreach (var item in headerItems)
            {
                ClientSocket.Options.SetRequestHeader(item.Key, item.Value);
            }

            Uri = new Uri(uri);

            // NOTE: User-Agent cannot be set on a .NET Framework ClientWebSocket:
            // https://github.com/dotnet/corefx/issues/26627
        }
Exemple #4
0
        /// <summary>
        /// Called when a WebSocket session is connected.
        /// </summary>
        /// <param name="session">The session.</param>
        private void OnNewSessionConnected(WebSocketSession session)
        {
            Logger.Info($"Handling WebSocket request from {session.RemoteEndPoint}.");

            var ws = new EtpServerWebSocket {
                WebSocketSession = session
            };

            _webSockets[session.SessionID] = ws;

            var headers = new Dictionary <string, string>();

            foreach (var item in session.Items)
            {
                headers[item.Key.ToString()] = item.Value.ToString();
            }

            var version  = EtpWebSocketValidation.GetEtpVersion(session.SubProtocol.Name);
            var encoding = EtpWebSocketValidation.GetEtpEncoding(headers);

            if (!Details.IsVersionSupported(version))
            {
                Logger.Debug($"Sub protocol not supported: {session.SubProtocol.Name}");
                session.Close(CloseReason.ApplicationError);
                return;
            }
            if (encoding == null)
            {
                Logger.Debug($"Error getting ETP encoding.");
                session.Close(CloseReason.ApplicationError);
                return;
            }
            if (!Details.IsEncodingSupported(encoding.Value))
            {
                Logger.Debug($"Encoding not supported: {encoding.Value}");
                session.Close(CloseReason.ApplicationError);
                return;
            }

            var server = ServerManager.CreateServer(ws, version, encoding.Value, headers);

            server.Start();
        }
Exemple #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EtpServer"/> class.
 /// </summary>
 /// <param name="session">The web socket session.</param>
 /// <param name="application">The serve application name.</param>
 /// <param name="version">The server application version.</param>
 /// <param name="headers">The WebSocket or HTTP headers.</param>
 public EtpServer(WebSocketSession session, string application, string version, IDictionary <string, string> headers)
     : base(EtpWebSocketValidation.GetEtpVersion(session.SubProtocol.Name), application, version, headers, false, false)
 {
     SessionId = session.SessionID;
     _session  = session;
 }
Exemple #6
0
        private async Task HandleListenerCore(CancellationToken token)
        {
            try
            {
                HttpListenerContext context = await _httpListener.GetContextAsync().ConfigureAwait(false);

                if (token.IsCancellationRequested)
                {
                    CleanUpContext(context);
                    return;
                }

                var headers = GetCombinedHeaders(context.Request.Headers, context.Request.QueryString);
                if (IsServerCapabilitiesRequest(context.Request))
                {
                    Logger.Info($"Handling ServerCapabilities request from {context.Request.RemoteEndPoint}.");
                    HandleServerCapabilitiesRequest(context.Response, headers);
                    CleanUpContext(context);
                    return;
                }

                if (!context.Request.IsWebSocketRequest)
                {
                    CleanUpContext(context);
                    return;
                }

                Logger.Info($"Handling WebSocket request from {context.Request.RemoteEndPoint}.");

                if (!EtpWebSocketValidation.IsWebSocketRequestUpgrading(headers))
                {
                    context.Response.StatusCode = (int)HttpStatusCode.UpgradeRequired;
                    Logger.Debug($"Invalid web socket request");
                    context.Response.StatusDescription = "Invalid web socket request";
                    CleanUpContext(context);
                    return;
                }

                var preferredProtocol = EtpWebSocketValidation.GetPreferredSubProtocol(headers);
                if (preferredProtocol == null)
                {
                    context.Response.StatusCode        = (int)HttpStatusCode.BadRequest;
                    context.Response.StatusDescription = "Invalid web socket request";
                    Logger.Debug($"Invalid web socket request");
                    CleanUpContext(context);
                    return;
                }

                var encoding = EtpWebSocketValidation.GetEtpEncoding(headers);
                if (encoding == null)
                {
                    context.Response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
                    Logger.Debug($"Error getting ETP encoding.");
                    context.Response.StatusDescription = "Invalid etp-encoding header";
                    CleanUpContext(context);
                    return;
                }
                if (!Details.IsEncodingSupported(encoding.Value))
                {
                    context.Response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
                    Logger.Debug($"Encoding not supported: {encoding.Value}");
                    context.Response.StatusDescription = "Unsupported etp-encoding";
                    CleanUpContext(context);
                    return;
                }

                HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(preferredProtocol).ConfigureAwait(false);

                if (token.IsCancellationRequested)
                {
                    webSocketContext.WebSocket.Dispose();
                    context.Response.Close();
                    return;
                }

                var version = EtpWebSocketValidation.GetEtpVersion(preferredProtocol);
                if (!Details.IsVersionSupported(version))
                {
                    context.Response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
                    Logger.Debug($"Sub protocol not supported: {preferredProtocol}");
                    context.Response.StatusDescription = "Sub protocol not supported";
                    CleanUpContext(context);
                    return;
                }

                var ws = new EtpServerWebSocket {
                    WebSocket = webSocketContext.WebSocket
                };
                var server = ServerManager.CreateServer(ws, version, encoding.Value, headers);
                server.Start();
            }
            catch (Exception ex)
            {
                if (!ex.ExceptionMeansConnectionTerminated())
                {
                    ServerManager.Log("Error: Exception caught when handling a websocket connection: {0}", ex.Message);
                    Logger.DebugFormat("Exception caught when handling a websocket connection: {0}", ex);
                    throw;
                }
            }
        }
Exemple #7
0
        private async Task HandleListener(CancellationToken token)
        {
            try
            {
                // TODO: Handle server cap URL
                HttpListenerContext context = await _httpListener.GetContextAsync();

                if (token.IsCancellationRequested)
                {
                    CleanUpContext(context);
                    return;
                }

                var headers = GetWebSocketHeaders(context.Request.Headers, context.Request.QueryString);
                if (!context.Request.IsWebSocketRequest)
                {
                    CleanUpContext(context);
                    return;
                }

                if (!EtpWebSocketValidation.IsWebSocketRequestUpgrading(headers))
                {
                    context.Response.StatusCode        = (int)HttpStatusCode.UpgradeRequired;
                    context.Response.StatusDescription = "Invalid web socket request";
                    CleanUpContext(context);
                    return;
                }

                var preferredProtocol = EtpWebSocketValidation.GetPreferredSubProtocol(headers);
                if (preferredProtocol == null)
                {
                    context.Response.StatusCode        = (int)HttpStatusCode.BadRequest;
                    context.Response.StatusDescription = "Invalid web socket request";
                    CleanUpContext(context);
                    return;
                }

                if (!EtpWebSocketValidation.IsEtpEncodingValid(headers))
                {
                    context.Response.StatusCode        = (int)HttpStatusCode.PreconditionFailed;
                    context.Response.StatusDescription = "Invalid etp-encoding header";
                    CleanUpContext(context);
                    return;
                }

                HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(preferredProtocol);

                if (token.IsCancellationRequested)
                {
                    webSocketContext.WebSocket.Dispose();
                    context.Response.Close();
                    return;
                }

                var server = new EtpServer(webSocketContext.WebSocket, ApplicationName, ApplicationVersion, headers);

                server.SupportedObjects = SupportedObjects;
                RegisterAll(server);

                _servers[server.SessionId]     = server;
                _serverTasks[server.SessionId] = Task.Run(async() =>
                {
                    try
                    {
                        InvokeSessionConnected(server);
                        await server.HandleConnection(token);
                    }
                    finally
                    {
                        InvokeSessionClosed(server);
                        CleanUpServer(server);
                        webSocketContext.WebSocket.Dispose();
                        CleanUpContext(context);
                    }
                }, token);
            }
            catch (Exception ex)
            {
                if (!ex.ExceptionMeansConnectionTerminated())
                {
                    Log("Error: Exception caught when handling a websocket connection: {0}", ex.Message);
                    Logger.DebugFormat("Exception caught when handling a websocket connection: {0}", ex);
                    throw;
                }
            }
        }