diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index e27040edc6..5b7b0188dc 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -78,7 +78,7 @@ func httpBase(ctx *context.Context) *serviceHandler { strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") { isPull = true } else { - isPull = ctx.Req.Method == "GET" + isPull = ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET" } var accessMode perm.AccessMode diff --git a/services/context/api.go b/services/context/api.go index 230c3456d1..c163de036c 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -291,6 +291,11 @@ func RepoRefForAPI(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { ctx := GetAPIContext(req) + if ctx.Repo.Repository.IsEmpty { + ctx.APIErrorNotFound("repository is empty") + return + } + if ctx.Repo.GitRepo == nil { ctx.APIErrorInternal(fmt.Errorf("no open git repo")) return diff --git a/tests/integration/empty_repo_test.go b/tests/integration/empty_repo_test.go index b19774a826..e122531dc9 100644 --- a/tests/integration/empty_repo_test.go +++ b/tests/integration/empty_repo_test.go @@ -60,12 +60,20 @@ func TestEmptyRepoAddFile(t *testing.T) { defer tests.PrepareTestEnv(t)() session := loginUser(t, "user30") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) + + // test web page req := NewRequest(t, "GET", "/user30/empty") resp := session.MakeRequest(t, req, http.StatusOK) bodyString := resp.Body.String() assert.Contains(t, bodyString, "empty-repo-guide") assert.True(t, test.IsNormalPageCompleted(bodyString)) + // test api + req = NewRequest(t, "GET", "/api/v1/repos/user30/empty/raw/main/README.md").AddTokenAuth(token) + session.MakeRequest(t, req, http.StatusNotFound) + + // create a new file req = NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch) resp = session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`) diff --git a/tests/integration/git_smart_http_test.go b/tests/integration/git_smart_http_test.go index 15336b9b81..55d647672a 100644 --- a/tests/integration/git_smart_http_test.go +++ b/tests/integration/git_smart_http_test.go @@ -9,7 +9,10 @@ import ( "net/url" "testing" + "code.gitea.io/gitea/modules/util" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGitSmartHTTP(t *testing.T) { @@ -18,51 +21,55 @@ func TestGitSmartHTTP(t *testing.T) { func testGitSmartHTTP(t *testing.T, u *url.URL) { kases := []struct { - p string - code int + method, path string + code int }{ { - p: "user2/repo1/info/refs", + path: "user2/repo1/info/refs", code: http.StatusOK, }, { - p: "user2/repo1/HEAD", + method: "HEAD", + path: "user2/repo1/info/refs", + code: http.StatusOK, + }, + { + path: "user2/repo1/HEAD", code: http.StatusOK, }, { - p: "user2/repo1/objects/info/alternates", + path: "user2/repo1/objects/info/alternates", code: http.StatusNotFound, }, { - p: "user2/repo1/objects/info/http-alternates", + path: "user2/repo1/objects/info/http-alternates", code: http.StatusNotFound, }, { - p: "user2/repo1/../../custom/conf/app.ini", + path: "user2/repo1/../../custom/conf/app.ini", code: http.StatusNotFound, }, { - p: "user2/repo1/objects/info/../../../../custom/conf/app.ini", + path: "user2/repo1/objects/info/../../../../custom/conf/app.ini", code: http.StatusNotFound, }, { - p: `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`, + path: `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`, code: http.StatusBadRequest, }, } for _, kase := range kases { - t.Run(kase.p, func(t *testing.T) { - p := u.String() + kase.p - req, err := http.NewRequest("GET", p, nil) - assert.NoError(t, err) + t.Run(kase.path, func(t *testing.T) { + req, err := http.NewRequest(util.IfZero(kase.method, "GET"), u.String()+kase.path, nil) + require.NoError(t, err) req.SetBasicAuth("user2", userPassword) resp, err := http.DefaultClient.Do(req) - assert.NoError(t, err) + require.NoError(t, err) defer resp.Body.Close() assert.EqualValues(t, kase.code, resp.StatusCode) _, err = io.ReadAll(resp.Body) - assert.NoError(t, err) + require.NoError(t, err) }) } }