code.gitea.io/gitea@v1.21.7/routers/web/goget.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package web 5 6 import ( 7 "fmt" 8 "html" 9 "net/http" 10 "net/url" 11 "path" 12 "strings" 13 14 repo_model "code.gitea.io/gitea/models/repo" 15 "code.gitea.io/gitea/modules/context" 16 "code.gitea.io/gitea/modules/setting" 17 "code.gitea.io/gitea/modules/util" 18 ) 19 20 func goGet(ctx *context.Context) { 21 if ctx.Req.Method != "GET" || len(ctx.Req.URL.RawQuery) < 8 || ctx.FormString("go-get") != "1" { 22 return 23 } 24 25 parts := strings.SplitN(ctx.Req.URL.EscapedPath(), "/", 4) 26 27 if len(parts) < 3 { 28 return 29 } 30 31 ownerName := parts[1] 32 repoName := parts[2] 33 34 // Quick responses appropriate go-get meta with status 200 35 // regardless of if user have access to the repository, 36 // or the repository does not exist at all. 37 // This is particular a workaround for "go get" command which does not respect 38 // .netrc file. 39 40 trimmedRepoName := strings.TrimSuffix(repoName, ".git") 41 42 if ownerName == "" || trimmedRepoName == "" { 43 _, _ = ctx.Write([]byte(`<!doctype html> 44 <html> 45 <body> 46 invalid import path 47 </body> 48 </html> 49 `)) 50 ctx.Status(http.StatusBadRequest) 51 return 52 } 53 branchName := setting.Repository.DefaultBranch 54 55 repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, ownerName, repoName) 56 if err == nil && len(repo.DefaultBranch) > 0 { 57 branchName = repo.DefaultBranch 58 } 59 prefix := setting.AppURL + path.Join(url.PathEscape(ownerName), url.PathEscape(repoName), "src", "branch", util.PathEscapeSegments(branchName)) 60 61 appURL, _ := url.Parse(setting.AppURL) 62 63 insecure := "" 64 if appURL.Scheme == string(setting.HTTP) { 65 insecure = "--insecure " 66 } 67 68 goGetImport := context.ComposeGoGetImport(ownerName, trimmedRepoName) 69 70 var cloneURL string 71 if setting.Repository.GoGetCloneURLProtocol == "ssh" { 72 cloneURL = repo_model.ComposeSSHCloneURL(ownerName, repoName) 73 } else { 74 cloneURL = repo_model.ComposeHTTPSCloneURL(ownerName, repoName) 75 } 76 goImportContent := fmt.Sprintf("%s git %s", goGetImport, cloneURL /*CloneLink*/) 77 goSourceContent := fmt.Sprintf("%s _ %s %s", goGetImport, prefix+"{/dir}" /*GoDocDirectory*/, prefix+"{/dir}/{file}#L{line}" /*GoDocFile*/) 78 goGetCli := fmt.Sprintf("go get %s%s", insecure, goGetImport) 79 80 res := fmt.Sprintf(`<!doctype html> 81 <html> 82 <head> 83 <meta name="go-import" content="%s"> 84 <meta name="go-source" content="%s"> 85 </head> 86 <body> 87 %s 88 </body> 89 </html>`, html.EscapeString(goImportContent), html.EscapeString(goSourceContent), html.EscapeString(goGetCli)) 90 91 ctx.RespHeader().Set("Content-Type", "text/html") 92 _, _ = ctx.Write([]byte(res)) 93 }