|
- package packp
-
- import (
- "errors"
- "io"
-
- "bufio"
-
- "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability"
- "gopkg.in/src-d/go-git.v4/utils/ioutil"
- )
-
- // ErrUploadPackResponseNotDecoded is returned if Read is called without
- // decoding first
- var ErrUploadPackResponseNotDecoded = errors.New("upload-pack-response should be decoded")
-
- // UploadPackResponse contains all the information responded by the upload-pack
- // service, the response implements io.ReadCloser that allows to read the
- // packfile directly from it.
- type UploadPackResponse struct {
- ShallowUpdate
- ServerResponse
-
- r io.ReadCloser
- isShallow bool
- isMultiACK bool
- isOk bool
- }
-
- // NewUploadPackResponse create a new UploadPackResponse instance, the request
- // being responded by the response is required.
- func NewUploadPackResponse(req *UploadPackRequest) *UploadPackResponse {
- isShallow := !req.Depth.IsZero()
- isMultiACK := req.Capabilities.Supports(capability.MultiACK) ||
- req.Capabilities.Supports(capability.MultiACKDetailed)
-
- return &UploadPackResponse{
- isShallow: isShallow,
- isMultiACK: isMultiACK,
- }
- }
-
- // NewUploadPackResponseWithPackfile creates a new UploadPackResponse instance,
- // and sets its packfile reader.
- func NewUploadPackResponseWithPackfile(req *UploadPackRequest,
- pf io.ReadCloser) *UploadPackResponse {
-
- r := NewUploadPackResponse(req)
- r.r = pf
- return r
- }
-
- // Decode decodes all the responses sent by upload-pack service into the struct
- // and prepares it to read the packfile using the Read method
- func (r *UploadPackResponse) Decode(reader io.ReadCloser) error {
- buf := bufio.NewReader(reader)
-
- if r.isShallow {
- if err := r.ShallowUpdate.Decode(buf); err != nil {
- return err
- }
- }
-
- if err := r.ServerResponse.Decode(buf, r.isMultiACK); err != nil {
- return err
- }
-
- // now the reader is ready to read the packfile content
- r.r = ioutil.NewReadCloser(buf, reader)
-
- return nil
- }
-
- // Encode encodes an UploadPackResponse.
- func (r *UploadPackResponse) Encode(w io.Writer) (err error) {
- if r.isShallow {
- if err := r.ShallowUpdate.Encode(w); err != nil {
- return err
- }
- }
-
- if err := r.ServerResponse.Encode(w); err != nil {
- return err
- }
-
- defer ioutil.CheckClose(r.r, &err)
- _, err = io.Copy(w, r.r)
- return err
- }
-
- // Read reads the packfile data, if the request was done with any Sideband
- // capability the content read should be demultiplexed. If the methods wasn't
- // called before the ErrUploadPackResponseNotDecoded will be return
- func (r *UploadPackResponse) Read(p []byte) (int, error) {
- if r.r == nil {
- return 0, ErrUploadPackResponseNotDecoded
- }
-
- return r.r.Read(p)
- }
-
- // Close the underlying reader, if any
- func (r *UploadPackResponse) Close() error {
- if r.r == nil {
- return nil
- }
-
- return r.r.Close()
- }
|