From 01ea726be6ed745a21c88fd61fc5e2a62c4ceb88 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Wed, 7 Dec 2016 11:16:59 +0100 Subject: remote: sideband support (#164) * remote: sideband support * changes --- plumbing/protocol/packp/sideband/demux.go | 36 ++++++++++++++------------ plumbing/protocol/packp/sideband/demux_test.go | 3 +++ plumbing/protocol/packp/ulreq.go | 6 +++++ plumbing/protocol/packp/ulreq_test.go | 2 +- 4 files changed, 29 insertions(+), 18 deletions(-) (limited to 'plumbing/protocol') diff --git a/plumbing/protocol/packp/sideband/demux.go b/plumbing/protocol/packp/sideband/demux.go index 1669ed4..6470380 100644 --- a/plumbing/protocol/packp/sideband/demux.go +++ b/plumbing/protocol/packp/sideband/demux.go @@ -1,7 +1,6 @@ package sideband import ( - "bytes" "errors" "fmt" "io" @@ -15,21 +14,22 @@ var ErrMaxPackedExceeded = errors.New("max. packed size exceeded") // Progress allows to read the progress information type Progress interface { io.Reader + io.Writer } // Demuxer demultiplex the progress reports and error info interleaved with the // packfile itself. // -// A sideband has three different channels the main one call PackData contains +// A sideband has three different channels the main one, call PackData, contains // the packfile data, the ErrorMessage channel, that contains server errors and // the last one ProgressMessage channel containing information about the ongoing -// task happening in the server (optinal, can be suppressed sending NoProgress +// task happening in the server (optional, can be suppressed sending NoProgress // or Quiet capabilities to the server) // // In order to demultiplex the data stream, method `Read` should be called to // retrieve the PackData channel, the incoming data from the ProgressMessage is -// stored and can be read from `Progress` field, if any message is retrieved -// from the ErrorMessage channel an error is returned and we can assume that the +// written at `Progress` (if any), if any message is retrieved from the +// ErrorMessage channel an error is returned and we can assume that the // connection has been closed. type Demuxer struct { t Type @@ -39,7 +39,7 @@ type Demuxer struct { max int pending []byte - // Progress contains progress information + // Progress is where the progress messages are stored Progress Progress } @@ -51,21 +51,19 @@ func NewDemuxer(t Type, r io.Reader) *Demuxer { } return &Demuxer{ - t: t, - r: r, - max: max, - s: pktline.NewScanner(r), - Progress: bytes.NewBuffer(nil), + t: t, + r: r, + max: max, + s: pktline.NewScanner(r), } } // Read reads up to len(p) bytes from the PackData channel into p, an error can -// be return if an error happends when reading or if a message is sent in the +// be return if an error happens when reading or if a message is sent in the // ErrorMessage channel. // -// If a ProgressMessage is read, it won't be copied to b. Instead of this, it is -// stored and can be read through the reader Progress. If the n value returned -// is zero, err will be nil unless an error reading happens. +// When a ProgressMessage is read, is not copy to b, instead of this is written +// to the Progress func (d *Demuxer) Read(b []byte) (n int, err error) { var read, req int @@ -126,13 +124,17 @@ func (d *Demuxer) nextPackData() ([]byte, error) { case PackData: return content[1:], nil case ProgressMessage: - _, err := d.Progress.(io.Writer).Write(content[1:]) - return nil, err + if d.Progress != nil { + _, err := d.Progress.Write(content[1:]) + return nil, err + } case ErrorMessage: return nil, fmt.Errorf("unexpected error: %s", content[1:]) default: return nil, fmt.Errorf("unknown channel %s", content) } + + return nil, nil } func (d *Demuxer) getPending() (b []byte) { diff --git a/plumbing/protocol/packp/sideband/demux_test.go b/plumbing/protocol/packp/sideband/demux_test.go index 4814d89..ee5f19a 100644 --- a/plumbing/protocol/packp/sideband/demux_test.go +++ b/plumbing/protocol/packp/sideband/demux_test.go @@ -24,6 +24,7 @@ func (s *SidebandSuite) TestDecode(c *C) { buf := bytes.NewBuffer(nil) e := pktline.NewEncoder(buf) e.Encode(PackData.WithPayload(expected[0:8])) + e.Encode(ProgressMessage.WithPayload([]byte{'F', 'O', 'O', '\n'})) e.Encode(PackData.WithPayload(expected[8:16])) e.Encode(PackData.WithPayload(expected[16:26])) @@ -92,6 +93,8 @@ func (s *SidebandSuite) TestDecodeWithProgress(c *C) { content := make([]byte, 26) d := NewDemuxer(Sideband64k, buf) + d.Progress = bytes.NewBuffer(nil) + n, err := io.ReadFull(d, content) c.Assert(err, IsNil) c.Assert(n, Equals, 26) diff --git a/plumbing/protocol/packp/ulreq.go b/plumbing/protocol/packp/ulreq.go index d57c3fc..faf0885 100644 --- a/plumbing/protocol/packp/ulreq.go +++ b/plumbing/protocol/packp/ulreq.go @@ -82,6 +82,12 @@ func NewUploadRequestFromCapabilities(adv *capability.List) *UploadRequest { r.Capabilities.Set(capability.MultiACK) } + if adv.Supports(capability.Sideband64k) { + r.Capabilities.Set(capability.Sideband64k) + } else if adv.Supports(capability.Sideband) { + r.Capabilities.Set(capability.Sideband) + } + if adv.Supports(capability.ThinPack) { r.Capabilities.Set(capability.ThinPack) } diff --git a/plumbing/protocol/packp/ulreq_test.go b/plumbing/protocol/packp/ulreq_test.go index 177cf0e..f000b91 100644 --- a/plumbing/protocol/packp/ulreq_test.go +++ b/plumbing/protocol/packp/ulreq_test.go @@ -29,7 +29,7 @@ func (s *UlReqSuite) TestNewUploadRequestFromCapabilities(c *C) { r := NewUploadRequestFromCapabilities(cap) c.Assert(r.Capabilities.String(), Equals, - "multi_ack_detailed thin-pack ofs-delta agent=go-git/4.x", + "multi_ack_detailed side-band-64k thin-pack ofs-delta agent=go-git/4.x", ) } -- cgit