mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 12:26:05 +01:00 
			
		
		
		
	Fix git empty check and HEAD request (#33690)
This commit is contained in:
		@@ -78,7 +78,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
 | 
				
			|||||||
		strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") {
 | 
							strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") {
 | 
				
			||||||
		isPull = true
 | 
							isPull = true
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		isPull = ctx.Req.Method == "GET"
 | 
							isPull = ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var accessMode perm.AccessMode
 | 
						var accessMode perm.AccessMode
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -291,6 +291,11 @@ func RepoRefForAPI(next http.Handler) http.Handler {
 | 
				
			|||||||
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
						return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
				
			||||||
		ctx := GetAPIContext(req)
 | 
							ctx := GetAPIContext(req)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ctx.Repo.Repository.IsEmpty {
 | 
				
			||||||
 | 
								ctx.APIErrorNotFound("repository is empty")
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ctx.Repo.GitRepo == nil {
 | 
							if ctx.Repo.GitRepo == nil {
 | 
				
			||||||
			ctx.APIErrorInternal(fmt.Errorf("no open git repo"))
 | 
								ctx.APIErrorInternal(fmt.Errorf("no open git repo"))
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,12 +60,20 @@ func TestEmptyRepoAddFile(t *testing.T) {
 | 
				
			|||||||
	defer tests.PrepareTestEnv(t)()
 | 
						defer tests.PrepareTestEnv(t)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	session := loginUser(t, "user30")
 | 
						session := loginUser(t, "user30")
 | 
				
			||||||
 | 
						token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// test web page
 | 
				
			||||||
	req := NewRequest(t, "GET", "/user30/empty")
 | 
						req := NewRequest(t, "GET", "/user30/empty")
 | 
				
			||||||
	resp := session.MakeRequest(t, req, http.StatusOK)
 | 
						resp := session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
	bodyString := resp.Body.String()
 | 
						bodyString := resp.Body.String()
 | 
				
			||||||
	assert.Contains(t, bodyString, "empty-repo-guide")
 | 
						assert.Contains(t, bodyString, "empty-repo-guide")
 | 
				
			||||||
	assert.True(t, test.IsNormalPageCompleted(bodyString))
 | 
						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)
 | 
						req = NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch)
 | 
				
			||||||
	resp = session.MakeRequest(t, req, http.StatusOK)
 | 
						resp = session.MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
	doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`)
 | 
						doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,10 @@ import (
 | 
				
			|||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/require"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestGitSmartHTTP(t *testing.T) {
 | 
					func TestGitSmartHTTP(t *testing.T) {
 | 
				
			||||||
@@ -18,51 +21,55 @@ func TestGitSmartHTTP(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func testGitSmartHTTP(t *testing.T, u *url.URL) {
 | 
					func testGitSmartHTTP(t *testing.T, u *url.URL) {
 | 
				
			||||||
	kases := []struct {
 | 
						kases := []struct {
 | 
				
			||||||
		p    string
 | 
							method, path string
 | 
				
			||||||
		code int
 | 
							code         int
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			p:    "user2/repo1/info/refs",
 | 
								path: "user2/repo1/info/refs",
 | 
				
			||||||
			code: http.StatusOK,
 | 
								code: http.StatusOK,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			p:    "user2/repo1/HEAD",
 | 
								method: "HEAD",
 | 
				
			||||||
 | 
								path:   "user2/repo1/info/refs",
 | 
				
			||||||
 | 
								code:   http.StatusOK,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								path: "user2/repo1/HEAD",
 | 
				
			||||||
			code: http.StatusOK,
 | 
								code: http.StatusOK,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			p:    "user2/repo1/objects/info/alternates",
 | 
								path: "user2/repo1/objects/info/alternates",
 | 
				
			||||||
			code: http.StatusNotFound,
 | 
								code: http.StatusNotFound,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			p:    "user2/repo1/objects/info/http-alternates",
 | 
								path: "user2/repo1/objects/info/http-alternates",
 | 
				
			||||||
			code: http.StatusNotFound,
 | 
								code: http.StatusNotFound,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			p:    "user2/repo1/../../custom/conf/app.ini",
 | 
								path: "user2/repo1/../../custom/conf/app.ini",
 | 
				
			||||||
			code: http.StatusNotFound,
 | 
								code: http.StatusNotFound,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			p:    "user2/repo1/objects/info/../../../../custom/conf/app.ini",
 | 
								path: "user2/repo1/objects/info/../../../../custom/conf/app.ini",
 | 
				
			||||||
			code: http.StatusNotFound,
 | 
								code: http.StatusNotFound,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			p:    `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`,
 | 
								path: `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`,
 | 
				
			||||||
			code: http.StatusBadRequest,
 | 
								code: http.StatusBadRequest,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, kase := range kases {
 | 
						for _, kase := range kases {
 | 
				
			||||||
		t.Run(kase.p, func(t *testing.T) {
 | 
							t.Run(kase.path, func(t *testing.T) {
 | 
				
			||||||
			p := u.String() + kase.p
 | 
								req, err := http.NewRequest(util.IfZero(kase.method, "GET"), u.String()+kase.path, nil)
 | 
				
			||||||
			req, err := http.NewRequest("GET", p, nil)
 | 
								require.NoError(t, err)
 | 
				
			||||||
			assert.NoError(t, err)
 | 
					 | 
				
			||||||
			req.SetBasicAuth("user2", userPassword)
 | 
								req.SetBasicAuth("user2", userPassword)
 | 
				
			||||||
			resp, err := http.DefaultClient.Do(req)
 | 
								resp, err := http.DefaultClient.Do(req)
 | 
				
			||||||
			assert.NoError(t, err)
 | 
								require.NoError(t, err)
 | 
				
			||||||
			defer resp.Body.Close()
 | 
								defer resp.Body.Close()
 | 
				
			||||||
			assert.EqualValues(t, kase.code, resp.StatusCode)
 | 
								assert.EqualValues(t, kase.code, resp.StatusCode)
 | 
				
			||||||
			_, err = io.ReadAll(resp.Body)
 | 
								_, err = io.ReadAll(resp.Body)
 | 
				
			||||||
			assert.NoError(t, err)
 | 
								require.NoError(t, err)
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user