From 4cc9a5e73e5731d1033a0d1ec7e424bfa780b25d Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Wed, 14 Feb 2018 23:46:09 +0100 Subject: transport: http, fix services redirecting only info/refs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Máximo Cuadros --- plumbing/transport/http/common.go | 34 ++++++++++++++++++++++------- plumbing/transport/http/receive_pack.go | 2 +- plumbing/transport/http/upload_pack.go | 2 +- plumbing/transport/http/upload_pack_test.go | 28 ++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 10 deletions(-) (limited to 'plumbing/transport/http') diff --git a/plumbing/transport/http/common.go b/plumbing/transport/http/common.go index edf1c6c..24e63a4 100644 --- a/plumbing/transport/http/common.go +++ b/plumbing/transport/http/common.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "strconv" + "strings" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp" @@ -28,10 +29,12 @@ func applyHeadersToRequest(req *http.Request, content *bytes.Buffer, host string req.Header.Add("Content-Length", strconv.Itoa(content.Len())) } +const infoRefsPath = "/info/refs" + func advertisedReferences(s *session, serviceName string) (*packp.AdvRefs, error) { url := fmt.Sprintf( - "%s/info/refs?service=%s", - s.endpoint.String(), serviceName, + "%s%s?service=%s", + s.endpoint.String(), infoRefsPath, serviceName, ) req, err := http.NewRequest(http.MethodGet, url, nil) @@ -39,13 +42,14 @@ func advertisedReferences(s *session, serviceName string) (*packp.AdvRefs, error return nil, err } - s.applyAuthToRequest(req) + s.ApplyAuthToRequest(req) applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName) res, err := s.client.Do(req) if err != nil { return nil, err } + s.ModifyEndpointIfRedirect(res) defer ioutil.CheckClose(res.Body, &err) if err := NewErr(res); err != nil { @@ -129,11 +133,7 @@ func newSession(c *http.Client, ep *transport.Endpoint, auth transport.AuthMetho return s, nil } -func (*session) Close() error { - return nil -} - -func (s *session) applyAuthToRequest(req *http.Request) { +func (s *session) ApplyAuthToRequest(req *http.Request) { if s.auth == nil { return } @@ -141,6 +141,24 @@ func (s *session) applyAuthToRequest(req *http.Request) { s.auth.setAuth(req) } +func (s *session) ModifyEndpointIfRedirect(res *http.Response) { + if res.Request == nil { + return + } + + r := res.Request + if !strings.HasSuffix(r.URL.Path, infoRefsPath) { + return + } + + s.endpoint.Protocol = r.URL.Scheme + s.endpoint.Path = r.URL.Path[:len(r.URL.Path)-len(infoRefsPath)] +} + +func (*session) Close() error { + return nil +} + // AuthMethod is concrete implementation of common.AuthMethod for HTTP services type AuthMethod interface { transport.AuthMethod diff --git a/plumbing/transport/http/receive_pack.go b/plumbing/transport/http/receive_pack.go index e5cae28..72ba0ec 100644 --- a/plumbing/transport/http/receive_pack.go +++ b/plumbing/transport/http/receive_pack.go @@ -90,7 +90,7 @@ func (s *rpSession) doRequest( } applyHeadersToRequest(req, content, s.endpoint.Host, transport.ReceivePackServiceName) - s.applyAuthToRequest(req) + s.ApplyAuthToRequest(req) res, err := s.client.Do(req.WithContext(ctx)) if err != nil { diff --git a/plumbing/transport/http/upload_pack.go b/plumbing/transport/http/upload_pack.go index 85a57a5..fb5ac36 100644 --- a/plumbing/transport/http/upload_pack.go +++ b/plumbing/transport/http/upload_pack.go @@ -88,7 +88,7 @@ func (s *upSession) doRequest( } applyHeadersToRequest(req, content, s.endpoint.Host, transport.UploadPackServiceName) - s.applyAuthToRequest(req) + s.ApplyAuthToRequest(req) res, err := s.client.Do(req.WithContext(ctx)) if err != nil { diff --git a/plumbing/transport/http/upload_pack_test.go b/plumbing/transport/http/upload_pack_test.go index fbd28c7..3b85af5 100644 --- a/plumbing/transport/http/upload_pack_test.go +++ b/plumbing/transport/http/upload_pack_test.go @@ -75,3 +75,31 @@ func (s *UploadPackSuite) newEndpoint(c *C, name string) *transport.Endpoint { return ep } + +func (s *UploadPackSuite) TestAdvertisedReferencesRedirectPath(c *C) { + endpoint, _ := transport.NewEndpoint("https://gitlab.com/gitlab-org/gitter/webapp") + + session, err := s.Client.NewUploadPackSession(endpoint, s.EmptyAuth) + c.Assert(err, IsNil) + + info, err := session.AdvertisedReferences() + c.Assert(err, IsNil) + c.Assert(info, NotNil) + + url := session.(*upSession).endpoint.String() + c.Assert(url, Equals, "https://gitlab.com/gitlab-org/gitter/webapp.git") +} + +func (s *UploadPackSuite) TestAdvertisedReferencesRedirectSchema(c *C) { + endpoint, _ := transport.NewEndpoint("http://github.com/git-fixtures/basic") + + session, err := s.Client.NewUploadPackSession(endpoint, s.EmptyAuth) + c.Assert(err, IsNil) + + info, err := session.AdvertisedReferences() + c.Assert(err, IsNil) + c.Assert(info, NotNil) + + url := session.(*upSession).endpoint.String() + c.Assert(url, Equals, "https://github.com/git-fixtures/basic") +} -- cgit