@@ -10,13 +10,15 @@ import (
10
10
"compress/gzip"
11
11
gocontext "context"
12
12
"fmt"
13
+ "io/ioutil"
13
14
"net/http"
14
15
"os"
15
16
"os/exec"
16
17
"path"
17
18
"regexp"
18
19
"strconv"
19
20
"strings"
21
+ "sync"
20
22
"time"
21
23
22
24
"code.gitea.io/gitea/models"
@@ -65,11 +67,12 @@ func HTTP(ctx *context.Context) {
65
67
return
66
68
}
67
69
68
- var isPull bool
70
+ var isPull , receivePack bool
69
71
service := ctx .Query ("service" )
70
72
if service == "git-receive-pack" ||
71
73
strings .HasSuffix (ctx .Req .URL .Path , "git-receive-pack" ) {
72
74
isPull = false
75
+ receivePack = true
73
76
} else if service == "git-upload-pack" ||
74
77
strings .HasSuffix (ctx .Req .URL .Path , "git-upload-pack" ) {
75
78
isPull = true
@@ -282,6 +285,11 @@ func HTTP(ctx *context.Context) {
282
285
}
283
286
284
287
if ! repoExist {
288
+ if ! receivePack {
289
+ ctx .HandleText (http .StatusNotFound , "Repository not found" )
290
+ return
291
+ }
292
+
285
293
if owner .IsOrganization () && ! setting .Repository .EnablePushCreateOrg {
286
294
ctx .HandleText (http .StatusForbidden , "Push to create is not enabled for organizations." )
287
295
return
@@ -290,6 +298,13 @@ func HTTP(ctx *context.Context) {
290
298
ctx .HandleText (http .StatusForbidden , "Push to create is not enabled for users." )
291
299
return
292
300
}
301
+
302
+ // Return dummy payload if GET receive-pack
303
+ if ctx .Req .Method == http .MethodGet {
304
+ dummyInfoRefs (ctx )
305
+ return
306
+ }
307
+
293
308
repo , err = repo_service .PushCreateRepo (authUser , owner , reponame )
294
309
if err != nil {
295
310
log .Error ("pushCreateRepo: %v" , err )
@@ -352,6 +367,48 @@ func HTTP(ctx *context.Context) {
352
367
ctx .NotFound ("Smart Git HTTP" , nil )
353
368
}
354
369
370
+ var (
371
+ infoRefsCache []byte
372
+ infoRefsOnce sync.Once
373
+ )
374
+
375
+ func dummyInfoRefs (ctx * context.Context ) {
376
+ infoRefsOnce .Do (func () {
377
+ tmpDir , err := ioutil .TempDir (os .TempDir (), "gitea-info-refs-cache" )
378
+ if err != nil {
379
+ log .Error ("Failed to create temp dir for git-receive-pack cache: %v" , err )
380
+ return
381
+ }
382
+
383
+ defer func () {
384
+ if err := os .RemoveAll (tmpDir ); err != nil {
385
+ log .Error ("RemoveAll: %v" , err )
386
+ }
387
+ }()
388
+
389
+ if err := git .InitRepository (tmpDir , true ); err != nil {
390
+ log .Error ("Failed to init bare repo for git-receive-pack cache: %v" , err )
391
+ return
392
+ }
393
+
394
+ refs , err := git .NewCommand ("receive-pack" , "--stateless-rpc" , "--advertise-refs" , "." ).RunInDirBytes (tmpDir )
395
+ if err != nil {
396
+ log .Error (fmt .Sprintf ("%v - %s" , err , string (refs )))
397
+ }
398
+
399
+ log .Debug ("populating infoRefsCache: \n %s" , string (refs ))
400
+ infoRefsCache = refs
401
+ })
402
+
403
+ ctx .Header ().Set ("Expires" , "Fri, 01 Jan 1980 00:00:00 GMT" )
404
+ ctx .Header ().Set ("Pragma" , "no-cache" )
405
+ ctx .Header ().Set ("Cache-Control" , "no-cache, max-age=0, must-revalidate" )
406
+ ctx .Header ().Set ("Content-Type" , "application/x-git-receive-pack-advertisement" )
407
+ _ , _ = ctx .Write (packetWrite ("# service=git-receive-pack\n " ))
408
+ _ , _ = ctx .Write ([]byte ("0000" ))
409
+ _ , _ = ctx .Write (infoRefsCache )
410
+ }
411
+
355
412
type serviceConfig struct {
356
413
UploadPack bool
357
414
ReceivePack bool
0 commit comments