Exemplo n.º 1
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;
                }
            }
        }
Exemplo n.º 2
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;
                }
            }
        }