diff options
Diffstat (limited to 'plumbing/transport/internal')
-rw-r--r-- | plumbing/transport/internal/common/common.go | 28 | ||||
-rw-r--r-- | plumbing/transport/internal/common/server.go | 72 |
2 files changed, 86 insertions, 14 deletions
diff --git a/plumbing/transport/internal/common/common.go b/plumbing/transport/internal/common/common.go index 17c473e..831c4d7 100644 --- a/plumbing/transport/internal/common/common.go +++ b/plumbing/transport/internal/common/common.go @@ -77,20 +77,20 @@ type client struct { } // NewClient creates a new client using the given Commander. -func NewClient(runner Commander) transport.Client { +func NewClient(runner Commander) transport.Transport { return &client{runner} } -// NewFetchPackSession creates a new FetchPackSession. -func (c *client) NewFetchPackSession(ep transport.Endpoint) ( - transport.FetchPackSession, error) { +// NewUploadPackSession creates a new UploadPackSession. +func (c *client) NewUploadPackSession(ep transport.Endpoint) ( + transport.UploadPackSession, error) { return c.newSession(transport.UploadPackServiceName, ep) } -// NewSendPackSession creates a new SendPackSession. -func (c *client) NewSendPackSession(ep transport.Endpoint) ( - transport.SendPackSession, error) { +// NewReceivePackSession creates a new ReceivePackSession. +func (c *client) NewReceivePackSession(ep transport.Endpoint) ( + transport.ReceivePackSession, error) { return c.newSession(transport.ReceivePackServiceName, ep) } @@ -219,9 +219,9 @@ func (s *session) handleAdvRefDecodeError(err error) error { return err } -// FetchPack performs a request to the server to fetch a packfile. A reader is +// UploadPack performs a request to the server to fetch a packfile. A reader is // returned with the packfile content. The reader must be closed after reading. -func (s *session) FetchPack(req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { +func (s *session) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { if req.IsEmpty() { return nil, transport.ErrEmptyUploadPackRequest } @@ -236,7 +236,7 @@ func (s *session) FetchPack(req *packp.UploadPackRequest) (*packp.UploadPackResp s.packRun = true - if err := fetchPack(s.Stdin, s.Stdout, req); err != nil { + if err := uploadPack(s.Stdin, s.Stdout, req); err != nil { return nil, err } @@ -259,7 +259,7 @@ func (s *session) FetchPack(req *packp.UploadPackRequest) (*packp.UploadPackResp return DecodeUploadPackResponse(rc, req) } -func (s *session) SendPack(req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) { +func (s *session) ReceivePack(req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) { if _, err := s.AdvertisedReferences(); err != nil { return nil, err } @@ -295,7 +295,7 @@ func (s *session) finish() error { s.finished = true - // If we did not run fetch-pack or send-pack, we close the connection + // If we did not run a upload/receive-pack, we close the connection // gracefully by sending a flush packet to the server. If the server // operates correctly, it will exit with status 0. if !s.packRun { @@ -367,13 +367,13 @@ var ( eol = []byte("\n") ) -// fetchPack implements the git-fetch-pack protocol. +// uploadPack implements the git-upload-pack protocol. // // TODO support multi_ack mode // TODO support multi_ack_detailed mode // TODO support acks for common objects // TODO build a proper state machine for all these processing options -func fetchPack(w io.WriteCloser, r io.Reader, req *packp.UploadPackRequest) error { +func uploadPack(w io.WriteCloser, r io.Reader, req *packp.UploadPackRequest) error { if err := req.UploadRequest.Encode(w); err != nil { return fmt.Errorf("sending upload-req message: %s", err) } diff --git a/plumbing/transport/internal/common/server.go b/plumbing/transport/internal/common/server.go new file mode 100644 index 0000000..dd6cfbe --- /dev/null +++ b/plumbing/transport/internal/common/server.go @@ -0,0 +1,72 @@ +package common + +import ( + "fmt" + "io" + + "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp" + "gopkg.in/src-d/go-git.v4/plumbing/transport" + "gopkg.in/src-d/go-git.v4/utils/ioutil" +) + +// ServerCommand is used for a single server command execution. +type ServerCommand struct { + Stderr io.Writer + Stdout io.WriteCloser + Stdin io.Reader +} + +func ServeUploadPack(cmd ServerCommand, s transport.UploadPackSession) (err error) { + ioutil.CheckClose(cmd.Stdout, &err) + + ar, err := s.AdvertisedReferences() + if err != nil { + return err + } + + if err := ar.Encode(cmd.Stdout); err != nil { + return err + } + + req := packp.NewUploadPackRequest() + if err := req.Decode(cmd.Stdin); err != nil { + return err + } + + var resp *packp.UploadPackResponse + resp, err = s.UploadPack(req) + if err != nil { + return err + } + + return resp.Encode(cmd.Stdout) +} + +func ServeReceivePack(cmd ServerCommand, s transport.ReceivePackSession) error { + ar, err := s.AdvertisedReferences() + if err != nil { + return fmt.Errorf("internal error in advertised references: %s", err) + } + + if err := ar.Encode(cmd.Stdout); err != nil { + return fmt.Errorf("error in advertised references encoding: %s", err) + } + + req := packp.NewReferenceUpdateRequest() + if err := req.Decode(cmd.Stdin); err != nil { + return fmt.Errorf("error decoding: %s", err) + } + + rs, err := s.ReceivePack(req) + if rs != nil { + if err := rs.Encode(cmd.Stdout); err != nil { + return fmt.Errorf("error in encoding report status %s", err) + } + } + + if err != nil { + return fmt.Errorf("error in receive pack: %s", err) + } + + return nil +} |