diff options
author | John Olheiser <42128690+jolheiser@users.noreply.github.com> | 2020-01-15 20:40:13 -0600 |
---|---|---|
committer | Lunny Xiao <xiaolunwen@gmail.com> | 2020-01-16 10:40:13 +0800 |
commit | 176e7fb5d54aff955eef863f62cc232eaf8eb590 (patch) | |
tree | a912a704180ee46a4487388ebcac27f30de1cfd9 /routers/repo/http.go | |
parent | 8716752d22778048a067f1603105e1ae7f2c6049 (diff) | |
download | gitea-176e7fb5d54aff955eef863f62cc232eaf8eb590.tar.gz gitea-176e7fb5d54aff955eef863f62cc232eaf8eb590.zip |
Fix push-to-create (#9772)
* Fix push-to-create
Signed-off-by: jolheiser <john.olheiser@gmail.com>
* Check URL path and service
Signed-off-by: jolheiser <john.olheiser@gmail.com>
* Send dummy payload on receive-pack GET
Signed-off-by: jolheiser <john.olheiser@gmail.com>
* The space was actually a NUL byte
Signed-off-by: jolheiser <john.olheiser@gmail.com>
* Use real bare repo instead of manufactured payload
Signed-off-by: jolheiser <john.olheiser@gmail.com>
Diffstat (limited to 'routers/repo/http.go')
-rw-r--r-- | routers/repo/http.go | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/routers/repo/http.go b/routers/repo/http.go index b97feed51d..d0a2b289b7 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -10,6 +10,7 @@ import ( "compress/gzip" gocontext "context" "fmt" + "io/ioutil" "net/http" "os" "os/exec" @@ -17,6 +18,7 @@ import ( "regexp" "strconv" "strings" + "sync" "time" "code.gitea.io/gitea/models" @@ -65,11 +67,12 @@ func HTTP(ctx *context.Context) { return } - var isPull bool + var isPull, receivePack bool service := ctx.Query("service") if service == "git-receive-pack" || strings.HasSuffix(ctx.Req.URL.Path, "git-receive-pack") { isPull = false + receivePack = true } else if service == "git-upload-pack" || strings.HasSuffix(ctx.Req.URL.Path, "git-upload-pack") { isPull = true @@ -282,6 +285,11 @@ func HTTP(ctx *context.Context) { } if !repoExist { + if !receivePack { + ctx.HandleText(http.StatusNotFound, "Repository not found") + return + } + if owner.IsOrganization() && !setting.Repository.EnablePushCreateOrg { ctx.HandleText(http.StatusForbidden, "Push to create is not enabled for organizations.") return @@ -290,6 +298,13 @@ func HTTP(ctx *context.Context) { ctx.HandleText(http.StatusForbidden, "Push to create is not enabled for users.") return } + + // Return dummy payload if GET receive-pack + if ctx.Req.Method == http.MethodGet { + dummyInfoRefs(ctx) + return + } + repo, err = repo_service.PushCreateRepo(authUser, owner, reponame) if err != nil { log.Error("pushCreateRepo: %v", err) @@ -352,6 +367,48 @@ func HTTP(ctx *context.Context) { ctx.NotFound("Smart Git HTTP", nil) } +var ( + infoRefsCache []byte + infoRefsOnce sync.Once +) + +func dummyInfoRefs(ctx *context.Context) { + infoRefsOnce.Do(func() { + tmpDir, err := ioutil.TempDir(os.TempDir(), "gitea-info-refs-cache") + if err != nil { + log.Error("Failed to create temp dir for git-receive-pack cache: %v", err) + return + } + + defer func() { + if err := os.RemoveAll(tmpDir); err != nil { + log.Error("RemoveAll: %v", err) + } + }() + + if err := git.InitRepository(tmpDir, true); err != nil { + log.Error("Failed to init bare repo for git-receive-pack cache: %v", err) + return + } + + refs, err := git.NewCommand("receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunInDirBytes(tmpDir) + if err != nil { + log.Error(fmt.Sprintf("%v - %s", err, string(refs))) + } + + log.Debug("populating infoRefsCache: \n%s", string(refs)) + infoRefsCache = refs + }) + + ctx.Header().Set("Expires", "Fri, 01 Jan 1980 00:00:00 GMT") + ctx.Header().Set("Pragma", "no-cache") + ctx.Header().Set("Cache-Control", "no-cache, max-age=0, must-revalidate") + ctx.Header().Set("Content-Type", "application/x-git-receive-pack-advertisement") + _, _ = ctx.Write(packetWrite("# service=git-receive-pack\n")) + _, _ = ctx.Write([]byte("0000")) + _, _ = ctx.Write(infoRefsCache) +} + type serviceConfig struct { UploadPack bool ReceivePack bool |