/// <summary> /// Processes the packet within the context. Returns true whether the packet was processed or throttled. /// </summary> /// <param name="channel">The through which the packet is coming/going out.</param> /// <param name="context">The packet context for this operation.</param> /// <returns>True whether the packet was processed or throttled, false otherwise.</returns> public static ProcessingState Process(Emitter.Connection channel, ProcessingContext context) { // Only handle stuff with HTTP Context var httpContext = context.GetSession <HttpContext>(); if (httpContext == null) { return(ProcessingState.Failure); } // Must have Upgrade: websocket string upgradeType; if (!httpContext.Request.TryGetHeader("Upgrade", out upgradeType)) { return(ProcessingState.Failure); } if (String.IsNullOrWhiteSpace(upgradeType)) { return(ProcessingState.Failure); } if (upgradeType.ToLowerInvariant() != "websocket") { return(ProcessingState.Failure); } // This should not be tested with Fiddler2 or another proxy NetTrace.WriteLine("Websocket transport requested", channel, NetTraceCategory.WebSocket); // Get the websocket handler var handler = WebSocketFactory.GetHandler(httpContext.Request, channel, null, null); if (handler == null) { throw new WebSocketException("Requested websocket version is not supported"); } // Upgrade to websocket (handshake) var upgrade = handler.Upgrade(context, httpContext); // Trace the websocket upgrade NetTrace.WriteLine("WebSocket upgrade done", channel, NetTraceCategory.WebSocket); // If it's socket.io 1.x, setup the transport /*if (httpContext.Request.IsFabric) * { * // Set the pipeline * channel.Encoding.PipelineAddBeforeOrLast( * upgrade.Encoder, * Encode.WebSocket); * channel.Decoding.PipelineAddAfterOrFirst( * upgrade.Decoder, * Decode.WebSocket); * * // Make sure the session is set * var session = FabricRegistry.Get(httpContext); * if (session != null) * { * // Unbind the old one * channel.Client.UnbindChannel(channel); * * // Set the session * channel.Client = session; * channel.FabricSession = session.Handle; * channel.FabricEncoding = httpContext.GetFabricEncoding(); * } * }*/ // Trace the channel upgrade NetTrace.WriteLine(channel + " was upgraded to websocket transport", channel, NetTraceCategory.Channel); // There still might be SSL encoding in the pipeline return(ProcessingState.Stop); }
/// <summary> /// Processes the packet within the context. Returns true whether the packet was processed or throttled. /// </summary> /// <param name="channel">The through which the packet is coming/going out.</param> /// <param name="context">The packet context for this operation.</param> /// <returns>True whether the packet was processed or throttled, false otherwise.</returns> public static ProcessingState Process(Connection channel, ProcessingContext context) { // Only handle stuff with HTTP Context var httpContext = context.GetSession <HttpContext>(); if (httpContext == null) { return(ProcessingState.Failure); } try { // Get request var request = httpContext.Request; // We should apply cross-origin resource sharing first if (CorsPolicy.OnRequest(httpContext) == CorsType.Preflight) { // Send pending preflight response. It should be empty. context.Channel.Send(HttpHeaders.Create(httpContext.Response)); return(ProcessingState.Stop); } // Try to handle the incoming request var handler = Service.Http.GetHandler(httpContext, request.Verb, request.Path); if (handler == null) { // Send the error as HTTP 404 HttpResponse.Send404((Emitter.Connection)context.Channel); return(ProcessingState.Stop); } // Trace HTTP request NetTrace.WriteLine(request.HttpVerb.ToString().ToUpper() + " " + request.Path + " handled by " + handler.GetType().ToString(), channel, NetTraceCategory.Http); // Check if session id is present in the cookie. If there is no session id // we create a new session. HttpSession.OnRequest(httpContext); // Check the security and process the request if (handler is ISecureHttpHandler) { ISecureHttpHandler secure = handler as ISecureHttpHandler; if (secure.Security == null || secure.Security.Authorize(httpContext)) { handler.ProcessRequest(httpContext); context.Channel.Send(httpContext.Response); // Send pending } } else { handler.ProcessRequest(httpContext); context.Channel.Send(httpContext.Response); // Send pending } // Keep-Alive or close? if (!httpContext.Response.KeepAlive) { channel.Close(); } return(ProcessingState.Stop); } catch (NonAuthorizedException ex) { // Send the error as HTTP 500 HttpResponse.Send401((Emitter.Connection)context.Channel, ex); return(ProcessingState.Stop); } catch (HttpRedirectException) { // Send the response as it contains the redirect headers context.Channel.Send(httpContext.Response); return(ProcessingState.Stop); } catch (Exception ex) { // Send the error as HTTP 500 HttpResponse.Send500((Emitter.Connection)context.Channel, ex); return(ProcessingState.Stop); } finally { // Release the HTTP context back to the pool httpContext.TryRelease(); } }