diff options
author | Santiago M. Mola <santi@mola.io> | 2017-01-04 11:18:41 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-04 11:18:41 +0100 |
commit | 841abfb7dc640755c443432064252907e3e55c95 (patch) | |
tree | 8af69dcd3b301a10a3e493e2cd805cdec6dcaecd /plumbing/transport/http/fetch_pack.go | |
parent | 90d67bb648ae32d5b1a0f7b1af011da6dfb24315 (diff) | |
download | go-git-841abfb7dc640755c443432064252907e3e55c95.tar.gz |
server: add git server implementation (#190)
* server: add generic server implementation (transport-independent),
both for git-upload-pack and git-receive-pack.
* server: move internal functions to internal/common.
* cli: add git-receive-pack and git-upload-pack implementations.
* format/packfile: add UpdateObjectStorage function, extracted from
Remote.
* transport: implement tranport RPC-like, only with git-upload-pack and
git-receive-pack methods. Client renamed to Transport.
* storer: add storer.Storer interface.
* protocol/packp: add UploadPackResponse constructor with packfile.
* protocol/packp: fix UploadPackResponse encoding, add tests.
* protocol/packp/capability: implement All.
Diffstat (limited to 'plumbing/transport/http/fetch_pack.go')
-rw-r--r-- | plumbing/transport/http/fetch_pack.go | 174 |
1 files changed, 0 insertions, 174 deletions
diff --git a/plumbing/transport/http/fetch_pack.go b/plumbing/transport/http/fetch_pack.go deleted file mode 100644 index 0c85be4..0000000 --- a/plumbing/transport/http/fetch_pack.go +++ /dev/null @@ -1,174 +0,0 @@ -package http - -import ( - "bytes" - "fmt" - "io" - "net/http" - "strconv" - - "gopkg.in/src-d/go-git.v4/plumbing" - "gopkg.in/src-d/go-git.v4/plumbing/format/pktline" - "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/plumbing/transport/internal/common" - "gopkg.in/src-d/go-git.v4/utils/ioutil" -) - -type fetchPackSession struct { - *session -} - -func newFetchPackSession(c *http.Client, - ep transport.Endpoint) transport.FetchPackSession { - - return &fetchPackSession{ - session: &session{ - auth: basicAuthFromEndpoint(ep), - client: c, - endpoint: ep, - }, - } -} - -func (s *fetchPackSession) AdvertisedReferences() (*packp.AdvRefs, error) { - if s.advRefs != nil { - return s.advRefs, nil - } - - url := fmt.Sprintf( - "%s/info/refs?service=%s", - s.endpoint.String(), transport.UploadPackServiceName, - ) - - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return nil, err - } - - s.applyAuthToRequest(req) - s.applyHeadersToRequest(req, nil) - res, err := s.client.Do(req) - if err != nil { - return nil, err - } - - defer res.Body.Close() - - if res.StatusCode == http.StatusUnauthorized { - return nil, transport.ErrAuthorizationRequired - } - - ar := packp.NewAdvRefs() - if err := ar.Decode(res.Body); err != nil { - if err == packp.ErrEmptyAdvRefs { - err = transport.ErrEmptyRemoteRepository - } - - return nil, err - } - - transport.FilterUnsupportedCapabilities(ar.Capabilities) - s.advRefs = ar - return ar, nil -} - -func (s *fetchPackSession) FetchPack(req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { - if req.IsEmpty() { - return nil, transport.ErrEmptyUploadPackRequest - } - - if err := req.Validate(); err != nil { - return nil, err - } - - url := fmt.Sprintf( - "%s/%s", - s.endpoint.String(), transport.UploadPackServiceName, - ) - - content, err := uploadPackRequestToReader(req) - if err != nil { - return nil, err - } - - res, err := s.doRequest(http.MethodPost, url, content) - if err != nil { - return nil, err - } - - r, err := ioutil.NonEmptyReader(res.Body) - if err != nil { - if err == ioutil.ErrEmptyReader || err == io.ErrUnexpectedEOF { - return nil, transport.ErrEmptyUploadPackRequest - } - - return nil, err - } - - rc := ioutil.NewReadCloser(r, res.Body) - return common.DecodeUploadPackResponse(rc, req) -} - -// Close does nothing. -func (s *fetchPackSession) Close() error { - return nil -} - -func (s *fetchPackSession) doRequest(method, url string, content *bytes.Buffer) (*http.Response, error) { - var body io.Reader - if content != nil { - body = content - } - - req, err := http.NewRequest(method, url, body) - if err != nil { - return nil, plumbing.NewPermanentError(err) - } - - s.applyHeadersToRequest(req, content) - s.applyAuthToRequest(req) - - res, err := s.client.Do(req) - if err != nil { - return nil, plumbing.NewUnexpectedError(err) - } - - if err := NewErr(res); err != nil { - _ = res.Body.Close() - return nil, err - } - - return res, nil -} - -// it requires a bytes.Buffer, because we need to know the length -func (s *fetchPackSession) applyHeadersToRequest(req *http.Request, content *bytes.Buffer) { - req.Header.Add("User-Agent", "git/1.0") - req.Header.Add("Host", s.endpoint.Host) - - if content == nil { - req.Header.Add("Accept", "*/*") - return - } - - req.Header.Add("Accept", "application/x-git-upload-pack-result") - req.Header.Add("Content-Type", "application/x-git-upload-pack-request") - req.Header.Add("Content-Length", strconv.Itoa(content.Len())) -} - -func uploadPackRequestToReader(req *packp.UploadPackRequest) (*bytes.Buffer, error) { - buf := bytes.NewBuffer(nil) - e := pktline.NewEncoder(buf) - - if err := req.UploadRequest.Encode(buf); err != nil { - return nil, fmt.Errorf("sending upload-req message: %s", err) - } - - if err := req.UploadHaves.Encode(buf); err != nil { - return nil, fmt.Errorf("sending haves message: %s", err) - } - - _ = e.EncodeString("done\n") - return buf, nil -} |