-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgoredirect.go
75 lines (67 loc) · 1.88 KB
/
goredirect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package goredirect
import (
"fmt"
"html/template"
"net/http"
"strings"
)
type Mapping struct {
DstVCS string
DstScheme string
DstHostname string
SrcHostname string // if empty, uses hostname in HTTP request
SrcToDstRepoPathMapper *StringMapper
}
func isGoGet(req *http.Request) bool {
if req.URL.Query().Get("go-get") == "1" {
return true
}
return false
}
func NewGoGetHandler(mappings []Mapping, defaultHandler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if isGoGet(req) {
for _, mapping := range mappings {
if mapping.tryServe(w, req) {
return
}
}
http.Error(w, "No mapping for go-get request", http.StatusNotFound)
} else {
if defaultHandler != nil {
defaultHandler.ServeHTTP(w, req)
} else {
http.Error(w, "Not a go-get request and no default handler provided", http.StatusNotFound)
}
}
})
}
// Returns true if mapping input regex prefix-matches request URL
// (which indicates this mapping applies to this request), otherwise
// false.
func (m *Mapping) tryServe(w http.ResponseWriter, req *http.Request) bool {
path := req.URL.Path
var srcHost string
if m.SrcHostname == "" {
srcHost = strings.Split(req.Host, ":")[0]
} else {
srcHost = m.SrcHostname
}
dstRepoPath, srcRepoPath, _, err := m.SrcToDstRepoPathMapper.MapStringPrefix(path)
if err != nil {
return false
}
t, err := template.New("redirectTemplate").Parse(redirectTemplate)
if err != nil {
panic("error parsing template: " + err.Error())
}
err = t.Execute(w, templateParams{
Root: fmt.Sprintf("%s%s", srcHost, srcRepoPath),
VCS: m.DstVCS,
RedirectRoot: fmt.Sprintf("%s://%s%s", m.DstScheme, m.DstHostname, dstRepoPath),
})
if err != nil {
http.Error(w, "template execution error", http.StatusInternalServerError)
}
return true
}