/// <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); }
/// <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(); }
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(); }
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(); }
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(); }
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 }); }
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(); } }
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); }
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"); }
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); }
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(); }
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); } }
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; }
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; } }
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); }
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; }
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); } }
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); }
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); }
/// <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); }
/// <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); }