public SimpleApiPage(Color elementColor, string title, string handle) { if (WebApiHandleStore.Handles.Any(h => h.HandleId.Equals(handle))) { ILogManager.Log($"API Handler with the same name [{handle}] already exists. The page will not be registered.", this.ToString(), LogType.Error); return; } if (HttpHandleStore.Handles.Any(h => h.Value.Path.Equals(handle))) { ILogManager.Log($"Http handle with the same name [{handle}] already exists. The page will not be registered.", this.ToString(), LogType.Error); return; } this.Title = title; this.Handle = handle; this.ElementColor = elementColor; this.Handler = new ApiHandleHolder(handle); WebApiHandleStore.Add(this.Handler); // compile page this.Html = SimpleApiPageSplicerConstant.Page.Replace(SimpleApiPageSplicerConstant.ReplaceInTitle, title); this.Html = this.Html.Replace(SimpleApiPageSplicerConstant.ReplaceInColor, GetColor()); this.Html = this.Html.Replace(SimpleApiPageSplicerConstant.ReplaceInPort, IConfigurationStore.GetByType <RequiemConfig>().ApiPort.ToString()); this.Html = this.Html.Replace(SimpleApiPageSplicerConstant.ReplaceInHandle, handle); using (var ms = new MemoryStream()) { using var headers = new HttpResponseHeaders(this.Html.Length, ResponseStatusCode.Ok200, new IResponseField[] { new FieldAcceptRanges(HttpConstant.AcceptRanges), new FieldServer(HttpConstant.ServerName), new FieldContentType("text/html") }, "HTTP/1.1"); var h = headers.Compile(); ms.Write(h.Item1, 0, h.Item2); ms.Write(Encoding.UTF8.GetBytes(this.Html)); this.HtmlBytes = ms.ToArray(); } var webHandle = new SpecialHandler(handle, async(client) => { await client.SafeWriteAsync(this.HtmlBytes); }); HttpHandleStore.AddHandler(webHandle); }
public ApiGraphPage(string handle, string title, ApiGraph[] graphs, byte width) { this.ApiHandle = handle; this.Title = title; this.Graphs = graphs; var graphCodeStr = new List <string>(); var graphCodeHandles = new List <string>(); var declareVariablesInScript = new List <string>(); foreach (var graph in graphs) { graphCodeStr.Add(graph.Code); graphCodeHandles.Add(graph.GraphCtx); declareVariablesInScript.Add(graph.Variable); } var script = GraphPageSplicer.SpliceMainScript( IConfigurationStore.GetByType <RequiemConfig>().ApiPort, handle, declareVariablesInScript.ToArray(), graphCodeStr.ToArray(), graphCodeHandles.ToArray()); this.Code = GraphPageSplicer.SpliceFinalHtml(script, title, graphCodeHandles.ToArray(), width); using var ms = new MemoryStream(); using var headers = new HttpResponseHeaders(Code.Length, ResponseStatusCode.Ok200, new IResponseField[] { new FieldAcceptRanges("bytes"), new FieldContentType("text/html"), new FieldServer(HttpConstant.ServerName) }, "HTTP/1.1"); this.Header = headers.Compile(); ms.Write(Header.Item1, 0, Header.Item2); ms.Write(Encoding.UTF8.GetBytes(this.Code)); this.Stream = ms.ToArray(); var httpHandle = new SpecialHandler(handle, async(ctx) => await ctx.SafeWriteAsync(Stream)); HttpHandleStore.AddHandler(httpHandle); this.Api = new ApiHandleHolder(handle); WebApiHandleStore.Add(this.Api); }
public SimplePageHandler(string name, TableSite site) { this.Site = site; this.Handle = new SpecialHandler(name, async(holder) => { var document = Encoding.UTF8.GetBytes(Site.GetLatest()); using var headers = new HttpResponseHeaders(document.Length, ResponseStatusCode.Ok200, new IResponseField[] { new FieldServer(HttpConstant.ServerName), new FieldAcceptRanges(HttpConstant.AcceptRanges), new FieldContentType("text/html") }, "HTTP/1.1"); var h = headers.Compile(); if (!await holder.SafeWriteAsync(h.Item1, h.Item2)) { return; } await holder.SafeWriteAsync(document); }); HttpHandleStore.AddHandler(this.Handle); }
public ApiConsolePage(Color boxColor, string title, string handle, string placeholder) { this.Handle = handle; this.Title = title; this.Placeholder = placeholder; this.BoxColor = boxColor; this.Html = ApiConsolePageSplicer.Html.Replace(ApiConsolePageSplicer.ReplaceInTitle, title); this.Html = this.Html.Replace(ApiConsolePageSplicer.ReplaceInColor, GetColor()); this.Html = this.Html.Replace(ApiConsolePageSplicer.ReplaceInPort, IConfigurationStore.GetByType <RequiemConfig>().ApiPort.ToString()); this.Html = this.Html.Replace(ApiConsolePageSplicer.ReplaceInHandle, handle); this.Html = this.Html.Replace(ApiConsolePageSplicer.ReplaceInMainPlaceholder, placeholder); this.Handler = new ApiHandleHolder(handle); WebApiHandleStore.Add(this.Handler); using (var ms = new MemoryStream()) { using var headers = new HttpResponseHeaders(this.Html.Length, ResponseStatusCode.Ok200, new IResponseField[] { new FieldAcceptRanges(HttpConstant.AcceptRanges), new FieldServer(HttpConstant.ServerName), new FieldContentType("text/html") }, "HTTP/1.1"); var h = headers.Compile(); ms.Write(h.Item1, 0, h.Item2); ms.Write(Encoding.UTF8.GetBytes(this.Html)); this.HtmlBytes = ms.ToArray(); } var webHandle = new SpecialHandler(handle, async(client) => { await client.SafeWriteAsync(this.HtmlBytes); }); HttpHandleStore.AddHandler(webHandle); }
public static async ValueTask ProcessClient(HttpClientHolder holder, HttpInitialRequest request) { var handler = HttpHandleStore.Check(request.Path); if (handler == null) { request.Path = Path.Combine(Directory.GetCurrentDirectory(), HttpConstant.RootDirectory, request.Path); if (!File.Exists(request.Path)) { await holder.SafeWriteAsync(HttpErrorResponses.Instance.NotFoundResponse); return; } } else { handler.Invoked?.Invoke(holder); return; } var mime = MimeProcessor.Interpret(request.Path); if (mime == null) { await holder.SafeWriteAsync(HttpErrorResponses.Instance.NotImplementedResponse); return; } var fileInfo = new FileInfo(request.Path); holder.Client.SendBufferSize = HttpConstant.FileBufferSize; var asyncFs = fileInfo.Length > 1024 * 1024; Stream fs; if (Cfg.EnableHttpCache && !Cfg.HttpCacheExclude.Contains(request.Path)) { var(stat, array, length) = HttpServerFileCache.TryGet(request.Path); if (stat) { Trace.Assert(array != null, "Http cache null L58/Client.Processor!"); fs = new MemoryStream(array, 0, length.Value); asyncFs = false; } else { var(success, bytes, stream) = await HttpServerFileCache.TryCache(request.Path, asyncFs); if (success) { fs = new MemoryStream(bytes, 0, (int)fileInfo.Length); asyncFs = false; } else { fs = stream; } } } else { fs = new FileStream(request.Path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: asyncFs); } await using (fs) { if (request.Ranges == null || request.Ranges.Count == 0) { using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.Ok200, new IResponseField[] { new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } await CopyStream(fileInfo, fs, holder, fileInfo.Length, asyncFs); return; } foreach (var range in request.Ranges) { switch (range.Method) { case HttpRangeRequestMethod.SliceFromToEnd: { // implemented, tested if (fs.Length < range.Range.From) { return; } using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, range.Range.From, fileInfo.Length - 1, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } fs.Seek((long)range.Range.From !, SeekOrigin.Begin); await CopyStream(fileInfo, fs, holder, (int)(fs.Length - range.Range.From), asyncFs); return; } case HttpRangeRequestMethod.SendAll: { // implemented, tested using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, 0, fileInfo.Length - 1, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } await CopyStream(fileInfo, fs, holder, (int)fs.Length, asyncFs); return; } case HttpRangeRequestMethod.SliceFromTo: { if (fs.Length < range.Range.From || fs.Length < range.Range.To) { // attacker. return; } using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, range.Range.From, range.Range.To, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } fs.Seek((int)range.Range.From, SeekOrigin.Begin); await CopyStream(fileInfo, fs, holder, (long)(range.Range.To - range.Range.From) !, asyncFs); return; } case HttpRangeRequestMethod.SliceFromStartTo: { if (fs.Length < range.Range.To) { // attacker. return; } using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, 0, range.Range.To, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2) || range.Range.To == null) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } await CopyStream(fileInfo, fs, holder, (long)range.Range.To, asyncFs); return; } default: return; // ?? } } } }