]> source.dussan.org Git - gitea.git/commitdiff
Return go-get info on subdirs (#15642) (#15871)
authorzeripath <art27@cantab.net>
Sat, 15 May 2021 11:06:02 +0000 (12:06 +0100)
committerGitHub <noreply@github.com>
Sat, 15 May 2021 11:06:02 +0000 (12:06 +0100)
Backport #15642

This PR is an alternative to #15628 and makes the go get handler a
handler.

Fix #15625

Close #15628

Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
integrations/goget_test.go [new file with mode: 0644]
routers/routes/goget.go [new file with mode: 0644]
routers/routes/web.go

diff --git a/integrations/goget_test.go b/integrations/goget_test.go
new file mode 100644 (file)
index 0000000..1003d71
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package integrations
+
+import (
+       "fmt"
+       "net/http"
+       "testing"
+
+       "code.gitea.io/gitea/modules/setting"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestGoGet(t *testing.T) {
+       defer prepareTestEnv(t)()
+
+       req := NewRequest(t, "GET", "/blah/glah/plah?go-get=1")
+       resp := MakeRequest(t, req, http.StatusOK)
+
+       expected := fmt.Sprintf(`<!doctype html>
+<html>
+       <head>
+               <meta name="go-import" content="%[1]s:%[2]s/blah/glah git %[3]sblah/glah.git">
+               <meta name="go-source" content="%[1]s:%[2]s/blah/glah _ %[3]sblah/glah/src/branch/master{/dir} %[3]sblah/glah/src/branch/master{/dir}/{file}#L{line}">
+       </head>
+       <body>
+               go get --insecure %[1]s:%[2]s/blah/glah
+       </body>
+</html>
+`, setting.Domain, setting.HTTPPort, setting.AppURL)
+
+       assert.Equal(t, expected, resp.Body.String())
+}
diff --git a/routers/routes/goget.go b/routers/routes/goget.go
new file mode 100644 (file)
index 0000000..518f5e3
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package routes
+
+import (
+       "net/http"
+       "net/url"
+       "path"
+       "strings"
+
+       "code.gitea.io/gitea/models"
+       "code.gitea.io/gitea/modules/context"
+       "code.gitea.io/gitea/modules/setting"
+       "code.gitea.io/gitea/modules/util"
+       "github.com/unknwon/com"
+)
+
+func goGet(ctx *context.Context) {
+       if ctx.Req.Method != "GET" || ctx.Query("go-get") != "1" || len(ctx.Req.URL.Query()) > 1 {
+               return
+       }
+
+       parts := strings.SplitN(ctx.Req.URL.EscapedPath(), "/", 4)
+
+       if len(parts) < 3 {
+               return
+       }
+
+       ownerName := parts[1]
+       repoName := parts[2]
+
+       // Quick responses appropriate go-get meta with status 200
+       // regardless of if user have access to the repository,
+       // or the repository does not exist at all.
+       // This is particular a workaround for "go get" command which does not respect
+       // .netrc file.
+
+       trimmedRepoName := strings.TrimSuffix(repoName, ".git")
+
+       if ownerName == "" || trimmedRepoName == "" {
+               _, _ = ctx.Write([]byte(`<!doctype html>
+<html>
+       <body>
+               invalid import path
+       </body>
+</html>
+`))
+               ctx.Status(400)
+               return
+       }
+       branchName := setting.Repository.DefaultBranch
+
+       repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
+       if err == nil && len(repo.DefaultBranch) > 0 {
+               branchName = repo.DefaultBranch
+       }
+       prefix := setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName))
+
+       appURL, _ := url.Parse(setting.AppURL)
+
+       insecure := ""
+       if appURL.Scheme == string(setting.HTTP) {
+               insecure = "--insecure "
+       }
+       ctx.Header().Set("Content-Type", "text/html")
+       ctx.Status(http.StatusOK)
+       _, _ = ctx.Write([]byte(com.Expand(`<!doctype html>
+<html>
+       <head>
+               <meta name="go-import" content="{GoGetImport} git {CloneLink}">
+               <meta name="go-source" content="{GoGetImport} _ {GoDocDirectory} {GoDocFile}">
+       </head>
+       <body>
+               go get {Insecure}{GoGetImport}
+       </body>
+</html>
+`, map[string]string{
+               "GoGetImport":    context.ComposeGoGetImport(ownerName, trimmedRepoName),
+               "CloneLink":      models.ComposeHTTPSCloneURL(ownerName, repoName),
+               "GoDocDirectory": prefix + "{/dir}",
+               "GoDocFile":      prefix + "{/dir}/{file}#L{line}",
+               "Insecure":       insecure,
+       })))
+}
index 9521680498f5d01e07c8f45511e618ffdec468f5..9910249d7b3ab3de9f508ba66e9ee3c7df3f9132 100644 (file)
@@ -8,7 +8,6 @@ import (
        "encoding/gob"
        "fmt"
        "net/http"
-       "net/url"
        "os"
        "path"
        "strings"
@@ -24,7 +23,6 @@ import (
        "code.gitea.io/gitea/modules/setting"
        "code.gitea.io/gitea/modules/storage"
        "code.gitea.io/gitea/modules/templates"
-       "code.gitea.io/gitea/modules/util"
        "code.gitea.io/gitea/modules/validation"
        "code.gitea.io/gitea/modules/web"
        "code.gitea.io/gitea/routers"
@@ -51,7 +49,6 @@ import (
        "github.com/go-chi/cors"
        "github.com/prometheus/client_golang/prometheus"
        "github.com/tstranex/u2f"
-       "github.com/unknwon/com"
 )
 
 const (
@@ -190,6 +187,7 @@ func WebRoutes() *web.Route {
                ctx.Data["UnitPullsGlobalDisabled"] = models.UnitTypePullRequests.UnitGlobalDisabled()
                ctx.Data["UnitProjectsGlobalDisabled"] = models.UnitTypeProjects.UnitGlobalDisabled()
        })
+       r.Use(goGet)
 
        // for health check
        r.Head("/", func(w http.ResponseWriter, req *http.Request) {
@@ -229,67 +227,6 @@ func WebRoutes() *web.Route {
        return r
 }
 
-func goGet(ctx *context.Context) {
-       if ctx.Query("go-get") != "1" {
-               return
-       }
-
-       // Quick responses appropriate go-get meta with status 200
-       // regardless of if user have access to the repository,
-       // or the repository does not exist at all.
-       // This is particular a workaround for "go get" command which does not respect
-       // .netrc file.
-
-       ownerName := ctx.Params(":username")
-       repoName := ctx.Params(":reponame")
-       trimmedRepoName := strings.TrimSuffix(repoName, ".git")
-
-       if ownerName == "" || trimmedRepoName == "" {
-               _, _ = ctx.Write([]byte(`<!doctype html>
-<html>
-       <body>
-               invalid import path
-       </body>
-</html>
-`))
-               ctx.Status(400)
-               return
-       }
-       branchName := setting.Repository.DefaultBranch
-
-       repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName)
-       if err == nil && len(repo.DefaultBranch) > 0 {
-               branchName = repo.DefaultBranch
-       }
-       prefix := setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName))
-
-       appURL, _ := url.Parse(setting.AppURL)
-
-       insecure := ""
-       if appURL.Scheme == string(setting.HTTP) {
-               insecure = "--insecure "
-       }
-       ctx.Header().Set("Content-Type", "text/html")
-       ctx.Status(http.StatusOK)
-       _, _ = ctx.Write([]byte(com.Expand(`<!doctype html>
-<html>
-       <head>
-               <meta name="go-import" content="{GoGetImport} git {CloneLink}">
-               <meta name="go-source" content="{GoGetImport} _ {GoDocDirectory} {GoDocFile}">
-       </head>
-       <body>
-               go get {Insecure}{GoGetImport}
-       </body>
-</html>
-`, map[string]string{
-               "GoGetImport":    context.ComposeGoGetImport(ownerName, trimmedRepoName),
-               "CloneLink":      models.ComposeHTTPSCloneURL(ownerName, repoName),
-               "GoDocDirectory": prefix + "{/dir}",
-               "GoDocFile":      prefix + "{/dir}/{file}#L{line}",
-               "Insecure":       insecure,
-       })))
-}
-
 // RegisterRoutes register routes
 func RegisterRoutes(m *web.Route) {
        reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
@@ -1091,7 +1028,7 @@ func RegisterRoutes(m *web.Route) {
        m.Group("/{username}", func() {
                m.Group("/{reponame}", func() {
                        m.Get("", repo.SetEditorconfigIfExists, repo.Home)
-               }, goGet, ignSignIn, context.RepoAssignment, context.RepoRef(), context.UnitTypes())
+               }, ignSignIn, context.RepoAssignment, context.RepoRef(), context.UnitTypes())
 
                m.Group("/{reponame}", func() {
                        m.Group("/info/lfs", func() {