@@ -503,52 +503,43 @@ Gitea or set your environment appropriately.`, "")
503
503
// H: PKT-LINE(version=1\0push-options...)
504
504
// H: flush-pkt
505
505
506
- rs , err := readPktLine (reader )
507
- if err != nil {
508
- fail ("Internal Server Error" , "Pkt-Line format is wrong :%v" , err )
509
- }
510
- if rs .Type != pktLineTypeData {
511
- fail ("Internal Server Error" , "Pkt-Line format is wrong. get %v" , rs )
512
- }
506
+ rs := readPktLine (reader , pktLineTypeData )
513
507
514
508
const VersionHead string = "version=1"
515
509
516
- if ! strings .HasPrefix (rs .Data , VersionHead ) {
517
- fail ("Internal Server Error" , "Pkt-Line format is wrong. get %v" , rs )
518
- }
519
-
520
510
hasPushOptions := false
521
511
response := []byte (VersionHead )
522
- if strings .Contains (rs .Data , "push-options" ) {
523
- response = append (response , byte (0 ))
524
- response = append (response , []byte ("push-options" )... )
525
- hasPushOptions = true
526
- }
527
- response = append (response , []byte ("\n " )... )
512
+ var requestOptions []string
528
513
529
- rs , err = readPktLine (reader )
530
- if err != nil {
531
- fail ("Internal Server Error" , "Pkt-Line format is wrong :%v" , err )
532
- }
533
- if rs .Type != pktLineTypeFlush {
534
- fail ("Internal Server Error" , "Pkt-Line format is wrong. get %v" , rs )
514
+ for i := range rs .Data {
515
+ if rs .Data [i ] == byte (0 ) {
516
+ if string (rs .Data [0 :i ]) != VersionHead {
517
+ fail ("Internal Server Error" , "Received an not supported version: %s" , string (rs .Data [0 :i ]))
518
+ }
519
+ requestOptions = strings .Split (string (rs .Data [i + 1 :]), " " )
520
+ break
521
+ }
535
522
}
536
523
537
- err = writePktLine (os .Stdout , pktLineTypeData , response )
538
- if err != nil {
539
- fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
524
+ for _ , option := range requestOptions {
525
+ if strings .HasPrefix (option , "push-options" ) {
526
+ response = append (response , byte (0 ))
527
+ response = append (response , []byte ("push-options" )... )
528
+ hasPushOptions = true
529
+ }
540
530
}
531
+ response = append (response , []byte ("\n " )... )
541
532
542
- err = writePktLine ( os . Stdout , pktLineTypeFlush , nil )
543
- if err != nil {
544
- fail ( "Internal Server Error" , "Pkt-Line response failed: %v" , err )
545
- }
533
+ rs = readPktLine ( reader , pktLineTypeFlush )
534
+
535
+ writePktLine ( os . Stdout , pktLineTypeData , response )
536
+ writePktLine ( os . Stdout , pktLineTypeFlush , nil )
546
537
547
538
// 2. receive commands from server.
548
539
// S: PKT-LINE(<old-oid> <new-oid> <ref>)
549
540
// S: ... ...
550
541
// S: flush-pkt
551
- // # receive push-options
542
+ // # [ receive push-options]
552
543
// S: PKT-LINE(push-option)
553
544
// S: ... ...
554
545
// S: flush-pkt
@@ -561,14 +552,13 @@ Gitea or set your environment appropriately.`, "")
561
552
hookOptions .RefFullNames = make ([]string , 0 , hookBatchSize )
562
553
563
554
for {
564
- rs , err = readPktLine (reader )
565
- if err != nil {
566
- fail ("Internal Server Error" , "Pkt-Line format is wrong :%v" , err )
567
- }
555
+ // note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
556
+ rs = readPktLine (reader , pktLineTypeUnknow )
557
+
568
558
if rs .Type == pktLineTypeFlush {
569
559
break
570
560
}
571
- t := strings .SplitN (rs .Data , " " , 3 )
561
+ t := strings .SplitN (string ( rs .Data ) , " " , 3 )
572
562
if len (t ) != 3 {
573
563
continue
574
564
}
@@ -581,29 +571,27 @@ Gitea or set your environment appropriately.`, "")
581
571
582
572
if hasPushOptions {
583
573
for {
584
- rs , err = readPktLine (reader )
585
- if err != nil {
586
- fail ("Internal Server Error" , "Pkt-Line format is wrong :%v" , err )
587
- }
574
+ rs = readPktLine (reader , pktLineTypeUnknow )
575
+
588
576
if rs .Type == pktLineTypeFlush {
589
577
break
590
578
}
591
579
592
- kv := strings .SplitN (rs .Data , "=" , 2 )
580
+ kv := strings .SplitN (string ( rs .Data ) , "=" , 2 )
593
581
if len (kv ) == 2 {
594
582
hookOptions .GitPushOptions [kv [0 ]] = kv [1 ]
595
583
}
596
584
}
597
585
}
598
586
599
- // run hook
587
+ // 3. run hook
600
588
resp , err := private .HookProcReceive (repoUser , repoName , hookOptions )
601
589
if err != nil {
602
590
fail ("Internal Server Error" , "run proc-receive hook failed :%v" , err )
603
591
}
604
592
605
- // 3 response result to service.
606
- // # OK, but has an alternate reference. The alternate reference name
593
+ // 4. response result to service
594
+ // # a. OK, but has an alternate reference. The alternate reference name
607
595
// # and other status can be given in option directives.
608
596
// H: PKT-LINE(ok <ref>)
609
597
// H: PKT-LINE(option refname <refname>)
@@ -612,28 +600,24 @@ Gitea or set your environment appropriately.`, "")
612
600
// H: PKT-LINE(option forced-update)
613
601
// H: ... ...
614
602
// H: flush-pkt
603
+ // # b. NO, I reject it.
604
+ // H: PKT-LINE(ng <ref> <reason>)
605
+
615
606
for _ , rs := range resp .Results {
616
- err = writePktLine (os .Stdout , pktLineTypeData , []byte ("ok " + rs .OrignRef ))
617
- if err != nil {
618
- fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
619
- }
620
- err = writePktLine (os .Stdout , pktLineTypeData , []byte ("option refname " + rs .Ref ))
621
- if err != nil {
622
- fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
623
- }
624
- err = writePktLine (os .Stdout , pktLineTypeData , []byte ("option old-oid " + rs .OldOID ))
625
- if err != nil {
626
- fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
607
+ if len (rs .Err ) > 0 {
608
+ writePktLine (os .Stdout , pktLineTypeData , []byte ("ng " + rs .OrignRef + " " + rs .Err ))
609
+ continue
627
610
}
628
- err = writePktLine (os .Stdout , pktLineTypeData , []byte ("option new-oid " + rs .NewOID ))
629
- if err != nil {
630
- fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
611
+
612
+ writePktLine (os .Stdout , pktLineTypeData , []byte ("ok " + rs .OrignRef ))
613
+ writePktLine (os .Stdout , pktLineTypeData , []byte ("option refname " + rs .Ref ))
614
+ if rs .OldOID != git .EmptySHA {
615
+ writePktLine (os .Stdout , pktLineTypeData , []byte ("option old-oid " + rs .OldOID ))
631
616
}
617
+ writePktLine (os .Stdout , pktLineTypeData , []byte ("option new-oid " + rs .NewOID ))
632
618
}
633
- err = writePktLine (os .Stdout , pktLineTypeFlush , nil )
634
- if err != nil {
635
- fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
636
- }
619
+ writePktLine (os .Stdout , pktLineTypeFlush , nil )
620
+
637
621
return nil
638
622
}
639
623
@@ -653,75 +637,93 @@ const (
653
637
// gitPktLine pkt-line api
654
638
type gitPktLine struct {
655
639
Type pktLineType
656
- Length int64
657
- Data string
640
+ Length uint64
641
+ Data [] byte
658
642
}
659
643
660
- func readPktLine (in * bufio.Reader ) (r * gitPktLine , err error ) {
644
+ func readPktLine (in * bufio.Reader , requestType pktLineType ) (r * gitPktLine ) {
645
+ var err error
646
+
661
647
// read prefix
662
648
lengthBytes := make ([]byte , 4 )
663
649
for i := 0 ; i < 4 ; i ++ {
664
650
lengthBytes [i ], err = in .ReadByte ()
665
651
if err != nil {
666
- return nil , err
652
+ fail ( "Internal Server Error" , "Pkt-Line: read stdin failed : %v" , err )
667
653
}
668
654
}
655
+
669
656
r = new (gitPktLine )
670
- r .Length , err = strconv .ParseInt (string (lengthBytes ), 16 , 64 )
657
+ r .Length , err = strconv .ParseUint (string (lengthBytes ), 16 , 32 )
671
658
if err != nil {
672
- return nil , err
659
+ fail ( "Internal Server Error" , "Pkt-Line format is wrong :%v" , err )
673
660
}
674
661
675
662
if r .Length == 0 {
663
+ if requestType == pktLineTypeData {
664
+ fail ("Internal Server Error" , "Pkt-Line format is wrong" )
665
+ }
676
666
r .Type = pktLineTypeFlush
677
- return r , nil
667
+ return r
678
668
}
679
669
680
- if r .Length <= 4 || r .Length > 65520 {
681
- r .Type = pktLineTypeUnknow
682
- return r , nil
670
+ if r .Length <= 4 || r .Length > 65520 || requestType == pktLineTypeFlush {
671
+ fail ("Internal Server Error" , "Pkt-Line format is wrong" )
683
672
}
684
673
685
- tmp : = make ([]byte , r .Length - 4 )
686
- for i := range tmp {
687
- tmp [i ], err = in .ReadByte ()
674
+ r . Data = make ([]byte , r .Length - 4 )
675
+ for i := range r . Data {
676
+ r . Data [i ], err = in .ReadByte ()
688
677
if err != nil {
689
- return nil , err
678
+ fail ( "Internal Server Error" , "Pkt-Line: read stdin failed : %v" , err )
690
679
}
691
680
}
692
681
693
682
r .Type = pktLineTypeData
694
- r .Data = string (tmp )
695
683
696
- return r , nil
684
+ return r
697
685
}
698
686
699
- func writePktLine (out io.Writer , typ pktLineType , data []byte ) error {
687
+ func writePktLine (out io.Writer , typ pktLineType , data []byte ) {
700
688
if typ == pktLineTypeFlush {
701
689
l , err := out .Write ([]byte ("0000" ))
702
690
if err != nil {
703
- return err
691
+ fail ( "Internal Server Error" , "Pkt-Line response failed: %v" , err )
704
692
}
705
693
if l != 4 {
706
- return fmt . Errorf ( "real write length is different with request, want %v, real %v" , 4 , l )
694
+ fail ( "Internal Server Error" , "Pkt-Line response failed: %v" , err )
707
695
}
708
696
}
709
697
710
698
if typ != pktLineTypeData {
711
- return nil
699
+ return
700
+ }
701
+
702
+ hexchar := []byte ("0123456789abcdef" )
703
+ hex := func (n uint64 ) byte {
704
+ return hexchar [(n )& 15 ]
712
705
}
713
706
714
- l := len (data ) + 4
715
- tmp := []byte (fmt .Sprintf ("%04x" , l ))
716
- tmp = append (tmp , data ... )
707
+ length := uint64 (len (data ) + 4 )
708
+ tmp := make ([]byte , 4 )
709
+ tmp [0 ] = hex (length >> 12 )
710
+ tmp [1 ] = hex (length >> 8 )
711
+ tmp [2 ] = hex (length >> 4 )
712
+ tmp [3 ] = hex (length )
717
713
718
714
lr , err := out .Write (tmp )
719
715
if err != nil {
720
- return err
716
+ fail ( "Internal Server Error" , "Pkt-Line response failed: %v" , err )
721
717
}
722
- if l != lr {
723
- return fmt . Errorf ( "real write length is different with request, want %v, real %v" , l , lr )
718
+ if 4 != lr {
719
+ fail ( "Internal Server Error" , "Pkt-Line response failed: %v" , err )
724
720
}
725
721
726
- return nil
722
+ lr , err = out .Write (data )
723
+ if err != nil {
724
+ fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
725
+ }
726
+ if int (length - 4 ) != lr {
727
+ fail ("Internal Server Error" , "Pkt-Line response failed: %v" , err )
728
+ }
727
729
}
0 commit comments