diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2016-11-08 23:46:38 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-08 23:46:38 +0100 |
commit | ac095bb12c4d29722b60ba9f20590fa7cfa6bc7d (patch) | |
tree | 223f36f336ba3414b1e45cac8af6c4744a5d7ef6 /clients/http | |
parent | e523701393598f4fa241dd407af9ff8925507a1a (diff) | |
download | go-git-ac095bb12c4d29722b60ba9f20590fa7cfa6bc7d.tar.gz |
new plumbing package (#118)
* plumbing: now core was renamed to core, and formats and clients moved inside
Diffstat (limited to 'clients/http')
-rw-r--r-- | clients/http/common.go | 77 | ||||
-rw-r--r-- | clients/http/common_test.go | 52 | ||||
-rw-r--r-- | clients/http/git_upload_pack.go | 186 | ||||
-rw-r--r-- | clients/http/git_upload_pack_test.go | 135 |
4 files changed, 0 insertions, 450 deletions
diff --git a/clients/http/common.go b/clients/http/common.go deleted file mode 100644 index 483308a..0000000 --- a/clients/http/common.go +++ /dev/null @@ -1,77 +0,0 @@ -// Package http implements a HTTP client for go-git. -package http - -import ( - "fmt" - "net/http" - - "gopkg.in/src-d/go-git.v4/clients/common" - "gopkg.in/src-d/go-git.v4/core" -) - -// HTTPAuthMethod concrete implementation of common.AuthMethod for HTTP services -type HTTPAuthMethod interface { - common.AuthMethod - setAuth(r *http.Request) -} - -// BasicAuth represent a HTTP basic auth -type BasicAuth struct { - username, password string -} - -// NewBasicAuth returns a BasicAuth base on the given user and password -func NewBasicAuth(username, password string) *BasicAuth { - return &BasicAuth{username, password} -} - -func (a *BasicAuth) setAuth(r *http.Request) { - r.SetBasicAuth(a.username, a.password) -} - -// Name name of the auth -func (a *BasicAuth) Name() string { - return "http-basic-auth" -} - -func (a *BasicAuth) String() string { - masked := "*******" - if a.password == "" { - masked = "<empty>" - } - - return fmt.Sprintf("%s - %s:%s", a.Name(), a.username, masked) -} - -// HTTPError a dedicated error to return errors bases on status codes -type HTTPError struct { - Response *http.Response -} - -// NewHTTPError returns a new HTTPError based on a http response -func NewHTTPError(r *http.Response) error { - if r.StatusCode >= 200 && r.StatusCode < 300 { - return nil - } - - switch r.StatusCode { - case 401: - return common.ErrAuthorizationRequired - case 404: - return common.ErrRepositoryNotFound - } - - err := &HTTPError{r} - return core.NewUnexpectedError(err) -} - -// StatusCode returns the status code of the response -func (e *HTTPError) StatusCode() int { - return e.Response.StatusCode -} - -func (e *HTTPError) Error() string { - return fmt.Sprintf("unexpected requesting %q status code: %d", - e.Response.Request.URL, e.Response.StatusCode, - ) -} diff --git a/clients/http/common_test.go b/clients/http/common_test.go deleted file mode 100644 index 287897d..0000000 --- a/clients/http/common_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package http - -import ( - "net/http" - "testing" - - . "gopkg.in/check.v1" -) - -func Test(t *testing.T) { TestingT(t) } - -type SuiteCommon struct{} - -var _ = Suite(&SuiteCommon{}) - -func (s *SuiteCommon) TestNewBasicAuth(c *C) { - a := NewBasicAuth("foo", "qux") - - c.Assert(a.Name(), Equals, "http-basic-auth") - c.Assert(a.String(), Equals, "http-basic-auth - foo:*******") -} - -func (s *SuiteCommon) TestNewHTTPError200(c *C) { - res := &http.Response{StatusCode: 200} - res.StatusCode = 200 - err := NewHTTPError(res) - c.Assert(err, IsNil) -} - -func (s *SuiteCommon) TestNewHTTPError401(c *C) { - s.testNewHTTPError(c, 401, "authorization required") -} - -func (s *SuiteCommon) TestNewHTTPError404(c *C) { - s.testNewHTTPError(c, 404, "repository not found") -} - -func (s *SuiteCommon) TestNewHTTPError40x(c *C) { - s.testNewHTTPError(c, 402, "unexpected client error.*") -} - -func (s *SuiteCommon) testNewHTTPError(c *C, code int, msg string) { - req, _ := http.NewRequest("GET", "foo", nil) - res := &http.Response{ - StatusCode: code, - Request: req, - } - - err := NewHTTPError(res) - c.Assert(err, NotNil) - c.Assert(err, ErrorMatches, msg) -} diff --git a/clients/http/git_upload_pack.go b/clients/http/git_upload_pack.go deleted file mode 100644 index f652150..0000000 --- a/clients/http/git_upload_pack.go +++ /dev/null @@ -1,186 +0,0 @@ -package http - -import ( - "bufio" - "bytes" - "fmt" - "io" - "net/http" - "strings" - - "gopkg.in/src-d/go-git.v4/clients/common" - "gopkg.in/src-d/go-git.v4/core" - "gopkg.in/src-d/go-git.v4/formats/packp/pktline" -) - -// GitUploadPackService git-upoad-pack service over HTTP -type GitUploadPackService struct { - client *http.Client - endpoint common.Endpoint - auth HTTPAuthMethod -} - -// NewGitUploadPackService connects to a git-upload-pack service over HTTP, the -// auth is extracted from the URL, or can be provided using the SetAuth method -func NewGitUploadPackService(endpoint common.Endpoint) common.GitUploadPackService { - s := &GitUploadPackService{ - client: http.DefaultClient, - endpoint: endpoint, - } - - s.setBasicAuthFromEndpoint() - return s -} - -// Connect has not any effect, is here just for meet the interface -func (s *GitUploadPackService) Connect() error { - return nil -} - -func (s *GitUploadPackService) setBasicAuthFromEndpoint() { - info := s.endpoint.User - if info == nil { - return - } - - p, ok := info.Password() - if !ok { - return - } - - u := info.Username() - s.auth = NewBasicAuth(u, p) -} - -// SetAuth sets the AuthMethod -func (s *GitUploadPackService) SetAuth(auth common.AuthMethod) error { - httpAuth, ok := auth.(HTTPAuthMethod) - if !ok { - return common.ErrInvalidAuthMethod - } - - s.auth = httpAuth - return nil -} - -// Info returns the references info and capabilities from the service -func (s *GitUploadPackService) Info() (*common.GitUploadPackInfo, error) { - url := fmt.Sprintf( - "%s/info/refs?service=%s", - s.endpoint.String(), common.GitUploadPackServiceName, - ) - - res, err := s.doRequest("GET", url, nil) - if err != nil { - return nil, err - } - - defer res.Body.Close() - - i := common.NewGitUploadPackInfo() - return i, i.Decode(res.Body) -} - -// Fetch request and returns a reader to a packfile -func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (io.ReadCloser, error) { - url := fmt.Sprintf( - "%s/%s", - s.endpoint.String(), common.GitUploadPackServiceName, - ) - - res, err := s.doRequest("POST", url, r.Reader()) - if err != nil { - return nil, err - } - - reader := newBufferedReadCloser(res.Body) - if _, err := reader.Peek(1); err != nil { - if err == io.ErrUnexpectedEOF { - return nil, common.ErrEmptyGitUploadPack - } - - return nil, err - } - - if err := discardResponseInfo(reader); err != nil { - return nil, err - } - - return reader, nil -} - -func discardResponseInfo(r io.Reader) error { - s := pktline.NewScanner(r) - for s.Scan() { - if bytes.Equal(s.Bytes(), []byte{'N', 'A', 'K', '\n'}) { - break - } - } - - return s.Err() -} - -func (s *GitUploadPackService) doRequest(method, url string, content *strings.Reader) (*http.Response, error) { - var body io.Reader - if content != nil { - body = content - } - - req, err := http.NewRequest(method, url, body) - if err != nil { - return nil, core.NewPermanentError(err) - } - - s.applyHeadersToRequest(req, content) - s.applyAuthToRequest(req) - - res, err := s.client.Do(req) - if err != nil { - return nil, core.NewUnexpectedError(err) - } - - if err := NewHTTPError(res); err != nil { - return nil, err - } - - return res, nil -} - -func (s *GitUploadPackService) applyHeadersToRequest(req *http.Request, content *strings.Reader) { - req.Header.Add("User-Agent", "git/1.0") - req.Header.Add("Host", "github.com") - - if content == nil { - req.Header.Add("Accept", "*/*") - } else { - 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", string(content.Len())) - } -} - -func (s *GitUploadPackService) applyAuthToRequest(req *http.Request) { - if s.auth == nil { - return - } - - s.auth.setAuth(req) -} - -// Disconnect do nothing -func (s *GitUploadPackService) Disconnect() (err error) { - return nil -} - -type bufferedReadCloser struct { - *bufio.Reader - closer io.Closer -} - -func newBufferedReadCloser(r io.ReadCloser) *bufferedReadCloser { - return &bufferedReadCloser{bufio.NewReader(r), r} -} - -func (r *bufferedReadCloser) Close() error { - return r.closer.Close() -} diff --git a/clients/http/git_upload_pack_test.go b/clients/http/git_upload_pack_test.go deleted file mode 100644 index 579419f..0000000 --- a/clients/http/git_upload_pack_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package http - -import ( - "io/ioutil" - - . "gopkg.in/check.v1" - "gopkg.in/src-d/go-git.v4/clients/common" - "gopkg.in/src-d/go-git.v4/core" -) - -type RemoteSuite struct { - Endpoint common.Endpoint -} - -var _ = Suite(&RemoteSuite{}) - -func (s *RemoteSuite) SetUpSuite(c *C) { - var err error - s.Endpoint, err = common.NewEndpoint("https://github.com/git-fixtures/basic") - c.Assert(err, IsNil) -} - -func (s *RemoteSuite) TestNewGitUploadPackServiceAuth(c *C) { - e, err := common.NewEndpoint("https://foo:bar@github.com/git-fixtures/basic") - c.Assert(err, IsNil) - - r := NewGitUploadPackService(e) - auth := r.(*GitUploadPackService).auth - - c.Assert(auth.String(), Equals, "http-basic-auth - foo:*******") -} - -func (s *RemoteSuite) TestConnect(c *C) { - r := NewGitUploadPackService(s.Endpoint) - c.Assert(r.Connect(), IsNil) -} - -func (s *RemoteSuite) TestSetAuth(c *C) { - auth := &BasicAuth{} - r := NewGitUploadPackService(s.Endpoint) - r.SetAuth(auth) - c.Assert(auth, Equals, r.(*GitUploadPackService).auth) -} - -type mockAuth struct{} - -func (*mockAuth) Name() string { return "" } -func (*mockAuth) String() string { return "" } - -func (s *RemoteSuite) TestSetAuthWrongType(c *C) { - r := NewGitUploadPackService(s.Endpoint) - c.Assert(r.SetAuth(&mockAuth{}), Equals, common.ErrInvalidAuthMethod) -} - -func (s *RemoteSuite) TestInfoEmpty(c *C) { - endpoint, _ := common.NewEndpoint("https://github.com/git-fixture/empty") - r := NewGitUploadPackService(endpoint) - c.Assert(r.Connect(), IsNil) - - info, err := r.Info() - c.Assert(err, Equals, common.ErrAuthorizationRequired) - c.Assert(info, IsNil) -} - -func (s *RemoteSuite) TestInfoNotExists(c *C) { - endpoint, _ := common.NewEndpoint("https://github.com/git-fixture/not-exists") - r := NewGitUploadPackService(endpoint) - c.Assert(r.Connect(), IsNil) - - info, err := r.Info() - c.Assert(err, Equals, common.ErrAuthorizationRequired) - c.Assert(info, IsNil) -} - -func (s *RemoteSuite) TestDefaultBranch(c *C) { - r := NewGitUploadPackService(s.Endpoint) - c.Assert(r.Connect(), IsNil) - - info, err := r.Info() - c.Assert(err, IsNil) - c.Assert(info.Capabilities.SymbolicReference("HEAD"), Equals, "refs/heads/master") -} - -func (s *RemoteSuite) TestCapabilities(c *C) { - r := NewGitUploadPackService(s.Endpoint) - c.Assert(r.Connect(), IsNil) - - info, err := r.Info() - c.Assert(err, IsNil) - c.Assert(info.Capabilities.Get("agent").Values, HasLen, 1) -} - -func (s *RemoteSuite) TestFetch(c *C) { - r := NewGitUploadPackService(s.Endpoint) - c.Assert(r.Connect(), IsNil) - - req := &common.GitUploadPackRequest{} - req.Want(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - - reader, err := r.Fetch(req) - c.Assert(err, IsNil) - - b, err := ioutil.ReadAll(reader) - c.Assert(err, IsNil) - c.Assert(b, HasLen, 85374) -} - -func (s *RemoteSuite) TestFetchNoChanges(c *C) { - r := NewGitUploadPackService(s.Endpoint) - c.Assert(r.Connect(), IsNil) - - req := &common.GitUploadPackRequest{} - req.Want(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - req.Have(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - - reader, err := r.Fetch(req) - c.Assert(err, Equals, common.ErrEmptyGitUploadPack) - c.Assert(reader, IsNil) -} - -func (s *RemoteSuite) TestFetchMulti(c *C) { - r := NewGitUploadPackService(s.Endpoint) - c.Assert(r.Connect(), IsNil) - - req := &common.GitUploadPackRequest{} - req.Want(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - req.Want(core.NewHash("e8d3ffab552895c19b9fcf7aa264d277cde33881")) - - reader, err := r.Fetch(req) - c.Assert(err, IsNil) - - b, err := ioutil.ReadAll(reader) - c.Assert(err, IsNil) - c.Assert(b, HasLen, 85585) -} |