private bool Handler(FileCache cache, string key, byte[] value, TimeSpan timespan) { HttpResponse header = new HttpResponse(); header.SetBegin(200); header.SetContentType(Path.GetExtension(key)); header.SetHeader("Cache-Control", string.Format("max-age={0}", timespan.Seconds)); header.SetBody(value); return(cache.Add(key, header.Cache.Data, timespan)); }
/// <summary> /// Perform WebSocket server upgrade /// </summary> /// <param name="request">WebSocket upgrade HTTP request</param> /// <param name="response">WebSocket upgrade HTTP response</param> /// <returns>'true' if the WebSocket was successfully upgrade, 'false' if the WebSocket was not upgrade</returns> public bool PerformServerUpgrade(HttpRequest request, HttpResponse response) { if (request.Method != "GET") { return(false); } bool error = false; bool connection = false; bool upgrade = false; bool wsKey = false; bool wsVersion = false; string accept = ""; // Validate WebSocket handshake headers for (int i = 0; i < request.Headers; i++) { var header = request.Header(i); var key = header.Item1; var value = header.Item2; if (string.Compare(key, "Connection", StringComparison.OrdinalIgnoreCase) == 0) { if ((string.Compare(value, "Upgrade", StringComparison.OrdinalIgnoreCase) != 0) && (string.Compare(value, "keep-alive, Upgrade", StringComparison.OrdinalIgnoreCase) != 0)) { error = true; response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Connection' header value must be 'Upgrade' or 'keep-alive, Upgrade'"); break; } connection = true; } else if (string.Compare(key, "Upgrade", StringComparison.OrdinalIgnoreCase) == 0) { if (string.Compare(value, "websocket", StringComparison.OrdinalIgnoreCase) != 0) { error = true; response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Upgrade' header value must be 'websocket'"); break; } upgrade = true; } else if (string.Compare(key, "Sec-WebSocket-Key", StringComparison.OrdinalIgnoreCase) == 0) { if (string.IsNullOrEmpty(value)) { error = true; response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Sec-WebSocket-Key' header value must be non empty"); break; } // Calculate the original WebSocket hash string wskey = value + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; byte[] wshash; using (SHA1Managed sha1 = new SHA1Managed()) { wshash = sha1.ComputeHash(Encoding.UTF8.GetBytes(wskey)); } accept = Convert.ToBase64String(wshash); wsKey = true; } else if (string.Compare(key, "Sec-WebSocket-Version", StringComparison.OrdinalIgnoreCase) == 0) { if (string.Compare(value, "13", StringComparison.OrdinalIgnoreCase) != 0) { error = true; response.MakeErrorResponse(400, "Invalid WebSocket handshaked request: 'Sec-WebSocket-Version' header value must be '13'"); break; } wsVersion = true; } } // Filter out non WebSocket handshake requests if (!connection && !upgrade && !wsKey && !wsVersion) { return(false); } // Failed to perform WebSocket handshake if (!connection || !upgrade || !wsKey || !wsVersion) { if (!error) { response.MakeErrorResponse(400, "Invalid WebSocket response"); } _wsHandler.SendUpgrade(response); return(false); } // Prepare WebSocket upgrade success response response.Clear(); response.SetBegin(101); response.SetHeader("Connection", "Upgrade"); response.SetHeader("Upgrade", "websocket"); response.SetHeader("Sec-WebSocket-Accept", accept); response.SetBody(); // Validate WebSocket upgrade request and response if (!_wsHandler.OnWsConnecting(request, response)) { return(false); } // Send WebSocket upgrade response _wsHandler.SendUpgrade(response); // WebSocket successfully handshaked! WsHandshaked = true; for (int i = 0; i < WsSendMask.Length; i++) { WsSendMask[i] = 0; } _wsHandler.OnWsConnected(request); return(true); }