code.gitea.io/gitea@v1.22.3/routers/web/repo/render.go (about) 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package repo 5 6 import ( 7 "bytes" 8 "io" 9 "net/http" 10 "path" 11 12 "code.gitea.io/gitea/modules/charset" 13 "code.gitea.io/gitea/modules/git" 14 "code.gitea.io/gitea/modules/log" 15 "code.gitea.io/gitea/modules/markup" 16 "code.gitea.io/gitea/modules/typesniffer" 17 "code.gitea.io/gitea/modules/util" 18 "code.gitea.io/gitea/services/context" 19 ) 20 21 // RenderFile renders a file by repos path 22 func RenderFile(ctx *context.Context) { 23 blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreePath) 24 if err != nil { 25 if git.IsErrNotExist(err) { 26 ctx.NotFound("GetBlobByPath", err) 27 } else { 28 ctx.ServerError("GetBlobByPath", err) 29 } 30 return 31 } 32 33 dataRc, err := blob.DataAsync() 34 if err != nil { 35 ctx.ServerError("DataAsync", err) 36 return 37 } 38 defer dataRc.Close() 39 40 buf := make([]byte, 1024) 41 n, _ := util.ReadAtMost(dataRc, buf) 42 buf = buf[:n] 43 44 st := typesniffer.DetectContentType(buf) 45 isTextFile := st.IsText() 46 47 rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{}) 48 ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'; sandbox allow-scripts") 49 50 if markupType := markup.DetectMarkupTypeByFileName(blob.Name()); markupType == "" { 51 if isTextFile { 52 _, _ = io.Copy(ctx.Resp, rd) 53 } else { 54 http.Error(ctx.Resp, "Unsupported file type render", http.StatusInternalServerError) 55 } 56 return 57 } 58 59 err = markup.Render(&markup.RenderContext{ 60 Ctx: ctx, 61 RelativePath: ctx.Repo.TreePath, 62 Links: markup.Links{ 63 Base: ctx.Repo.RepoLink, 64 BranchPath: ctx.Repo.BranchNameSubURL(), 65 TreePath: path.Dir(ctx.Repo.TreePath), 66 }, 67 Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx), 68 GitRepo: ctx.Repo.GitRepo, 69 InStandalonePage: true, 70 }, rd, ctx.Resp) 71 if err != nil { 72 log.Error("Failed to render file %q: %v", ctx.Repo.TreePath, err) 73 http.Error(ctx.Resp, "Failed to render file", http.StatusInternalServerError) 74 return 75 } 76 }