using System; using System.IO; using MimeSharp; using SBRL.GlidingSquirrel.Websocket; using SBRL.Utilities; using System.Collections.Generic; using System.Reflection; namespace Nibriboard.Client { public class HttpEmbeddedFileHandler : WebsocketsServer { private string filePrefix; private Mime mimeTypeFinder = new Mime(); private Dictionary mimeTypeOverrides = new Dictionary() { ["application/xhtml+xml"] = "text/html", ["application/tei+xml"] = "image/x-icon" }; private List embeddedFiles = new List(EmbeddedFiles.ResourceList); public HttpEmbeddedFileHandler(string inFilePrefix) { filePrefix = inFilePrefix; } public void HandleRequest(string uri, HttpRequest request, HttpResponse response, HttpContext context) { StreamWriter responseData = new StreamWriter(response.Content) { AutoFlush = true }; if (request.Method != HttpMethod.Get) { response.ResponseCode = HttpResponseCode.MethodNotAllowed; response.ContentType = "text/plain"; responseData.WriteLine("Error: That method isn't supported yet."); logRequest(request, response); return; } string expandedFilePath = getEmbeddedFileReference(request.URI); if (!embeddedFiles.Contains(expandedFilePath)) { expandedFilePath += "index.html"; } if (!embeddedFiles.Contains(expandedFilePath)) { response.ResponseCode = HttpResponseCode.NotFound; response.ContentType = "text/plain"; responseData.WriteLine("Can't find {0}.", expandedFilePath); logRequest(request, response); return; } response.ContentType = getMimeType(expandedFilePath); response.Headers.Add("content-type", response.ContentType); byte[] embeddedFile = EmbeddedFiles.ReadAllBytes(expandedFilePath); response.ContentLength = embeddedFile.Length; try { response.Content.Write(embeddedFile, 0, embeddedFile.Length); } catch(Exception error) { Log.WriteLine($"[Nibriboard/EmbeddedFileHandler] Error: {error.Message} Details:"); Log.WriteLine(error.ToString()); } logRequest(request, response); } protected string getEmbeddedFileReference(string uri) { return filePrefix + "." + uri.TrimStart("/".ToCharArray()).Replace('/', '.'); } protected string getMimeType(string uri) { string mimeType = mimeTypeFinder.Lookup(uri); foreach (KeyValuePair mimeMapping in mimeTypeOverrides) { if (mimeType == mimeMapping.Key) mimeType = mimeMapping.Value; } return mimeType; } private void logRequest(HttpRequest request, HttpResponse response) { Log.WriteLine("[Http/FileHandler] {0} {1} {2} {3}", response.ResponseCode.ResponseCode(), response.ContentType, request.Method.ToString().ToUpper(), request.URI); } } }