/// <summary>
        /// authenticate using serialized messages
        /// </summary>
        /// <param name="channel">channel to authenticate</param>
        /// <param name="message">Received message, will be <see cref="AuthenticationRequiredException" /> first time and then responses to your authentication messages</param>
        /// <returns>
        ///   <c>true</c> if authentication process completed.
        /// </returns>
        public bool Process(ITcpChannel channel, object message)
        {
            if (message is AuthenticationRequiredException)
            {
                var handshake = _authenticationMessageFactory.CreateHandshake(_credentials.UserName);
                channel.Send(handshake);
                _state = 1;
                AuthenticationFailed = false;
                return(false);
            }

            if (message is AuthenticationHandshakeReply)
            {
                if (_state != 1)
                {
                    AuthenticationFailed = true;
                    return(true);
                }

                _state = 2;
                var handshakeReply = (AuthenticationHandshakeReply)message;
                _passwordHash = _passwordHasher.HashPassword(_credentials.Password, handshakeReply.AccountSalt);
                var token = _passwordHasher.HashPassword(_passwordHash, handshakeReply.SessionSalt);
                var auth  = _authenticationMessageFactory.CreateAuthentication(token);
                _clientSalt = auth.ClientSalt;
                channel.Send(auth);
                return(false);
            }

            if (message is AuthenticateReply)
            {
                if (_state != 2)
                {
                    AuthenticationFailed = true;
                    return(true);
                }

                var result = (AuthenticateReply)message;
                AuthenticationFailed = true;
                if (result.State == AuthenticateReplyState.Success)
                {
                    var ourToken = _passwordHasher.HashPassword(_passwordHash, _clientSalt);
                    if (!_passwordHasher.Compare(ourToken, result.AuthenticationToken))
                    {
                        return(true);
                    }
                }
                else
                {
                    return(true);
                }

                AuthenticationFailed = false;
                return(true);
            }

            return(false);
        }
示例#2
0
        /// <summary>
        ///     Send message to the remote end point.
        /// </summary>
        /// <param name="message">message to send.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">message</exception>
        /// <remarks>
        ///     <para>
        ///         All messages are being enqueued and sent in order. This method will return when the current message have been
        ///         sent. It
        ///     </para>
        ///     <para>
        ///         The method is thread safe and can be executed from multiple threads.
        ///     </para>
        /// </remarks>
        public async Task SendAsync(object message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (_sendException != null)
            {
                var ex = _sendException;
                _sendException = null;
                throw new AggregateException(ex);
            }
            if (Authenticator != null && Authenticator.AuthenticationFailed)
            {
                throw new AuthenticationDeniedException("Failed to authenticate");
            }

            await _sendQueueSemaphore.WaitAsync();

            _channel.Send(message);


            await _sendCompletedSemaphore.WaitAsync();

            _sendQueueSemaphore.Release();
        }
示例#3
0
        private static void OnMessage(ITcpChannel channel, object message)
        {
            var request  = (HttpRequest)message;
            var response = request.CreateResponse();


            if (request.Uri.AbsolutePath.StartsWith("/restricted"))
            {
                var user = _authenticator.Authenticate(request);
                if (user == null)
                {
                    _authenticator.CreateChallenge(request, response);
                    channel.Send(response);
                    return;
                }


                Console.WriteLine("Logged in: " + user);
            }

            if (request.Uri.AbsolutePath == "/favicon.ico")
            {
                response.StatusCode = 404;
                channel.Send(response);
                return;
            }

            var msg = Encoding.UTF8.GetBytes("Hello world");

            if (request.Uri.ToString().Contains(".jpg"))
            {
                response.Body        = new FileStream(@"C:\users\gaujon01\Pictures\DSC_0231.jpg", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                response.ContentType = "image/jpeg";
            }
            else
            {
                response.Body = new MemoryStream(msg);
                //response.Body.Write(msg, 0, msg.Length);
                response.ContentType = "text/plain";
            }
            channel.Send(response);
            if (request.HttpVersion == "HTTP/1.0")
            {
                channel.Close();
            }
        }
 private void OnDecoderFailure(ITcpChannel channel, Exception error)
 {
     var pos = error.Message.IndexOfAny(new[] {'\r', '\n'});
     var descr = pos == -1 ? error.Message : error.Message.Substring(0, pos);
     var response = new HttpResponseBase(HttpStatusCode.BadRequest, descr, "HTTP/1.1");
     channel.Send(response);
     channel.Close();
 }
示例#5
0
        private static void OnMessage(ITcpChannel channel, object message)
        {
            var request = (HttpRequestBase)message;
            var response = request.CreateResponse();


            if (request.Uri.AbsolutePath.StartsWith("/restricted"))
            {

                var user = _authenticator.Authenticate(request);
                if (user == null)
                {
                    _authenticator.CreateChallenge(request, response);
                    channel.Send(response);
                    return;
                }


                Console.WriteLine("Logged in: " + user);
            }

            if (request.Uri.AbsolutePath == "/favicon.ico")
            {
                response.StatusCode = 404;
                channel.Send(response);
                return;
            }

            var msg = Encoding.UTF8.GetBytes("Hello world");
            if (request.Uri.ToString().Contains(".jpg"))
            {
                response.Body = new FileStream(@"C:\users\gaujon01\Pictures\DSC_0231.jpg", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                response.ContentType = "image/jpeg";
            }
            else
            {
                response.Body = new MemoryStream(msg);
                //response.Body.Write(msg, 0, msg.Length);
                response.ContentType = "text/plain";
            }
            channel.Send(response);
            if (request.HttpVersion == "HTTP/1.0")
                channel.Close();

        }
示例#6
0
        private void OnDecoderFailure(ITcpChannel channel, Exception error)
        {
            var pos      = error.Message.IndexOfAny(new[] { '\r', '\n' });
            var descr    = pos == -1 ? error.Message : error.Message.Substring(0, pos);
            var response = new HttpResponseBase(HttpStatusCode.BadRequest, descr, "HTTP/1.1");

            channel.Send(response);
            channel.Close();
        }
 private void OnDecoderFailure(ITcpChannel channel, Exception error)
 {
     var pos = error.Message.IndexOfAny(new[] {'\r', '\n'});
     var descr = pos == -1 ? error.Message : error.Message.Substring(0, pos);
     var response = new HttpResponse(HttpStatusCode.BadRequest, descr, "HTTP/1.1");
     var counter = (int)channel.Data.GetOrAdd(HttpMessage.PipelineIndexKey, x => 1);
     response.Headers[HttpMessage.PipelineIndexKey] = counter.ToString();
     channel.Send(response);
     channel.Close();
 }
示例#8
0
        private static void OnMessage(ITcpChannel channel, object message)
        {
            var ping = (Ping)message;

            Console.WriteLine("Server received: " + message);
            channel.Send(new Pong
            {
                From = "Server",
                To   = ping.Name
            });
        }
示例#9
0
        private void OnDecoderFailure(ITcpChannel channel, Exception error)
        {
            var pos      = error.Message.IndexOfAny(new[] { '\r', '\n' });
            var descr    = pos == -1 ? error.Message : error.Message.Substring(0, pos);
            var response = new HttpResponseBase(HttpStatusCode.BadRequest, descr, "HTTP/1.1");
            var counter  = (int)channel.Data.GetOrAdd(HttpMessage.PipelineIndexKey, x => 1);

            response.Headers[HttpMessage.PipelineIndexKey] = counter.ToString();
            channel.Send(response);
            channel.Close();
        }
        private static void OnMessage(ITcpChannel channel, object message)
        {
            var request  = (IHttpRequest)message;
            var response = request.CreateResponse();

            if (request.Uri.AbsolutePath == "/favicon.ico")
            {
                response.StatusCode = 404;
                channel.Send(response);
                return;
            }

            var msg = Encoding.UTF8.GetBytes("Hello world");

            response.Body        = new MemoryStream(msg);
            response.ContentType = "text/plain";
            channel.Send(response);

            if (request.HttpVersion == "HTTP/1.0")
            {
                channel.Close();
            }
        }
示例#11
0
        private bool AuthenticateUser(ITcpChannel channel, HttpRequest request)
        {
            if (channel.Data["Principal"] != null)
            {
                Thread.CurrentPrincipal = (IPrincipal)channel.Data["Principal"];
                return(true);
            }

            try
            {
                var user = Authenticator.Authenticate(request);
                if (user == null)
                {
                    return(true);
                }

                if (PrincipalFactory != null)
                {
                    var ctx = new PrincipalFactoryContext(request, user);
                    Thread.CurrentPrincipal   = PrincipalFactory.Create(ctx);
                    channel.Data["Principal"] = Thread.CurrentPrincipal;
                    return(true);
                }

                var roles = user as IUserWithRoles;
                if (roles == null)
                {
                    throw new InvalidOperationException(
                              "You must specify a PrincipalFactory if you do not return a IUserWithRoles from your IAccountService.");
                }

                Thread.CurrentPrincipal   = new GenericPrincipal(new GenericIdentity(user.Username), roles.RoleNames);
                channel.Data["Principal"] = Thread.CurrentPrincipal;
            }
            catch (HttpException ex)
            {
                if (Logger != null)
                {
                    Logger("Authentication failed.\r\nException:\r\n" + ex.ToString());
                }
                var response = request.CreateResponse();
                response.StatusCode   = ex.HttpCode;
                response.ReasonPhrase = FirstLine(ex.Message);
                channel.Send(response);
                return(false);
            }

            return(true);
        }
示例#12
0
        private void OnServerMessageReceived(ITcpChannel channel, object message)
        {
            var s = message as string;

            if (s == null)
            {
                var f = (Stream)message;
                if (f == null)
                {
                    throw new Exception("Server received unexpected object type.");
                }
            }
            Console.WriteLine("Server received: " + message);
            channel.Send("world");
        }
示例#13
0
        private static void OnServerMessage(ITcpChannel channel, object message)
        {
            var contract = message as MessageContract;

            if (contract != null)
            {
                var type = Type.GetType(contract.ServiceType);
                if (type != null)
                {
                    var srv    = ObjectFactory.GetInstance(type);
                    var result = type.GetMethod(contract.MethodName).Invoke(srv, contract.Arguments); // find better/faster way
                    channel.Send(result);
                }
            }
            Debug.WriteLine("Received message type: " + message.GetType().Name);
        }
示例#14
0
        private static void OnServerMessageReceived(ITcpChannel channel, object message)
        {
            var ping = (Ping)message;

            if (ping == null)
            {
                throw new Exception("Server received unexpected object type.");
            }

            Console.WriteLine("Server received: " + message);
            channel.Send(new Pong
            {
                From = "Server",
                To   = ping.Name
            });
        }
        /// <summary>
        ///     Send an object
        /// </summary>
        /// <param name="message">Message to send</param>
        /// <returns>completion task (completed once the message have been delivered).</returns>
        /// <remarks>
        ///     <para>All objects are enqueued and sent in order as soon as possible</para>
        /// </remarks>
        public Task SendAsync(object message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (_sendCompletionSource != null)
            {
                throw new InvalidOperationException("There is already a pending send operation.");
            }

            _sendCompletionSource = new TaskCompletionSource <object>();
            _sendCompletionSource.Task.ConfigureAwait(false);

            _channel.Send(message);
            return(_sendCompletionSource.Task);
        }
        /// <summary>
        ///     SendAsync(). It is used internally to send command to FreeSwitch
        /// </summary>
        /// <param name="message">the command to send</param>
        /// <returns>Async task</returns>
        protected async Task SendAsync(object message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            if (_sendException != null)
            {
                var ex = _sendException;
                _sendException = null;
                throw new AggregateException(ex);
            }
            await _sendQueueSemaphore.WaitAsync();

            _channel.Send(message);
            await _sendCompletedSemaphore.WaitAsync();

            _sendQueueSemaphore.Release();
        }
示例#17
0
        private void OnDecoderFailure(ITcpChannel channel, Exception error)
        {
            if (!channel.IsConnected || error is SocketException)
            {
                return;
            }

            try
            {
                var pos      = error.Message.IndexOfAny(new[] { '\r', '\n' });
                var descr    = pos == -1 ? error.Message : error.Message.Substring(0, pos);
                var response = new HttpResponse(HttpStatusCode.BadRequest, descr, "HTTP/1.1");
                var counter  = (int)channel.Data.GetOrAdd(HttpMessage.PipelineIndexKey, x => 1);
                response.Headers[HttpMessage.PipelineIndexKey] = counter.ToString();
                channel.Send(response);
                channel.Close();
            }
            catch (Exception ex)
            {
                OnListenerError(ex);
            }
        }
示例#18
0
        private async Task ExecuteConnectModules(ITcpChannel channel, ClientContext context)
        {
            var result = ModuleResult.Continue;

            for (var i = 0; i < _modules.Length; i++)
            {
                var connectMod = _modules[i] as IConnectionEvents;
                if (connectMod == null)
                {
                    continue;
                }

                try
                {
                    result = await connectMod.OnClientConnected(context);
                }
                catch (Exception exception)
                {
                    context.Error = exception;
                    result        = ModuleResult.SendResponse;
                }

                if (result != ModuleResult.Continue)
                {
                    break;
                }
            }

            switch (result)
            {
            case ModuleResult.Disconnect:
                channel.Close();
                break;

            case ModuleResult.SendResponse:
                channel.Send(context.ResponseMessage);
                break;
            }
        }
        private bool AuthenticateUser(ITcpChannel channel, IHttpRequest request)
        {
            if (channel.Data["Principal"] != null)
            {
                Thread.CurrentPrincipal = (IPrincipal)channel.Data["Principal"];
                return true;
            }

            try
            {
                var user = AuthenticationService.Authenticate(request);
                if (user == null)
                    return true;

                if (PrincipalFactory != null)
                {
                    var ctx = new PrincipalFactoryContext(request, user);
                    Thread.CurrentPrincipal = PrincipalFactory.Create(ctx);
                    channel.Data["Principal"] = Thread.CurrentPrincipal;
                    return true;
                }

                var roles = user as IUserWithRoles;
                if (roles == null)
                    throw new InvalidOperationException(
                        "You must specify a PrincipalFactory if you do not return a IUserWithRoles from your IAccountService.");

                Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(user.Username), roles.RoleNames);
                channel.Data["Principal"] = Thread.CurrentPrincipal;
            }
            catch (HttpException ex)
            {
                var response = request.CreateResponse();
                response.StatusCode = ex.HttpCode;
                response.ReasonPhrase = FirstLine(ex.Message);
                ;
                channel.Send(response);
                return false;
            }

            return true;
        }
示例#20
0
        private async Task ExecuteConnectModules(ITcpChannel channel, IClientContext context)
        {
            var result = ModuleResult.Continue;

            for (var i = 0; i < _modules.Length; i++)
            {
                var connectMod = _modules[i] as IConnectionEvents;
                if (connectMod == null)
                    continue;

                try
                {
                    result = await connectMod.OnClientConnected(context);
                }
                catch (Exception exception)
                {
                    context.Error = exception;
                    result = ModuleResult.SendResponse;
                }

                if (result != ModuleResult.Continue)
                    break;
            }

            switch (result)
            {
                case ModuleResult.Disconnect:
                    channel.Close();
                    break;
                case ModuleResult.SendResponse:
                    channel.Send(context.ResponseMessage);
                    break;
            }
        }
示例#21
0
        private async Task ExecuteModules(ITcpChannel channel, ClientContext context)
        {
            var result = ModuleResult.Continue;

            for (var i = 0; i < _modules.Length; i++)
            {
                try
                {
                    await _modules[i].BeginRequestAsync(context);
                }
                catch (Exception exception)
                {
                    context.Error = exception;
                    result = ModuleResult.SendResponse;
                }
            }


            if (result == ModuleResult.Continue)
            {
                for (var i = 0; i < _modules.Length; i++)
                {
                    try
                    {
                        result = await _modules[i].ProcessAsync(context);
                    }
                    catch (Exception exception)
                    {
                        context.Error = exception;
                        result = ModuleResult.SendResponse;
                    }

                    if (result != ModuleResult.Continue)
                        break;
                }
            }


            try
            {
                await EndRequestAsync(context);
            }
            catch (Exception exception)
            {
                if (context.ResponseMessage == null)
                    context.ResponseMessage = exception;
                result = ModuleResult.Disconnect;
            }

            if (context.ResponseMessage != null)
                channel.Send(context.ResponseMessage);

            if (result == ModuleResult.Disconnect)
            {
                channel.Close();
            }
        }
        /// <summary>
        /// Handles the upgrade
        /// </summary>
        /// <param name="source">Channel that we've received a request from</param>
        /// <param name="msg">Message received.</param>
        protected override void OnMessage(ITcpChannel source, object msg)
        {
            var httpMessage = msg as IHttpMessage;
            if (WebSocketUtils.IsWebSocketUpgrade(httpMessage))
            {
                if (httpMessage is IHttpRequest) // server mode
                {
                    var args = new WebSocketClientConnectEventArgs(source, (IHttpRequest) httpMessage);
                    WebSocketClientConnect(this, args);

                    if (args.MayConnect)
                    {
                        var webSocketKey = httpMessage.Headers["Sec-WebSocket-Key"];

                        // TODO: why not provide the response in the WebSocketClientConnectEventArgs event?
                        var response = new WebSocketUpgradeResponse(webSocketKey);

                        source.Send(response);

                        WebSocketClientConnected(this,
                            new WebSocketClientConnectedEventArgs(source, (IHttpRequest) httpMessage, response));
                    }
                    else if (args.SendResponse)
                    {
                        var response = new HttpResponseBase(HttpStatusCode.NotImplemented, "Not Implemented", "HTTP/1.1");
                        if (args.Response != null)
                            response.Body = args.Response;

                        source.Send(response);
                    }
                    return;
                }

                if (httpMessage is IHttpResponse) // client mode
                {
                    WebSocketClientConnected(this,
                        new WebSocketClientConnectedEventArgs(source, null, (IHttpResponse) httpMessage));
                }
            }

            var webSocketMessage = msg as IWebSocketMessage;
            if (webSocketMessage != null)
            {
                // standard message responses handled by listener
                switch (webSocketMessage.Opcode)
                {
                    case WebSocketOpcode.Ping:
                        source.Send(new WebSocketMessage(WebSocketOpcode.Pong, webSocketMessage.Payload));
                        return;
                    case WebSocketOpcode.Close:
                        source.Send(new WebSocketMessage(WebSocketOpcode.Close));
                        source.Close();

                        WebSocketClientDisconnected(this,
                            new ClientDisconnectedEventArgs(source, new Exception("WebSocket closed")));
                        return;
                }

                _webSocketMessageReceived(source, webSocketMessage);
                return;
            }

            base.OnMessage(source, msg);
        }
示例#23
0
 private void OnClientMessage(ITcpChannel channel, object message)
 {
     if (message is IQuery)
     {
         var dto       = (IQuery)message;
         var type      = message.GetType();
         var replyType = type.BaseType.GetGenericArguments()[0];
         var method    = _queryMethod.MakeGenericMethod(type, replyType);
         var task      = (Task)method.Invoke(this, new object[] { message });
         task.ContinueWith(t =>
         {
             if (t.Exception != null)
             {
                 channel.Send(new ClientResponse(dto.QueryId, task.Exception));
             }
             else
             {
                 channel.Send(new ClientResponse(dto.QueryId, ((dynamic)task).Result));
             }
         });
     }
     else if (message is Command)
     {
         var dto    = (Command)message;
         var type   = message.GetType();
         var method = _commandMethod.MakeGenericMethod(type);
         try
         {
             var task = (Task)method.Invoke(this, new object[] { message });
             task.ConfigureAwait(false);
             task.ContinueWith(t =>
             {
                 if (t.Exception != null)
                 {
                     channel.Send(new ClientResponse(dto.CommandId, task.Exception));
                 }
                 else
                 {
                     channel.Send(new ClientResponse(dto.CommandId, null));
                 }
             });
         }
         catch (Exception exception)
         {
             channel.Send(new ClientResponse(dto.CommandId, exception));
         }
     }
     if (message is IRequest)
     {
         var dto       = (IRequest)message;
         var type      = message.GetType();
         var replyType = type.BaseType.GetGenericArguments()[0];
         var method    = _requestMethod.MakeGenericMethod(type, replyType);
         var task      = (Task)method.Invoke(this, new object[] { message });
         task.ContinueWith(t =>
         {
             if (t.Exception != null)
             {
                 channel.Send(new ClientResponse(dto.RequestId, task.Exception));
             }
             else
             {
                 channel.Send(new ClientResponse(dto.RequestId, ((dynamic)task).Result));
             }
         });
     }
     if (message is ApplicationEvent)
     {
         var dto  = (ApplicationEvent)message;
         var task = _eventBus.PublishAsync(dto);
         task.ContinueWith(t =>
         {
             if (t.Exception != null)
             {
                 channel.Send(new ClientResponse(dto.EventId, task.Exception));
             }
             else
             {
                 channel.Send(new ClientResponse(dto.EventId, null));
             }
         });
     }
 }
        private void OnMessage(ITcpChannel channel, object message)
        {
            var msg = (HttpRequest)message;

            channel.Send(msg.CreateResponse());
        }
        /// <summary>
        /// authenticate using serialized messages
        /// </summary>
        /// <param name="channel">channel to authenticate</param>
        /// <param name="message">Received message, will be <see cref="AuthenticationRequiredException" /> first time and then responses to your authentication messages</param>
        /// <returns>
        ///   <c>true</c> if authentication process completed.
        /// </returns>
        public bool Process(ITcpChannel channel, object message)
        {
            if (message is AuthenticationRequiredException)
            {
                var handshake = _authenticationMessageFactory.CreateHandshake(_credentials.UserName);
                channel.Send(handshake);
                _state = 1;
                AuthenticationFailed = false;
                return false;
            }

            if (message is AuthenticationHandshakeReply)
            {
                if (_state != 1)
                {
                    AuthenticationFailed = true;
                    return true;
                }

                _state = 2;
                var handshakeReply = (AuthenticationHandshakeReply)message;
                _passwordHash = _passwordHasher.HashPassword(_credentials.Password, handshakeReply.AccountSalt);
                var token = _passwordHasher.HashPassword(_passwordHash, handshakeReply.SessionSalt);
                var auth = _authenticationMessageFactory.CreateAuthentication(token);
                _clientSalt = auth.ClientSalt;
                channel.Send(auth);
                return false;
            }

            if (message is AuthenticateReply)
            {
                if (_state != 2)
                {
                    AuthenticationFailed = true;
                    return true;
                }

                var result = (AuthenticateReply)message;
                AuthenticationFailed = true;
                if (result.State == AuthenticateReplyState.Success)
                {
                    var ourToken = _passwordHasher.HashPassword(_passwordHash, _clientSalt);
                    if (!_passwordHasher.Compare(ourToken, result.AuthenticationToken))
                        return true;

                }
                else
                    return true;

                AuthenticationFailed = false;
                return true;
            }

            return false;
        }
示例#26
0
        private void OnWebsocketMessage(ITcpChannel channel, object message)
        {
            var request = (WebSocketRequest)message;

            if (request.Opcode != WebSocketOpcode.Text)
            {
                Logger("Unexpected msg");
                return;
            }

            var streamReader = new StreamReader(request.Payload);
            var data         = streamReader.ReadToEnd();
            var pos          = data.IndexOf(':');

            if (pos == -1 || pos > 50)
            {
                Logger("cqsObjectName is missing.");
                return;
            }

            var cqsName = data.Substring(0, pos);
            var json    = data.Substring(pos + 1);

            Type type;

            if (!_cqsTypes.TryGetValue(cqsName, out type))
            {
                var response = CreateWebSocketResponse(@"{ ""error"": ""Unknown type: " + cqsName + "\" }");
                channel.Send(response);
                Logger("Unknown type: " + cqsName + ".");
                return;
            }


            var            cqs = SimpleJson.DeserializeObject(json, type);
            ClientResponse cqsReplyObject;

            try
            {
                cqsReplyObject = _messageProcessor.ProcessAsync(cqs).Result;
            }
            catch (HttpException ex)
            {
                var responseJson = SimpleJson.SerializeObject(new
                {
                    error      = ex.Message,
                    statusCode = ex.HttpCode
                });
                var response = CreateWebSocketResponse(responseJson);
                channel.Send(response);
                return;
            }
            catch (Exception ex)
            {
                var responseJson = SimpleJson.SerializeObject(new
                {
                    error      = ex.Message,
                    statusCode = 500
                });
                var response = CreateWebSocketResponse(responseJson);
                channel.Send(response);
                return;
            }


            if (cqsReplyObject.Body is Exception)
            {
                var responseJson = SimpleJson.SerializeObject(new
                {
                    error      = ((Exception)cqsReplyObject.Body).Message,
                    statusCode = 500
                });
                var response = CreateWebSocketResponse(responseJson);
                channel.Send(response);
            }
            else
            {
                json = SimpleJson.SerializeObject(cqsReplyObject.Body);
                var reply = CreateWebSocketResponse(json);
                channel.Send(reply);
            }
        }
示例#27
0
        private void OnMessage(ITcpChannel channel, object message)
        {
            var request = (HttpRequestBase)message;

            if (_requestFilter != null)
            {
                var resp = _requestFilter(channel, request);
                if (resp != null)
                {
                    channel.Send(resp);
                    return;
                }
            }
            var name       = request.Headers["X-Cqs-Type"];
            var dotNetType = request.Headers["X-Cqs-Object-Type"];
            var cqsName    = request.Headers["X-Cqs-Name"];

            if (Authenticator != null)
            {
                if (!AuthenticateUser(channel, request))
                {
                    return;
                }
            }

            Type type;

            if (!string.IsNullOrEmpty(dotNetType))
            {
                type = Type.GetType(dotNetType);
                if (type == null)
                {
                    var response = request.CreateResponse();
                    response.StatusCode   = 400;
                    response.ReasonPhrase = "Unknown type: " + dotNetType;
                    Logger("Unknown type: " + dotNetType + " for " + request.Uri);
                    channel.Send(response);
                    return;
                }
            }
            else if (!string.IsNullOrEmpty(cqsName))
            {
                if (!_cqsTypes.TryGetValue(cqsName, out type))
                {
                    var response = request.CreateResponse();
                    response.StatusCode   = 400;
                    response.ReasonPhrase = "Unknown type: " + cqsName;
                    Logger("Unknown type: " + cqsName + " for " + request.Uri);
                    channel.Send(response);
                    return;
                }
            }
            else
            {
                var response = request.CreateResponse();
                response.StatusCode   = 400;
                response.ReasonPhrase =
                    "Expected a class name in the header 'X-Cqs-Name' or a .NET type name in the header 'X-Cqs-Object-Type'.";
                Logger(
                    "Expected a class name in the header 'X-Cqs-Name' or a .NET type name in the header 'X-Cqs-Object-Type' for " +
                    request.Uri);
                channel.Send(response);
                return;
            }


            string json = "{}";

            //empty json
            if (request.Body != null)
            {
                var reader = new StreamReader(request.Body);
                json = reader.ReadToEnd();
            }

            var            cqs            = SimpleJson.DeserializeObject(json, type);
            ClientResponse cqsReplyObject = null;

            Exception ex = null;

            try
            {
                cqsReplyObject = _messageProcessor.ProcessAsync(cqs).Result;
            }
            catch (AggregateException e1)
            {
                ex = e1.InnerException;
            }

            if (ex is HttpException)
            {
                var response = request.CreateResponse();
                response.StatusCode   = ((HttpException)ex).HttpCode;
                response.ReasonPhrase = FirstLine(ex.Message);
                channel.Send(response);
                return;
            }
            else if (ex is AuthorizationException)
            {
                var authEx   = (AuthorizationException)ex;
                var response = request.CreateResponse();
                response.StatusCode   = 401;
                response.ReasonPhrase = FirstLine(ex.Message);
                channel.Send(response);
                return;
            }
            else if (ex != null)
            {
                var response = request.CreateResponse();
                response.StatusCode   = 500;
                response.ReasonPhrase = FirstLine(ex.Message);
                channel.Send(response);
                return;
            }

            var reply = request.CreateResponse();

            reply.ContentType = "application/json";

            // for instance commands do not have a return value.
            if (cqsReplyObject.Body != null)
            {
                reply.AddHeader("X-Cqs-Object-Type", cqsReplyObject.Body.GetType().GetSimpleAssemblyQualifiedName());
                reply.AddHeader("X-Cqs-Name", cqsReplyObject.Body.GetType().Name);
                if (cqsReplyObject.Body is Exception)
                {
                    reply.StatusCode = 500;
                }

                json = SimpleJson.SerializeObject(cqsReplyObject.Body);
                var buffer = Encoding.UTF8.GetBytes(json);
                reply.Body = new MemoryStream();
                reply.Body.Write(buffer, 0, buffer.Length);
            }
            else
            {
                reply.StatusCode = (int)HttpStatusCode.NoContent;
            }

            channel.Send(reply);
        }
示例#28
0
        private async Task ExecuteModules(ITcpChannel channel, ClientContext context)
        {
            var result = ModuleResult.Continue;

            for (var i = 0; i < _modules.Length; i++)
            {
                try
                {
                    await _modules[i].BeginRequestAsync(context);
                }
                catch (Exception exception)
                {
                    context.Error = exception;
                    result        = ModuleResult.SendResponse;
                }
            }


            if (result == ModuleResult.Continue)
            {
                for (var i = 0; i < _modules.Length; i++)
                {
                    try
                    {
                        result = await _modules[i].ProcessAsync(context);
                    }
                    catch (Exception exception)
                    {
                        context.Error = exception;
                        result        = ModuleResult.SendResponse;
                    }

                    if (result != ModuleResult.Continue)
                    {
                        break;
                    }
                }
            }


            try
            {
                await EndRequestAsync(context);
            }
            catch (Exception exception)
            {
                if (context.ResponseMessage == null)
                {
                    context.ResponseMessage = exception;
                }
                result = ModuleResult.Disconnect;
            }

            if (context.ResponseMessage != null)
            {
                channel.Send(context.ResponseMessage);
            }

            if (result == ModuleResult.Disconnect)
            {
                channel.Close();
            }
        }
        private void OnMessage(ITcpChannel channel, object message)
        {
            var request = (HttpRequest) message;

            if (_requestFilter != null)
            {
                var resp = _requestFilter(channel, request);
                if (resp != null)
                {
                    channel.Send(resp);
                    return;
                }
            }
            var name = request.Headers["X-Cqs-Type"];
            var dotNetType = request.Headers["X-Cqs-Object-Type"];
            var cqsName = request.Headers["X-Cqs-Name"];

            if (Authenticator != null)
            {
                if (!AuthenticateUser(channel, request))
                    return;
            }

            var json = "{}";
            if (request.Body != null)
            {
                var reader = new StreamReader(request.Body);
                json = reader.ReadToEnd();
            }

            object cqsObject;
            if (!string.IsNullOrEmpty(dotNetType))
            {
                cqsObject = _cqsObjectMapper.Deserialize(dotNetType, json);
                if (cqsObject == null)
                {
                    var response = request.CreateResponse();
                    response.StatusCode = 400;
                    response.ReasonPhrase = "Unknown type: " + dotNetType;
                    Logger("Unknown type: " + dotNetType + " for " + request.Uri);
                    channel.Send(response);
                    return;
                }
            }
            else if (!string.IsNullOrEmpty(cqsName))
            {
                cqsObject = _cqsObjectMapper.Deserialize(cqsName, json);
                if (cqsObject == null)
                {
                    var response = request.CreateResponse();
                    response.StatusCode = 400;
                    response.ReasonPhrase = "Unknown type: " + cqsName;
                    Logger("Unknown type: " + cqsName + " for " + request.Uri);
                    channel.Send(response);
                    return;
                }
            }
            else
            {
                var response = request.CreateResponse();
                response.StatusCode = 400;
                response.ReasonPhrase =
                    "Expected a class name in the header 'X-Cqs-Name' or a .NET type name in the header 'X-Cqs-Object-Type'.";
                Logger(
                    "Expected a class name in the header 'X-Cqs-Name' or a .NET type name in the header 'X-Cqs-Object-Type' for " +
                    request.Uri);
                channel.Send(response);
                return;
            }


            ClientResponse cqsReplyObject = null;
            Exception ex = null;
            try
            {
                cqsReplyObject = _messageProcessor.ProcessAsync(cqsObject).Result;
            }
            catch (AggregateException e1)
            {
                 ex = e1.InnerException;
            }

            if (ex is HttpException)
            {
                Logger("Failed to process " + json + ", Exception:\r\n" + ex);
                var response = request.CreateResponse();
                response.StatusCode = ((HttpException) ex).HttpCode;
                response.ReasonPhrase = FirstLine(ex.Message);
                channel.Send(response);
                return;
            }
            if (ex is AuthorizationException)
            {
                Logger("Failed to process " + json + ", Exception:\r\n" + ex);
                var authEx = (AuthorizationException)ex;
                var response = request.CreateResponse();
                response.StatusCode = 401;
                response.ReasonPhrase = FirstLine(ex.Message);
                channel.Send(response);
                return;
            }
            if (ex != null)
            {
                Logger("Failed to process " + json + ", Exception:\r\n" + ex);
                var response = request.CreateResponse();
                response.StatusCode = 500;
                response.ReasonPhrase = FirstLine(ex.Message);
                channel.Send(response);
                return;
            }

            var reply = request.CreateResponse();
            reply.ContentType = "application/json;encoding=utf8";

            // for instance commands do not have a return value.
            if (cqsReplyObject.Body != null)
            {
                reply.AddHeader("X-Cqs-Object-Type", cqsReplyObject.Body.GetType().GetSimpleAssemblyQualifiedName());
                reply.AddHeader("X-Cqs-Name", cqsReplyObject.Body.GetType().Name);
                if (cqsReplyObject.Body is Exception)
                    reply.StatusCode = 500;

                var contentType = "application/json;encoding=utf8";
                json = CqsSerializer == null
                    ? SimpleJson.SerializeObject(cqsReplyObject.Body)
                    : CqsSerializer.Serialize(cqsReplyObject.Body, out contentType);
                reply.ContentType = contentType;

                var buffer = Encoding.UTF8.GetBytes(json);
                reply.Body = new MemoryStream();
                reply.Body.Write(buffer, 0, buffer.Length);
            }
            else
                reply.StatusCode = (int) HttpStatusCode.NoContent;

            channel.Send(reply);
        }
示例#30
0
        /// <summary>
        ///     Always revoke since we do not want incoming messages to be queued up for receive operations.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private ClientFilterResult OnMessageReceived(ITcpChannel channel, object message)
        {
            if (message is AuthenticationRequiredException || _continueAuthenticate)
            {
                var authenticator = Authenticator;
                if (authenticator != null)
                {
                    if (!authenticator.AuthenticationFailed)
                    {
                        if (authenticator.RequiresRawData)
                        {
                            channel.BufferPreProcessor = AuthenticateBytes;
                        }
                        else
                        {
                            _continueAuthenticate = authenticator.Process(channel, message);
                            if (!_continueAuthenticate)
                            {
                                if (_lastSentItem != null)
                                {
                                    channel.Send(_lastSentItem);
                                }
                            }
                        }
                    }
                }
            }

            //currently authentication etc are not wrapped, so we need to do it like this.
            var result = message as ClientResponse;

            if (result == null)
            {
                Waiter waiter;
                if (_response.Count != 1)
                {
                    throw new InvalidOperationException(
                              "More than one pending message and we received an unwrapped object: " + message);
                }

                var key = _response.Keys.First();
                if (!_response.TryRemove(key, out waiter))
                {
                    //TODO: LOG
                    return(ClientFilterResult.Revoke);
                }
                waiter.Trigger(message);
            }

            else
            {
                Waiter waiter;
                if (!_response.TryRemove(result.Identifier, out waiter))
                {
                    //TODO: LOG
                    return(ClientFilterResult.Revoke);
                }
                waiter.Trigger(result.Body);
            }



            return(ClientFilterResult.Revoke);
        }
示例#31
0
        /// <summary>
        /// Handles the upgrade
        /// </summary>
        /// <param name="source">Channel that we've received a request from</param>
        /// <param name="msg">Message received.</param>
        protected override void OnMessage(ITcpChannel source, object msg)
        {
            var httpMessage = msg as IHttpMessage;

            if (WebSocketUtils.IsWebSocketUpgrade(httpMessage))
            {
                if (httpMessage is IHttpRequest) // server mode
                {
                    var args = new WebSocketClientConnectEventArgs(source, (IHttpRequest)httpMessage);
                    WebSocketClientConnect(this, args);

                    if (args.MayConnect)
                    {
                        var webSocketKey = httpMessage.Headers["Sec-WebSocket-Key"];

                        // TODO: why not provide the response in the WebSocketClientConnectEventArgs event?
                        var response = new WebSocketUpgradeResponse(webSocketKey);

                        source.Send(response);

                        WebSocketClientConnected(this,
                                                 new WebSocketClientConnectedEventArgs(source, (IHttpRequest)httpMessage, response));
                    }
                    else
                    {
                        var response = new HttpResponseBase(HttpStatusCode.NotImplemented, "Not Implemented", "HTTP/1.1");
                        if (args.Response != null)
                        {
                            response.Body = args.Response;
                        }

                        source.Send(response);
                    }
                    return;
                }

                if (httpMessage is IHttpResponse) // client mode
                {
                    WebSocketClientConnected(this,
                                             new WebSocketClientConnectedEventArgs(source, null, (IHttpResponse)httpMessage));
                }
            }

            var webSocketMessage = msg as IWebSocketMessage;

            if (webSocketMessage != null)
            {
                // standard message responses handled by listener
                switch (webSocketMessage.Opcode)
                {
                case WebSocketOpcode.Ping:
                    source.Send(new WebSocketMessage(WebSocketOpcode.Pong, webSocketMessage.Payload));
                    return;

                case WebSocketOpcode.Close:
                    source.Send(new WebSocketMessage(WebSocketOpcode.Close));
                    source.Close();

                    WebSocketClientDisconnected(this,
                                                new ClientDisconnectedEventArgs(source, new Exception("WebSocket closed")));
                    return;
                }

                _webSocketMessageReceived(source, webSocketMessage);
                return;
            }

            base.OnMessage(source, msg);
        }
        private void OnWebsocketMessage(ITcpChannel channel, object message)
        {
            var request = (WebSocketRequest)message;
            if (request.Opcode != WebSocketOpcode.Text)
            {
                Logger("Unexpected msg");
                return;
            }

            var streamReader = new StreamReader(request.Payload);
            var data = streamReader.ReadToEnd();
            var pos = data.IndexOf(':');
            if (pos == -1 || pos > 50)
            {
                Logger("cqsObjectName is missing.");
                return;
            }

            var cqsName = data.Substring(0, pos);
            var json = data.Substring(pos + 1);

            Type type;
            if (!_cqsTypes.TryGetValue(cqsName, out type))
            {
                var response = CreateWebSocketResponse(@"{ ""error"": ""Unknown type: " + cqsName + "\" }");
                channel.Send(response);
                Logger("Unknown type: " + cqsName + ".");
                return;
            }


            var cqs = SimpleJson.DeserializeObject(json, type);
            ClientResponse cqsReplyObject;

            try
            {
                cqsReplyObject = _messageProcessor.ProcessAsync(cqs).Result;
            }
            catch (HttpException ex)
            {
                var responseJson = SimpleJson.SerializeObject(new
                {
                    error = ex.Message,
                    statusCode = ex.HttpCode
                });
                var response = CreateWebSocketResponse(responseJson);
                channel.Send(response);
                return;
            }
            catch (Exception ex)
            {
                var responseJson = SimpleJson.SerializeObject(new
                {
                    error = ex.Message,
                    statusCode = 500
                });
                var response = CreateWebSocketResponse(responseJson);
                channel.Send(response);
                return;
            }


            if (cqsReplyObject.Body is Exception)
            {
                var responseJson = SimpleJson.SerializeObject(new
                {
                    error = ((Exception)cqsReplyObject.Body).Message,
                    statusCode = 500
                });
                var response = CreateWebSocketResponse(responseJson);
                channel.Send(response);
            }
            else
            {
                json = SimpleJson.SerializeObject(cqsReplyObject.Body);
                var reply = CreateWebSocketResponse(json);
                channel.Send(reply);
            }
        }