@@ -462,6 +462,7 @@ func handleWriteTGZ(w http.ResponseWriter, r *http.Request) {
462
462
baseDir := * workDir
463
463
if dir := urlParam .Get ("dir" ); dir != "" {
464
464
if ! validRelativeDir (dir ) {
465
+ log .Printf ("writetgz: bogus dir %q" , dir )
465
466
http .Error (w , "bogus dir" , http .StatusBadRequest )
466
467
return
467
468
}
@@ -472,49 +473,55 @@ func handleWriteTGZ(w http.ResponseWriter, r *http.Request) {
472
473
// This lets clients do a blind write to it and not do extra work.
473
474
if r .Method == "POST" && dir == "go1.4" {
474
475
if fi , err := os .Stat (baseDir ); err == nil && fi .IsDir () {
475
- log .Printf ("skipping URL puttar to go1.4 dir; already exists" )
476
+ log .Printf ("writetgz: skipping URL puttar to go1.4 dir; already exists" )
476
477
io .WriteString (w , "SKIP" )
477
478
return
478
479
}
479
480
}
480
481
481
482
if err := os .MkdirAll (baseDir , 0755 ); err != nil {
483
+ log .Printf ("writetgz: %v" , err )
482
484
http .Error (w , "mkdir of base: " + err .Error (), http .StatusInternalServerError )
483
485
return
484
486
}
485
487
}
486
488
487
489
var tgz io.Reader
490
+ var urlStr string
488
491
switch r .Method {
489
492
case "PUT" :
490
493
tgz = r .Body
494
+ log .Printf ("writetgz: untarring Request.Body into %s" , baseDir )
491
495
case "POST" :
492
- urlStr : = r .FormValue ("url" )
496
+ urlStr = r .FormValue ("url" )
493
497
if urlStr == "" {
498
+ log .Printf ("writetgz: missing url POST param" )
494
499
http .Error (w , "missing url POST param" , http .StatusBadRequest )
495
500
return
496
501
}
502
+ t0 := time .Now ()
497
503
res , err := http .Get (urlStr )
498
504
if err != nil {
499
- log .Printf ("Failed to fetch tgz URL %s: %v" , urlStr , err )
505
+ log .Printf ("writetgz: failed to fetch tgz URL %s: %v" , urlStr , err )
500
506
http .Error (w , fmt .Sprintf ("fetching URL %s: %v" , urlStr , err ), http .StatusInternalServerError )
501
507
return
502
508
}
503
509
defer res .Body .Close ()
504
510
if res .StatusCode != http .StatusOK {
505
- log .Printf ("Failed to fetch tgz URL %s: status=%v" , urlStr , res .Status )
511
+ log .Printf ("writetgz: failed to fetch tgz URL %s: status=%v" , urlStr , res .Status )
506
512
http .Error (w , fmt .Sprintf ("fetching provided url: %s" , res .Status ), http .StatusInternalServerError )
507
513
return
508
514
}
509
515
tgz = res .Body
516
+ log .Printf ("writetgz: untarring %s (got headers in %v) into %s" , urlStr , time .Since (t0 ), baseDir )
510
517
default :
518
+ log .Printf ("writetgz: invalid method %q" , r .Method )
511
519
http .Error (w , "requires PUT or POST method" , http .StatusBadRequest )
512
520
return
513
521
}
514
522
515
523
err := untar (tgz , baseDir )
516
524
if err != nil {
517
- log .Printf ("untar failure: %v" , err )
518
525
status := http .StatusInternalServerError
519
526
if he , ok := err .(httpStatuser ); ok {
520
527
status = he .httpStatus ()
@@ -583,7 +590,18 @@ func writeFile(r io.Reader, path string, mode os.FileMode) error {
583
590
}
584
591
585
592
// untar reads the gzip-compressed tar file from r and writes it into dir.
586
- func untar (r io.Reader , dir string ) error {
593
+ func untar (r io.Reader , dir string ) (err error ) {
594
+ t0 := time .Now ()
595
+ nFiles := 0
596
+ madeDir := map [string ]bool {}
597
+ defer func () {
598
+ td := time .Since (t0 )
599
+ if err == nil {
600
+ log .Printf ("extracted tarball into %s: %d files, %d dirs (%v)" , dir , nFiles , len (madeDir ), td )
601
+ } else {
602
+ log .Printf ("error extracting tarball into %s after %d files, %d dirs, %v: %v" , dir , nFiles , len (madeDir ), td , err )
603
+ }
604
+ }()
587
605
zr , err := gzip .NewReader (r )
588
606
if err != nil {
589
607
return badRequest ("requires gzip-compressed body: " + err .Error ())
@@ -612,7 +630,13 @@ func untar(r io.Reader, dir string) error {
612
630
// already be made by a directory entry in the tar
613
631
// beforehand. Thus, don't check for errors; the next
614
632
// write will fail with the same error.
615
- os .MkdirAll (filepath .Dir (abs ), 0755 )
633
+ dir := filepath .Dir (abs )
634
+ if ! madeDir [dir ] {
635
+ if err := os .MkdirAll (filepath .Dir (abs ), 0755 ); err != nil {
636
+ return err
637
+ }
638
+ madeDir [dir ] = true
639
+ }
616
640
wf , err := os .OpenFile (abs , os .O_RDWR | os .O_CREATE | os .O_TRUNC , mode .Perm ())
617
641
if err != nil {
618
642
return err
@@ -627,7 +651,6 @@ func untar(r io.Reader, dir string) error {
627
651
if n != f .Size {
628
652
return fmt .Errorf ("only wrote %d bytes to %s; expected %d" , n , abs , f .Size )
629
653
}
630
- log .Printf ("wrote %s" , abs )
631
654
if ! f .ModTime .IsZero () {
632
655
if err := os .Chtimes (abs , f .ModTime , f .ModTime ); err != nil {
633
656
// benign error. Gerrit doesn't even set the
@@ -638,10 +661,12 @@ func untar(r io.Reader, dir string) error {
638
661
log .Printf ("error changing modtime: %v" , err )
639
662
}
640
663
}
664
+ nFiles ++
641
665
case mode .IsDir ():
642
666
if err := os .MkdirAll (abs , 0755 ); err != nil {
643
667
return err
644
668
}
669
+ madeDir [abs ] = true
645
670
default :
646
671
return badRequest (fmt .Sprintf ("tar file entry %s contained unsupported file type %v" , f .Name , mode ))
647
672
}
0 commit comments