summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorJohn Olheiser <42128690+jolheiser@users.noreply.github.com>2020-01-15 20:40:13 -0600
committerLunny Xiao <xiaolunwen@gmail.com>2020-01-16 10:40:13 +0800
commit176e7fb5d54aff955eef863f62cc232eaf8eb590 (patch)
treea912a704180ee46a4487388ebcac27f30de1cfd9 /routers
parent8716752d22778048a067f1603105e1ae7f2c6049 (diff)
downloadgitea-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')
-rw-r--r--routers/repo/http.go59
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