Skip to content

Commit 45d21a0

Browse files
GiteaBotwxiaoguang
andauthored
Fix raw file API ref handling (#33172) (#33189)
Backport #33172 by wxiaoguang Fix #33164 and add more tests Co-authored-by: wxiaoguang <[email protected]>
1 parent 15ad001 commit 45d21a0

File tree

3 files changed

+52
-47
lines changed

3 files changed

+52
-47
lines changed

services/context/api.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
305305
return
306306
}
307307

308-
// NOTICE: the "ref" here for internal usage only (e.g. woodpecker)
309-
refName, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.FormTrim("ref"))
308+
refName, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.PathParam("*"), ctx.FormTrim("ref"))
310309
var err error
311310

312311
if ctx.Repo.GitRepo.IsBranchExist(refName) {

services/context/repo.go

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -769,35 +769,30 @@ func getRefNameFromPath(repo *Repository, path string, isExist func(string) bool
769769
return ""
770770
}
771771

772-
func getRefNameLegacy(ctx *Base, repo *Repository, optionalExtraRef ...string) (string, RepoRefType) {
773-
extraRef := util.OptionalArg(optionalExtraRef)
774-
reqPath := ctx.PathParam("*")
775-
reqPath = path.Join(extraRef, reqPath)
776-
777-
if refName := getRefName(ctx, repo, RepoRefBranch); refName != "" {
772+
func getRefNameLegacy(ctx *Base, repo *Repository, reqPath, extraRef string) (string, RepoRefType) {
773+
reqRefPath := path.Join(extraRef, reqPath)
774+
reqRefPathParts := strings.Split(reqRefPath, "/")
775+
if refName := getRefName(ctx, repo, reqRefPath, RepoRefBranch); refName != "" {
778776
return refName, RepoRefBranch
779777
}
780-
if refName := getRefName(ctx, repo, RepoRefTag); refName != "" {
778+
if refName := getRefName(ctx, repo, reqRefPath, RepoRefTag); refName != "" {
781779
return refName, RepoRefTag
782780
}
783-
784-
// For legacy support only full commit sha
785-
parts := strings.Split(reqPath, "/")
786-
if git.IsStringLikelyCommitID(git.ObjectFormatFromName(repo.Repository.ObjectFormatName), parts[0]) {
781+
if git.IsStringLikelyCommitID(git.ObjectFormatFromName(repo.Repository.ObjectFormatName), reqRefPathParts[0]) {
787782
// FIXME: this logic is different from other types. Ideally, it should also try to GetCommit to check if it exists
788-
repo.TreePath = strings.Join(parts[1:], "/")
789-
return parts[0], RepoRefCommit
783+
repo.TreePath = strings.Join(reqRefPathParts[1:], "/")
784+
return reqRefPathParts[0], RepoRefCommit
790785
}
791-
792-
if refName := getRefName(ctx, repo, RepoRefBlob); len(refName) > 0 {
786+
if refName := getRefName(ctx, repo, reqPath, RepoRefBlob); refName != "" {
793787
return refName, RepoRefBlob
794788
}
789+
// FIXME: the old code falls back to default branch if "ref" doesn't exist, there could be an edge case:
790+
// "README?ref=no-such" would read the README file from the default branch, but the user might expect a 404
795791
repo.TreePath = reqPath
796792
return repo.Repository.DefaultBranch, RepoRefBranch
797793
}
798794

799-
func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
800-
path := ctx.PathParam("*")
795+
func getRefName(ctx *Base, repo *Repository, path string, pathType RepoRefType) string {
801796
switch pathType {
802797
case RepoRefBranch:
803798
ref := getRefNameFromPath(repo, path, repo.GitRepo.IsBranchExist)
@@ -900,7 +895,8 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
900895
}
901896

902897
// Get default branch.
903-
if len(ctx.PathParam("*")) == 0 {
898+
reqPath := ctx.PathParam("*")
899+
if reqPath == "" {
904900
refName = ctx.Repo.Repository.DefaultBranch
905901
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
906902
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1)
@@ -925,12 +921,12 @@ func RepoRefByType(detectRefType RepoRefType, opts ...RepoRefByTypeOptions) func
925921
return cancel
926922
}
927923
ctx.Repo.IsViewBranch = true
928-
} else {
924+
} else { // there is a path in request
929925
guessLegacyPath := refType == RepoRefUnknown
930926
if guessLegacyPath {
931-
refName, refType = getRefNameLegacy(ctx.Base, ctx.Repo)
927+
refName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
932928
} else {
933-
refName = getRefName(ctx.Base, ctx.Repo, refType)
929+
refName = getRefName(ctx.Base, ctx.Repo, reqPath, refType)
934930
}
935931
ctx.Repo.RefName = refName
936932
isRenamedBranch, has := ctx.Data["IsRenamedBranch"].(bool)

tests/integration/api_repo_get_contents_test.go

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"code.gitea.io/gitea/modules/setting"
1919
api "code.gitea.io/gitea/modules/structs"
2020
repo_service "code.gitea.io/gitea/services/repository"
21+
"code.gitea.io/gitea/tests"
2122

2223
"github.com/stretchr/testify/assert"
2324
)
@@ -168,28 +169,37 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
168169
}
169170

170171
func TestAPIGetContentsRefFormats(t *testing.T) {
171-
onGiteaRun(t, func(t *testing.T, u *url.URL) {
172-
file := "README.md"
173-
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
174-
content := "# repo1\n\nDescription for repo1"
175-
176-
noRef := setting.AppURL + "api/v1/repos/user2/repo1/raw/" + file
177-
refInPath := setting.AppURL + "api/v1/repos/user2/repo1/raw/" + sha + "/" + file
178-
refInQuery := setting.AppURL + "api/v1/repos/user2/repo1/raw/" + file + "?ref=" + sha
179-
180-
resp := MakeRequest(t, NewRequest(t, http.MethodGet, noRef), http.StatusOK)
181-
raw, err := io.ReadAll(resp.Body)
182-
assert.NoError(t, err)
183-
assert.EqualValues(t, content, string(raw))
184-
185-
resp = MakeRequest(t, NewRequest(t, http.MethodGet, refInPath), http.StatusOK)
186-
raw, err = io.ReadAll(resp.Body)
187-
assert.NoError(t, err)
188-
assert.EqualValues(t, content, string(raw))
189-
190-
resp = MakeRequest(t, NewRequest(t, http.MethodGet, refInQuery), http.StatusOK)
191-
raw, err = io.ReadAll(resp.Body)
192-
assert.NoError(t, err)
193-
assert.EqualValues(t, content, string(raw))
194-
})
172+
defer tests.PrepareTestEnv(t)()
173+
174+
file := "README.md"
175+
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
176+
content := "# repo1\n\nDescription for repo1"
177+
178+
resp := MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+file), http.StatusOK)
179+
raw, err := io.ReadAll(resp.Body)
180+
assert.NoError(t, err)
181+
assert.EqualValues(t, content, string(raw))
182+
183+
resp = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+sha+"/"+file), http.StatusOK)
184+
raw, err = io.ReadAll(resp.Body)
185+
assert.NoError(t, err)
186+
assert.EqualValues(t, content, string(raw))
187+
188+
resp = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+file+"?ref="+sha), http.StatusOK)
189+
raw, err = io.ReadAll(resp.Body)
190+
assert.NoError(t, err)
191+
assert.EqualValues(t, content, string(raw))
192+
193+
resp = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+file+"?ref=master"), http.StatusOK)
194+
raw, err = io.ReadAll(resp.Body)
195+
assert.NoError(t, err)
196+
assert.EqualValues(t, content, string(raw))
197+
198+
_ = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/docs/README.md?ref=main"), http.StatusNotFound)
199+
_ = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/README.md?ref=main"), http.StatusOK)
200+
_ = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/docs/README.md?ref=sub-home-md-img-check"), http.StatusOK)
201+
_ = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/README.md?ref=sub-home-md-img-check"), http.StatusNotFound)
202+
203+
// FIXME: this is an incorrect behavior, non-existing branch falls back to default branch
204+
_ = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/README.md?ref=no-such"), http.StatusOK)
195205
}

0 commit comments

Comments
 (0)