private static Boolean Handler(NetworkFileCache cache, String key, Byte[] value, TimeSpan timespan) { HttpNetworkResponse header = new HttpNetworkResponse(); header.SetBegin(200); header.SetContentType(Path.GetExtension(key)); header.SetHeader("Cache-Control", $"max-age={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 Boolean PerformServerUpgrade(HttpNetworkRequest request, HttpNetworkResponse response) { if (request.Method != "GET") { return(false); } Boolean error = false; Boolean connection = false; Boolean upgrade = false; Boolean wsKey = false; Boolean wsVersion = false; String accept = ""; // Validate WebSocket handshake headers for (Int32 i = 0; i < request.Headers; ++i) { Tuple <String, String> header = request.Header(i); String key = header.Item1; String value = header.Item2; if (key == "Connection") { if (value != "Upgrade" && value != "keep-alive, Upgrade") { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Connection' header value must be 'Upgrade' or 'keep-alive, Upgrade'", 400); break; } connection = true; } else if (key == "Upgrade") { if (value != "websocket") { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Upgrade' header value must be 'websocket'", 400); break; } upgrade = true; } else if (key == "Sec-WebSocket-Key") { if (String.IsNullOrEmpty(value)) { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Sec-WebSocket-Key' header value must be non empty", 400); 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 (key == "Sec-WebSocket-Version") { if (value != "13") { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Sec-WebSocket-Version' header value must be '13'", 400); 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("Invalid WebSocket response", 400); } _wsHandler.SendResponse(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.SendResponse(response); // WebSocket successfully handshaked! WsHandshaked = true; Array.Fill(WsSendMask, (Byte)0); _wsHandler.OnWsConnected(request); return(true); }