gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package url
  4. import (
  5. "context"
  6. "net/http"
  7. "net/url"
  8. "testing"
  9. "code.gitea.io/gitea/modules/httplib"
  10. "code.gitea.io/gitea/modules/setting"
  11. "code.gitea.io/gitea/modules/test"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. func TestParseGitURLs(t *testing.T) {
  15. kases := []struct {
  16. kase string
  17. expected *GitURL
  18. }{
  19. {
  20. kase: "git@127.0.0.1:go-gitea/gitea.git",
  21. expected: &GitURL{
  22. URL: &url.URL{
  23. Scheme: "ssh",
  24. User: url.User("git"),
  25. Host: "127.0.0.1",
  26. Path: "go-gitea/gitea.git",
  27. },
  28. extraMark: 1,
  29. },
  30. },
  31. {
  32. kase: "git@[fe80:14fc:cec5:c174:d88%2510]:go-gitea/gitea.git",
  33. expected: &GitURL{
  34. URL: &url.URL{
  35. Scheme: "ssh",
  36. User: url.User("git"),
  37. Host: "[fe80:14fc:cec5:c174:d88%10]",
  38. Path: "go-gitea/gitea.git",
  39. },
  40. extraMark: 1,
  41. },
  42. },
  43. {
  44. kase: "git@[::1]:go-gitea/gitea.git",
  45. expected: &GitURL{
  46. URL: &url.URL{
  47. Scheme: "ssh",
  48. User: url.User("git"),
  49. Host: "[::1]",
  50. Path: "go-gitea/gitea.git",
  51. },
  52. extraMark: 1,
  53. },
  54. },
  55. {
  56. kase: "git@github.com:go-gitea/gitea.git",
  57. expected: &GitURL{
  58. URL: &url.URL{
  59. Scheme: "ssh",
  60. User: url.User("git"),
  61. Host: "github.com",
  62. Path: "go-gitea/gitea.git",
  63. },
  64. extraMark: 1,
  65. },
  66. },
  67. {
  68. kase: "ssh://git@github.com/go-gitea/gitea.git",
  69. expected: &GitURL{
  70. URL: &url.URL{
  71. Scheme: "ssh",
  72. User: url.User("git"),
  73. Host: "github.com",
  74. Path: "/go-gitea/gitea.git",
  75. },
  76. extraMark: 0,
  77. },
  78. },
  79. {
  80. kase: "ssh://git@[::1]/go-gitea/gitea.git",
  81. expected: &GitURL{
  82. URL: &url.URL{
  83. Scheme: "ssh",
  84. User: url.User("git"),
  85. Host: "[::1]",
  86. Path: "/go-gitea/gitea.git",
  87. },
  88. extraMark: 0,
  89. },
  90. },
  91. {
  92. kase: "/repositories/go-gitea/gitea.git",
  93. expected: &GitURL{
  94. URL: &url.URL{
  95. Scheme: "file",
  96. Path: "/repositories/go-gitea/gitea.git",
  97. },
  98. extraMark: 2,
  99. },
  100. },
  101. {
  102. kase: "file:///repositories/go-gitea/gitea.git",
  103. expected: &GitURL{
  104. URL: &url.URL{
  105. Scheme: "file",
  106. Path: "/repositories/go-gitea/gitea.git",
  107. },
  108. extraMark: 0,
  109. },
  110. },
  111. {
  112. kase: "https://github.com/go-gitea/gitea.git",
  113. expected: &GitURL{
  114. URL: &url.URL{
  115. Scheme: "https",
  116. Host: "github.com",
  117. Path: "/go-gitea/gitea.git",
  118. },
  119. extraMark: 0,
  120. },
  121. },
  122. {
  123. kase: "https://git:git@github.com/go-gitea/gitea.git",
  124. expected: &GitURL{
  125. URL: &url.URL{
  126. Scheme: "https",
  127. Host: "github.com",
  128. User: url.UserPassword("git", "git"),
  129. Path: "/go-gitea/gitea.git",
  130. },
  131. extraMark: 0,
  132. },
  133. },
  134. {
  135. kase: "https://[fe80:14fc:cec5:c174:d88%2510]:20/go-gitea/gitea.git",
  136. expected: &GitURL{
  137. URL: &url.URL{
  138. Scheme: "https",
  139. Host: "[fe80:14fc:cec5:c174:d88%10]:20",
  140. Path: "/go-gitea/gitea.git",
  141. },
  142. extraMark: 0,
  143. },
  144. },
  145. {
  146. kase: "git://github.com/go-gitea/gitea.git",
  147. expected: &GitURL{
  148. URL: &url.URL{
  149. Scheme: "git",
  150. Host: "github.com",
  151. Path: "/go-gitea/gitea.git",
  152. },
  153. extraMark: 0,
  154. },
  155. },
  156. }
  157. for _, kase := range kases {
  158. t.Run(kase.kase, func(t *testing.T) {
  159. u, err := ParseGitURL(kase.kase)
  160. assert.NoError(t, err)
  161. assert.Equal(t, kase.expected.extraMark, u.extraMark)
  162. assert.Equal(t, *kase.expected, *u)
  163. })
  164. }
  165. }
  166. func TestParseRepositoryURL(t *testing.T) {
  167. defer test.MockVariableValue(&setting.AppURL, "https://localhost:3000")()
  168. defer test.MockVariableValue(&setting.SSH.Domain, "try.gitea.io")()
  169. ctxURL, _ := url.Parse("https://gitea")
  170. ctxReq := &http.Request{URL: ctxURL, Header: http.Header{}}
  171. ctxReq.Host = ctxURL.Host
  172. ctxReq.Header.Add("X-Forwarded-Proto", ctxURL.Scheme)
  173. ctx := context.WithValue(t.Context(), httplib.RequestContextKey, ctxReq)
  174. cases := []struct {
  175. input string
  176. ownerName, repoName, remaining string
  177. }{
  178. {input: "/user/repo"},
  179. {input: "https://localhost:3000/user/repo", ownerName: "user", repoName: "repo"},
  180. {input: "https://external:3000/user/repo"},
  181. {input: "https://localhost:3000/user/repo.git/other", ownerName: "user", repoName: "repo", remaining: "/other"},
  182. {input: "https://gitea/user/repo", ownerName: "user", repoName: "repo"},
  183. {input: "https://gitea:3333/user/repo"},
  184. {input: "ssh://try.gitea.io:2222/user/repo", ownerName: "user", repoName: "repo"},
  185. {input: "ssh://external:2222/user/repo"},
  186. {input: "git+ssh://user@try.gitea.io/user/repo.git", ownerName: "user", repoName: "repo"},
  187. {input: "git+ssh://user@external/user/repo.git"},
  188. {input: "root@try.gitea.io:user/repo.git", ownerName: "user", repoName: "repo"},
  189. {input: "root@gitea:user/repo.git", ownerName: "user", repoName: "repo"},
  190. {input: "root@external:user/repo.git"},
  191. }
  192. for _, c := range cases {
  193. t.Run(c.input, func(t *testing.T) {
  194. ret, _ := ParseRepositoryURL(ctx, c.input)
  195. assert.Equal(t, c.ownerName, ret.OwnerName)
  196. assert.Equal(t, c.repoName, ret.RepoName)
  197. assert.Equal(t, c.remaining, ret.RemainingPath)
  198. })
  199. }
  200. t.Run("WithSubpath", func(t *testing.T) {
  201. defer test.MockVariableValue(&setting.AppURL, "https://localhost:3000/subpath")()
  202. defer test.MockVariableValue(&setting.AppSubURL, "/subpath")()
  203. cases = []struct {
  204. input string
  205. ownerName, repoName, remaining string
  206. }{
  207. {input: "https://localhost:3000/user/repo"},
  208. {input: "https://localhost:3000/subpath/user/repo.git/other", ownerName: "user", repoName: "repo", remaining: "/other"},
  209. {input: "ssh://try.gitea.io:2222/user/repo", ownerName: "user", repoName: "repo"},
  210. {input: "ssh://external:2222/user/repo"},
  211. {input: "git+ssh://user@try.gitea.io/user/repo.git", ownerName: "user", repoName: "repo"},
  212. {input: "git+ssh://user@external/user/repo.git"},
  213. {input: "root@try.gitea.io:user/repo.git", ownerName: "user", repoName: "repo"},
  214. {input: "root@external:user/repo.git"},
  215. }
  216. for _, c := range cases {
  217. t.Run(c.input, func(t *testing.T) {
  218. ret, _ := ParseRepositoryURL(ctx, c.input)
  219. assert.Equal(t, c.ownerName, ret.OwnerName)
  220. assert.Equal(t, c.repoName, ret.RepoName)
  221. assert.Equal(t, c.remaining, ret.RemainingPath)
  222. })
  223. }
  224. })
  225. }
  226. func TestMakeRepositoryBaseLink(t *testing.T) {
  227. defer test.MockVariableValue(&setting.AppURL, "https://localhost:3000/subpath")()
  228. defer test.MockVariableValue(&setting.AppSubURL, "/subpath")()
  229. u, err := ParseRepositoryURL(t.Context(), "https://localhost:3000/subpath/user/repo.git")
  230. assert.NoError(t, err)
  231. assert.Equal(t, "/subpath/user/repo", MakeRepositoryWebLink(u))
  232. u, err = ParseRepositoryURL(t.Context(), "https://github.com/owner/repo.git")
  233. assert.NoError(t, err)
  234. assert.Equal(t, "https://github.com/owner/repo", MakeRepositoryWebLink(u))
  235. u, err = ParseRepositoryURL(t.Context(), "git@github.com:owner/repo.git")
  236. assert.NoError(t, err)
  237. assert.Equal(t, "https://github.com/owner/repo", MakeRepositoryWebLink(u))
  238. u, err = ParseRepositoryURL(t.Context(), "git+ssh://other:123/owner/repo.git")
  239. assert.NoError(t, err)
  240. assert.Equal(t, "https://other/owner/repo", MakeRepositoryWebLink(u))
  241. }