urls.go
1940 bytes
1package pages
2
3import "net/url"
4
5// RepositoryURL builds a repository overview URL without interpolating a name.
6func RepositoryURL(repository string) string {
7 return (&url.URL{Path: "/"}).JoinPath(splitRepositoryName(repository)...).String()
8}
9
10// PageURL builds a page operation URL without interpolating untrusted values.
11func PageURL(repository, operation string, query url.Values) string {
12 segments := append(splitRepositoryName(repository), "@", operation)
13 u := (&url.URL{Path: "/"}).JoinPath(segments...)
14 if query != nil {
15 u.RawQuery = query.Encode()
16 }
17 return u.String()
18}
19
20// TreeURL builds a tree-browser URL for a selected repository, ref, and path.
21func TreeURL(repository, ref, treePath string) string {
22 return PageURL(repository, "tree", url.Values{"ref": {ref}, "path": {treePath}})
23}
24
25// RawURL builds a raw-file URL for a selected repository, ref, and path.
26func RawURL(repository, ref, treePath string) string {
27 return PageURL(repository, "raw", url.Values{"ref": {ref}, "path": {treePath}})
28}
29
30func AbsoluteRawURL(publicURL, repository, ref, treePath string) string {
31 base, err := url.Parse(publicURL)
32 if err != nil || base.Scheme == "" || base.Host == "" {
33 return RawURL(repository, ref, treePath)
34 }
35 raw, err := url.Parse(RawURL(repository, ref, treePath))
36 if err != nil {
37 return RawURL(repository, ref, treePath)
38 }
39 return base.ResolveReference(raw).String()
40}
41
42func splitRepositoryName(name string) []string {
43 // A repository name may be nested. URL.JoinPath escapes each component and
44 // preserves only the deliberate repository separators.
45 return splitNonEmpty(name)
46}
47
48func splitNonEmpty(value string) []string {
49 segments := make([]string, 0, 1)
50 start := 0
51 for i := range value {
52 if value[i] == '/' {
53 if i > start {
54 segments = append(segments, value[start:i])
55 }
56 start = i + 1
57 }
58 }
59 if start < len(value) {
60 segments = append(segments, value[start:])
61 }
62 return segments
63}