]> source.dussan.org Git - gitea.git/commitdiff
Add "X-Gitea-Object-Type" header for GET `/raw/` & `/media/` API (#20438)
author6543 <6543@obermui.de>
Thu, 21 Jul 2022 19:18:41 +0000 (21:18 +0200)
committerGitHub <noreply@github.com>
Thu, 21 Jul 2022 19:18:41 +0000 (21:18 +0200)
integrations/api_repo_raw_test.go
routers/api/v1/repo/file.go
services/repository/files/content.go

index 2a77d1ba630dced4bbefe6a2628971e853def99b..258b409befb875309bced3618f8010d8270776b2 100644 (file)
@@ -10,6 +10,8 @@ import (
 
        "code.gitea.io/gitea/models/unittest"
        user_model "code.gitea.io/gitea/models/user"
+
+       "github.com/stretchr/testify/assert"
 )
 
 func TestAPIReposRaw(t *testing.T) {
@@ -25,9 +27,11 @@ func TestAPIReposRaw(t *testing.T) {
                "65f1bf27bc3bf70f64657658635e66094edbcb4d", // Commit
        } {
                req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/%s/README.md?token="+token, user.Name, ref)
-               session.MakeRequest(t, req, http.StatusOK)
+               resp := session.MakeRequest(t, req, http.StatusOK)
+               assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type"))
        }
        // Test default branch
        req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/README.md?token="+token, user.Name)
-       session.MakeRequest(t, req, http.StatusOK)
+       resp := session.MakeRequest(t, req, http.StatusOK)
+       assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type"))
 }
index 1ac1088839231e809ebfb578d1c8ed7495202dab..ba8a938b8308cb50a6772c9d184edba5c7ae1aa8 100644 (file)
@@ -33,6 +33,8 @@ import (
        files_service "code.gitea.io/gitea/services/repository/files"
 )
 
+const giteaObjectTypeHeader = "X-Gitea-Object-Type"
+
 // GetRawFile get a file by path on a repository
 func GetRawFile(ctx *context.APIContext) {
        // swagger:operation GET /repos/{owner}/{repo}/raw/{filepath} repository repoGetRawFile
@@ -72,11 +74,13 @@ func GetRawFile(ctx *context.APIContext) {
                return
        }
 
-       blob, lastModified := getBlobForEntry(ctx)
+       blob, entry, lastModified := getBlobForEntry(ctx)
        if ctx.Written() {
                return
        }
 
+       ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry)))
+
        if err := common.ServeBlob(ctx.Context, blob, lastModified); err != nil {
                ctx.Error(http.StatusInternalServerError, "ServeBlob", err)
        }
@@ -119,11 +123,13 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
                return
        }
 
-       blob, lastModified := getBlobForEntry(ctx)
+       blob, entry, lastModified := getBlobForEntry(ctx)
        if ctx.Written() {
                return
        }
 
+       ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry)))
+
        // LFS Pointer files are at most 1024 bytes - so any blob greater than 1024 bytes cannot be an LFS file
        if blob.Size() > 1024 {
                // First handle caching for the blob
@@ -218,7 +224,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
        }
 }
 
-func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, lastModified time.Time) {
+func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEntry, lastModified time.Time) {
        entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
        if err != nil {
                if git.IsErrNotExist(err) {
@@ -251,7 +257,7 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, lastModified time
        }
        blob = entry.Blob()
 
-       return blob, lastModified
+       return blob, entry, lastModified
 }
 
 // GetArchive get archive of a repository
index 2237671a60cbbc2e16f38af0989008867fe03d82..c2069092899ef158d570c5022db5688d6d13571e 100644 (file)
@@ -101,6 +101,22 @@ func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, treePat
        return fileList, nil
 }
 
+// GetObjectTypeFromTreeEntry check what content is behind it
+func GetObjectTypeFromTreeEntry(entry *git.TreeEntry) ContentType {
+       switch {
+       case entry.IsDir():
+               return ContentTypeDir
+       case entry.IsSubModule():
+               return ContentTypeSubmodule
+       case entry.IsExecutable(), entry.IsRegular():
+               return ContentTypeRegular
+       case entry.IsLink():
+               return ContentTypeLink
+       default:
+               return ""
+       }
+}
+
 // GetContents gets the meta data on a file's contents. Ref can be a branch, commit or tag
 func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref string, forList bool) (*api.ContentsResponse, error) {
        if ref == "" {