code.gitea.io/gitea@v1.21.7/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/context" 14 "code.gitea.io/gitea/modules/git" 15 "code.gitea.io/gitea/modules/markup" 16 "code.gitea.io/gitea/modules/typesniffer" 17 "code.gitea.io/gitea/modules/util" 18 ) 19 20 // RenderFile renders a file by repos path 21 func RenderFile(ctx *context.Context) { 22 blob, err := ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreePath) 23 if err != nil { 24 if git.IsErrNotExist(err) { 25 ctx.NotFound("GetBlobByPath", err) 26 } else { 27 ctx.ServerError("GetBlobByPath", err) 28 } 29 return 30 } 31 32 dataRc, err := blob.DataAsync() 33 if err != nil { 34 ctx.ServerError("DataAsync", err) 35 return 36 } 37 defer dataRc.Close() 38 39 buf := make([]byte, 1024) 40 n, _ := util.ReadAtMost(dataRc, buf) 41 buf = buf[:n] 42 43 st := typesniffer.DetectContentType(buf) 44 isTextFile := st.IsText() 45 46 rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{}) 47 48 if markupType := markup.Type(blob.Name()); markupType == "" { 49 if isTextFile { 50 _, err = io.Copy(ctx.Resp, rd) 51 if err != nil { 52 ctx.ServerError("Copy", err) 53 } 54 return 55 } 56 ctx.Error(http.StatusInternalServerError, "Unsupported file type render") 57 return 58 } 59 60 ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'; sandbox allow-scripts") 61 err = markup.Render(&markup.RenderContext{ 62 Ctx: ctx, 63 RelativePath: ctx.Repo.TreePath, 64 Links: markup.Links{ 65 Base: ctx.Repo.RepoLink, 66 BranchPath: ctx.Repo.BranchNameSubURL(), 67 TreePath: path.Dir(ctx.Repo.TreePath), 68 }, 69 Metas: ctx.Repo.Repository.ComposeDocumentMetas(), 70 GitRepo: ctx.Repo.GitRepo, 71 InStandalonePage: true, 72 }, rd, ctx.Resp) 73 if err != nil { 74 ctx.ServerError("Render", err) 75 return 76 } 77 }