Merge pull request #749 from irias/master

plumbing: diff, fix crash when a small ending equal-chunk
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 @@
 	"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 @@
 	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 @@
 		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 @@
 	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 @@
 	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 @@
 	}
 
 	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 @@
 	}
 
 	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 @@
 
 	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")
+}