/// <summary> /// The function used to process http request. /// </summary> /// <param name="context">The context of the http request.</param> public override void Process(HttpContext context) { HttpRequestMessage reqMsg = context.Request; if (reqMsg.Method != HttpMethod.Get) { return; } string url = reqMsg.RequestUri.ToString(); int paramPos = url.IndexOf("?"); if (paramPos >= 0) { url = url.Substring(0, paramPos); } string sFilePath = HttpUtility.UrlDecode(url); // sFilePath = sFilePath.Replace("/", "\\"); bool isRootRequest = sFilePath == "/"; string filePath = null; if (isRootRequest) { if (DefaultFiles.Count == 0) { return; } bool isMatch = false; foreach (string fileName in DefaultFiles) { filePath = Path.Combine(RootDir, fileName); if (File.Exists(filePath)) { isMatch = true; break; } } if (!isMatch) { return; } } else { filePath = Path.Combine(RootDir, sFilePath.TrimStart('/')); if (!File.Exists(filePath)) { return; } } string ext = Path.GetExtension(filePath); DateTimeOffset?reqModifyDateTime = null; if (context.Request.Headers.TryGetValues("If-Modified-Since", out IEnumerable <string> vals)) { if (DateTimeOffset.TryParse(vals.First(), out DateTimeOffset outTime)) { reqModifyDateTime = outTime; } } try { FileInfo fi = new FileInfo(filePath); HttpResponseMessage repMsg = ResponseMsgHelper.CreateSimpleRepMsg(); HttpContent content = null; DateTimeOffset fileTime = new DateTimeOffset(fi.LastWriteTimeUtc); bool isFileTimeSame = false; if (reqModifyDateTime != null) { isFileTimeSame = fileTime.Year == reqModifyDateTime.Value.Year && fileTime.Month == reqModifyDateTime.Value.Month && fileTime.Day == reqModifyDateTime.Value.Day && fileTime.Hour == reqModifyDateTime.Value.Hour && fileTime.Minute == reqModifyDateTime.Value.Minute && fileTime.Second == reqModifyDateTime.Value.Second; } if (!isFileTimeSame) { string fileName = Path.GetFileName(filePath); string contentType = MimeDict.First().Value; if (!string.IsNullOrEmpty(ext)) { ext = ext.TrimStart('.').ToLower(); if (MimeDict.TryGetValue(ext, out string temp)) { contentType = temp; } } bool acceptGzip = EnableGZIP && reqMsg.Headers.AcceptEncoding.Any(p => p.Value.ToLower() == "gzip"); if (acceptGzip) { if (fi.Length <= 2 * 1024 || !CompressFileExt.Contains(ext) || fi.Length > MaxCompressLength) { acceptGzip = false; } } if (acceptGzip || fi.Length <= MaxCacheLength) { FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); byte[] data = null; if (acceptGzip) { data = DataZip.CompressToGZIPBytes(fs); } else { data = new byte[fs.Length]; fs.Read(data, 0, data.Length); } fs.Close(); content = new ByteArrayContent(data); content.Headers.ContentLength = data.Length; } else { FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); StreamContent streamContent = new StreamContent(fs); content = streamContent; content.Headers.ContentLength = fi.Length; } MediaTypeHeaderValue headerValue = new MediaTypeHeaderValue(contentType); content.Headers.ContentType = headerValue; content.Headers.Add("Last-Modified", fileTime.ToString("R")); if (acceptGzip) { content.Headers.ContentEncoding.Add("gzip"); } } else { repMsg.StatusCode = System.Net.HttpStatusCode.NotModified; } repMsg.Content = content; context.Response = repMsg; } catch (Exception ex) { context.Response = new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError); //System.Diagnostics.Trace.WriteLine(ex.ToString()); Console.WriteLine(ex.Message); } }
/// <summary> /// The function used to process web socket request. /// </summary> /// <param name="context">The context of the http request.</param> public override void Process(HttpContext context) { HttpRequestMessage reqMsg = context.Request; if (reqMsg.Method != HttpMethod.Get) { return; } HttpResponseMessage repMsg = ResponseMsgHelper.CreateSimpleRepMsg(); string url = reqMsg.RequestUri.ToString(); int paramPos = url.IndexOf("?"); if (paramPos >= 0) { url = url.Substring(0, paramPos); } if (url.ToLower() != _url) { return; } do { repMsg.StatusCode = HttpStatusCode.BadRequest; if (reqMsg.Method != HttpMethod.Get || !reqMsg.Headers.Connection.Contains("Upgrade") || reqMsg.Version < Version.Parse("1.1") || !reqMsg.Headers.Upgrade.Contains(new ProductHeaderValue("websocket"))) { break; } if (!TryGetHeaderValue(reqMsg.Headers, "Sec-WebSocket-Key", out string wsKey)) { break; } if (!TryGetHeaderValue(reqMsg.Headers, "Sec-webSocket-Version", out string wsVersion) || wsVersion != "13") { break; } string protocol = null; if (reqMsg.Headers.TryGetValues("Sec-WebSocket-Protocol", out IEnumerable <string> protocols)) { if (!protocols.Contains("chat")) { break; } protocol = "chat"; } wsKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; string acceptKey = Sha1Signature(wsKey); string wsUrl = $"ws://{reqMsg.Headers.Host}{_url}"; repMsg.StatusCode = HttpStatusCode.SwitchingProtocols; repMsg.Headers.Upgrade.Add(new ProductHeaderValue("websocket")); repMsg.Headers.Connection.Add("Upgrade"); repMsg.Headers.Add("Sec-WebSocket-Accept", acceptKey); if (protocol != null) { repMsg.Headers.Add("Sec-WebSocket-Protocol", protocol); } repMsg.Headers.Add("Sec-WebSocket-Location", wsUrl); } while (false); context.Response = repMsg; }