Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 5135923

Browse files
committed
clients/http: better error handling
1 parent 1eb3872 commit 5135923

File tree

6 files changed

+77
-16
lines changed

6 files changed

+77
-16
lines changed

clients/common/common.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ import (
1616
)
1717

1818
var (
19-
ErrNotFound = errors.New("repository not found")
20-
ErrEmptyGitUploadPack = errors.New("empty git-upload-pack given")
21-
ErrInvalidAuthMethod = errors.New("invalid auth method")
19+
ErrRepositoryNotFound = errors.New("repository not found")
20+
ErrAuthorizationRequired = errors.New("authorization required")
21+
ErrEmptyGitUploadPack = errors.New("empty git-upload-pack given")
22+
ErrInvalidAuthMethod = errors.New("invalid auth method")
2223
)
2324

2425
const GitUploadPackServiceName = "git-upload-pack"

clients/http/common.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@ func NewHTTPError(r *http.Response) error {
4848
return nil
4949
}
5050

51-
err := &HTTPError{r}
52-
if r.StatusCode == 404 || r.StatusCode == 401 {
53-
return core.NewPermanentError(common.ErrNotFound)
51+
switch r.StatusCode {
52+
case 401:
53+
return common.ErrAuthorizationRequired
54+
case 404:
55+
return common.ErrRepositoryNotFound
5456
}
5557

58+
err := &HTTPError{r}
5659
return core.NewUnexpectedError(err)
5760
}
5861

clients/http/common_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ func (s *SuiteCommon) TestNewHTTPError200(c *C) {
2828
}
2929

3030
func (s *SuiteCommon) TestNewHTTPError401(c *C) {
31-
s.testNewHTTPError(c, 401, "permanent client error.*not found.*")
31+
s.testNewHTTPError(c, 401, "authorization required")
3232
}
3333

3434
func (s *SuiteCommon) TestNewHTTPError404(c *C) {
35-
s.testNewHTTPError(c, 404, "permanent client error.*not found.*")
35+
s.testNewHTTPError(c, 404, "repository not found")
3636
}
3737

3838
func (s *SuiteCommon) TestNewHTTPError40x(c *C) {

clients/http/git_upload_pack.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package http
22

33
import (
4+
"bufio"
45
"fmt"
56
"io"
67
"net/http"
@@ -66,11 +67,20 @@ func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (io.ReadClo
6667
return nil, err
6768
}
6869

69-
if err := s.discardResponseInfo(res.Body); err != nil {
70+
reader := newBufferedReadCloser(res.Body)
71+
if _, err := reader.Peek(1); err != nil {
72+
if err == io.ErrUnexpectedEOF {
73+
return nil, common.ErrEmptyGitUploadPack
74+
}
75+
76+
return nil, err
77+
}
78+
79+
if err := s.discardResponseInfo(reader); err != nil {
7080
return nil, err
7181
}
7282

73-
return res.Body, nil
83+
return reader, nil
7484
}
7585

7686
func (s *GitUploadPackService) discardResponseInfo(r io.Reader) error {
@@ -138,3 +148,16 @@ func (s *GitUploadPackService) applyAuthToRequest(req *http.Request) {
138148
func (s *GitUploadPackService) Disconnect() (err error) {
139149
return nil
140150
}
151+
152+
type bufferedReadCloser struct {
153+
*bufio.Reader
154+
closer io.Closer
155+
}
156+
157+
func newBufferedReadCloser(r io.ReadCloser) *bufferedReadCloser {
158+
return &bufferedReadCloser{bufio.NewReader(r), r}
159+
}
160+
161+
func (r *bufferedReadCloser) Close() error {
162+
return r.closer.Close()
163+
}

clients/http/git_upload_pack_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,26 @@ func (s *RemoteSuite) TestConnectWithAuthWrongType(c *C) {
4141
c.Assert(r.ConnectWithAuth(&mockAuth{}), Equals, common.ErrInvalidAuthMethod)
4242
}
4343

44+
func (s *RemoteSuite) TestInfoEmpty(c *C) {
45+
endpoint, _ := common.NewEndpoint("https://github.com/git-fixture/empty")
46+
r := NewGitUploadPackService(endpoint)
47+
c.Assert(r.Connect(), IsNil)
48+
49+
info, err := r.Info()
50+
c.Assert(err, Equals, common.ErrAuthorizationRequired)
51+
c.Assert(info, IsNil)
52+
}
53+
54+
func (s *RemoteSuite) TestInfoNotExists(c *C) {
55+
endpoint, _ := common.NewEndpoint("https://github.com/git-fixture/not-exists")
56+
r := NewGitUploadPackService(endpoint)
57+
c.Assert(r.Connect(), IsNil)
58+
59+
info, err := r.Info()
60+
c.Assert(err, Equals, common.ErrAuthorizationRequired)
61+
c.Assert(info, IsNil)
62+
}
63+
4464
func (s *RemoteSuite) TestDefaultBranch(c *C) {
4565
r := NewGitUploadPackService(s.Endpoint)
4666
c.Assert(r.Connect(), IsNil)
@@ -74,6 +94,19 @@ func (s *RemoteSuite) TestFetch(c *C) {
7494
c.Assert(b, HasLen, 85374)
7595
}
7696

97+
func (s *RemoteSuite) TestFetchNoChanges(c *C) {
98+
r := NewGitUploadPackService(s.Endpoint)
99+
c.Assert(r.Connect(), IsNil)
100+
101+
req := &common.GitUploadPackRequest{}
102+
req.Want(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
103+
req.Have(core.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
104+
105+
reader, err := r.Fetch(req)
106+
c.Assert(err, Equals, common.ErrEmptyGitUploadPack)
107+
c.Assert(reader, IsNil)
108+
}
109+
77110
func (s *RemoteSuite) TestFetchMulti(c *C) {
78111
r := NewGitUploadPackService(s.Endpoint)
79112
c.Assert(r.Connect(), IsNil)

clients/ssh/git_upload_pack.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (rc io.Read
152152
if err != nil {
153153
return nil, err
154154
}
155+
155156
defer func() {
156157
// the session can be closed by the other endpoint,
157158
// therefore we must ignore a close error.
@@ -168,20 +169,19 @@ func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (rc io.Read
168169
return nil, err
169170
}
170171

172+
if err := session.Start("git-upload-pack " + s.vcs.FullName + ".git"); err != nil {
173+
return nil, err
174+
}
175+
171176
go func() {
172177
fmt.Fprintln(si, r.String())
173178
err = si.Close()
174179
}()
175180

176-
err = session.Start("git-upload-pack " + s.vcs.FullName + ".git")
177-
if err != nil {
178-
return nil, err
179-
}
180181
// TODO: investigate this *ExitError type (command fails or
181182
// doesn't complete successfully), as it is happenning all
182183
// the time, but everything seems to work fine.
183-
err = session.Wait()
184-
if err != nil {
184+
if err := session.Wait(); err != nil {
185185
if _, ok := err.(*ssh.ExitError); !ok {
186186
return nil, err
187187
}
@@ -205,6 +205,7 @@ func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (rc io.Read
205205
if err != nil {
206206
return nil, err
207207
}
208+
208209
buf := bytes.NewBuffer(data)
209210
return ioutil.NopCloser(buf), nil
210211
}

0 commit comments

Comments
 (0)