diff --git a/app.go b/app.go new file mode 100644 index 0000000..5043e9d --- /dev/null +++ b/app.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "net/http" +) + +type Application struct { + Config *Config + Mux *http.ServeMux + Log *LogFile +} + +func (app *Application) routes() { + m := http.NewServeMux() + + m.HandleFunc("/healthcheck", healthcheck) + m.HandleFunc("/reloadRules", reloadRules(app.Config)) + m.HandleFunc("/", serveLogger(app.Log)(serveRules(app.Config))) + + app.Mux = m +} + +func (app *Application) Setup(port string) *http.Server { + app.routes() + return &http.Server{ + Addr: fmt.Sprintf(":%s", port), + Handler: app.Mux, + } +} diff --git a/embed.go b/embed.go new file mode 100644 index 0000000..8a32e90 --- /dev/null +++ b/embed.go @@ -0,0 +1,19 @@ +package main + +import ( + "embed" + "html/template" +) + +// go:embed templates/* +var tmpls embed.FS + +func GetServeHtml() *template.Template { + data, _ := tmpls.ReadFile("success.html") + return template.Must(template.New("main").Parse(string(data))) +} + +func GetDefaultHtml() []byte { + data, _ := tmpls.ReadFile("default.html") + return data +} diff --git a/handlers.go b/handlers.go new file mode 100644 index 0000000..139474c --- /dev/null +++ b/handlers.go @@ -0,0 +1,71 @@ +package main + +import ( + "bytes" + "net/http" + "strings" +) + +func healthcheck(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("ok")) +} + +func reloadRules(c *Config) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + err := c.LoadMappingFile("") + if err != nil { + errorLog.Printf("Cannot reload rules: %+v", err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Write([]byte("ok")) + } +} + +func serveRules(c *Config) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusInternalServerError) + return + } + + // if go-get param is absent, return nothing + if r.FormValue("go-get") != "1" { + w.Write(GetDefaultHtml()) + return + } + + nameOfPkg := r.Host + r.URL.Path + + var vanityUrl, proto, repoUrl string + for _, rule := range c.MappingRules.Mappings { + if strings.HasPrefix(strings.ToLower(nameOfPkg), strings.ToLower(rule.VanityUrl+"/")) { + repo := strings.Replace(strings.ToLower(nameOfPkg), strings.ToLower(rule.VanityUrl), "", -1) + repo = strings.Split(repo, "/")[1] + + vanityUrl = rule.VanityUrl + "/" + repo + repoUrl = rule.RealUrl + "/" + repo + proto = rule.Protocol + + break + } + } + + d := ImportRuleStruct{ + VanityUrl: vanityUrl, + Proto: proto, + RepoUrl: repoUrl, + } + tmpl := GetServeHtml() + + var buf bytes.Buffer + err := tmpl.Execute(&buf, &d) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Cache-Control", "public, max-age=500") + w.Write(buf.Bytes()) + } +} diff --git a/middleware.go b/middleware.go new file mode 100644 index 0000000..d4ed069 --- /dev/null +++ b/middleware.go @@ -0,0 +1,23 @@ +package main + +import ( + "net/http" +) + +// serveLogger is a logging middleware for serving. It generates logs for +// requests sent to the server. +func serveLogger(l *LogFile) func(http.HandlerFunc) http.HandlerFunc { + return func(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l.WriteLog(r) + next(w, r) + } + } +} + +// func serveLogger(logger *LogFile, next http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// logger.WriteLog(r) +// next.ServeHTTP(w, r) +// }) +// } diff --git a/templates/default.html b/templates/default.html new file mode 100644 index 0000000..76bdefa --- /dev/null +++ b/templates/default.html @@ -0,0 +1,6 @@ + +
+ +