mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 08:21:11 +00:00 
			
		
		
		
	This PR detects Interlisp files (files that include "(DEFINE-FILE-INFO" somewhere near the start, and do not have an .LCOM extension) as text files and displays them as such in the web UI. To check for extensions, I had to extend the `typesniffer.DetectContentType` function to accept an extra filename parameter—which could be useful for future filetype detection features. It is possible that a few of the places I modified pass a full file path instead of just passing a file name. Implements #8184 ## Checklist ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - NA - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [x] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. <!--start release-notes-assistant--> ## Release notes <!--URL:https://codeberg.org/forgejo/forgejo--> - Features - [PR](https://codeberg.org/forgejo/forgejo/pulls/8377): <!--number 8377 --><!--line 0 --><!--description ZGV0ZWN0IEludGVybGlzcCBzb3VyY2VzIGFzIHRleHQ=-->detect Interlisp sources as text<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8377 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: Bojidar Marinov <bojidar.marinov.bg@gmail.com> Co-committed-by: Bojidar Marinov <bojidar.marinov.bg@gmail.com>
		
			
				
	
	
		
			76 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2022 The Gitea Authors. All rights reserved.
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
package repo
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"io"
 | 
						|
	"net/http"
 | 
						|
	"path"
 | 
						|
 | 
						|
	"forgejo.org/modules/charset"
 | 
						|
	"forgejo.org/modules/git"
 | 
						|
	"forgejo.org/modules/log"
 | 
						|
	"forgejo.org/modules/markup"
 | 
						|
	"forgejo.org/modules/typesniffer"
 | 
						|
	"forgejo.org/modules/util"
 | 
						|
	"forgejo.org/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, blob.Name())
 | 
						|
	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
 | 
						|
	}
 | 
						|
}
 |