diff options
author | Daniel Baumann <daniel@debian.org> | 2024-10-18 20:33:49 +0200 |
---|---|---|
committer | Daniel Baumann <daniel@debian.org> | 2024-12-12 23:57:56 +0100 |
commit | e68b9d00a6e05b3a941f63ffb696f91e554ac5ec (patch) | |
tree | 97775d6c13b0f416af55314eb6a89ef792474615 /routers/web/repo/render.go | |
parent | Initial commit. (diff) | |
download | forgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.tar.xz forgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.zip |
Adding upstream version 9.0.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'routers/web/repo/render.go')
-rw-r--r-- | routers/web/repo/render.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go new file mode 100644 index 0000000..e64db03 --- /dev/null +++ b/routers/web/repo/render.go @@ -0,0 +1,76 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "bytes" + "io" + "net/http" + "path" + + "code.gitea.io/gitea/modules/charset" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/typesniffer" + "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/context" +) + +// RenderFile renders a file by repos path +func RenderFile(ctx *context.Context) { + blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreePath) + if err != nil { + if git.IsErrNotExist(err) { + ctx.NotFound("GetBlobByPath", err) + } else { + ctx.ServerError("GetBlobByPath", err) + } + return + } + + dataRc, err := blob.DataAsync() + if err != nil { + ctx.ServerError("DataAsync", err) + return + } + defer dataRc.Close() + + buf := make([]byte, 1024) + n, _ := util.ReadAtMost(dataRc, buf) + buf = buf[:n] + + st := typesniffer.DetectContentType(buf) + isTextFile := st.IsText() + + rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{}) + ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'; sandbox allow-scripts") + + if markupType := markup.Type(blob.Name()); markupType == "" { + if isTextFile { + _, _ = io.Copy(ctx.Resp, rd) + } else { + http.Error(ctx.Resp, "Unsupported file type render", http.StatusInternalServerError) + } + return + } + + err = markup.Render(&markup.RenderContext{ + Ctx: ctx, + RelativePath: ctx.Repo.TreePath, + Links: markup.Links{ + Base: ctx.Repo.RepoLink, + BranchPath: ctx.Repo.BranchNameSubURL(), + TreePath: path.Dir(ctx.Repo.TreePath), + }, + Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx), + GitRepo: ctx.Repo.GitRepo, + InStandalonePage: true, + }, rd, ctx.Resp) + if err != nil { + log.Error("Failed to render file %q: %v", ctx.Repo.TreePath, err) + http.Error(ctx.Resp, "Failed to render file", http.StatusInternalServerError) + return + } +} |