Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
 }
Ejemplo n.º 4
0
        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;     // ??
                    }
                }
            }
        }