143 lines
2.8 KiB
Go
143 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/starkandwayne/goutils/log"
|
|
)
|
|
|
|
func urlify(template string, version string) string {
|
|
re := regexp.MustCompile("{{version}}")
|
|
return re.ReplaceAllLiteralString(template, version)
|
|
}
|
|
|
|
func sha1sum(url string) (string, error) {
|
|
r, err := http.Get(url)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
h := sha1.New()
|
|
io.Copy(h, r.Body)
|
|
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
|
}
|
|
|
|
func match(req *http.Request, pattern string) bool {
|
|
matched, _ := regexp.MatchString(
|
|
fmt.Sprintf("^%s$", pattern),
|
|
fmt.Sprintf("%s %s", req.Method, req.URL.Path))
|
|
return matched
|
|
}
|
|
|
|
func extract(r *http.Request, pattern string) string {
|
|
re := regexp.MustCompile(fmt.Sprintf("^%s$", pattern))
|
|
return re.FindStringSubmatch(r.URL.Path)[1]
|
|
}
|
|
|
|
func bail(w http.ResponseWriter, e error) {
|
|
w.WriteHeader(500)
|
|
|
|
fmt.Printf("responding with an error: [%s]\n", e)
|
|
x := struct {
|
|
E string `json:"e"`
|
|
}{E: e.Error()}
|
|
b, err := json.Marshal(x)
|
|
if err == nil {
|
|
fmt.Fprintf(w, "%s\n", string(b))
|
|
} else {
|
|
fmt.Fprintf(w, `{"e":"failed to prepare JSON response"}%s`, "\n")
|
|
}
|
|
}
|
|
|
|
func respond(w http.ResponseWriter, e error, status int, payload interface{}) {
|
|
w.Header().Set("Content-type", "application/json")
|
|
|
|
if e != nil {
|
|
bail(w, e)
|
|
return
|
|
}
|
|
|
|
if payload != nil {
|
|
if s, ok := payload.(string); ok {
|
|
fmt.Printf("SEND %d %s\n", status, s)
|
|
payload = struct {
|
|
M string `json:"m"`
|
|
}{M: s}
|
|
}
|
|
|
|
b, err := json.Marshal(payload)
|
|
if err == nil {
|
|
w.WriteHeader(status)
|
|
fmt.Fprintf(w, "%s\n", string(b))
|
|
} else {
|
|
bail(w, err)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func authed(w http.ResponseWriter, r *http.Request) bool {
|
|
auth_user := os.Getenv("AUTH_USERNAME")
|
|
auth_pass := os.Getenv("AUTH_PASSWORD")
|
|
|
|
if auth_user == "" {
|
|
log.Debugf("no AUTH_USERNAME set in environment; skipping auth checks")
|
|
return true
|
|
}
|
|
|
|
try_user, try_pass, provided := r.BasicAuth()
|
|
if !provided {
|
|
log.Debugf("no Authorization header provided. returning a 401")
|
|
w.WriteHeader(401)
|
|
return false
|
|
}
|
|
|
|
if try_user == auth_user && try_pass == auth_pass {
|
|
return true
|
|
}
|
|
|
|
log.Debugf("authorization failed for user '%s'", try_user)
|
|
w.WriteHeader(403)
|
|
return false
|
|
}
|
|
|
|
func vnum(v string) (uint64, error) {
|
|
var rc, n uint64
|
|
var err error
|
|
|
|
re := regexp.MustCompile(`^(.+)[-.]rc\.(\d+)$`)
|
|
if m := re.FindStringSubmatch(v); len(m) == 3 {
|
|
v = m[1]
|
|
rc, err = strconv.ParseUint(m[2], 10, 64)
|
|
if err != nil {
|
|
log.Debugf("vnum had an issue with '%s': %s", v, err)
|
|
return n, err
|
|
}
|
|
}
|
|
|
|
sem := strings.Split(v, ".")
|
|
for len(sem) < 3 {
|
|
sem = append(sem, "0")
|
|
}
|
|
|
|
for i := 0; i < 3; i++ {
|
|
u, err := strconv.ParseUint(sem[i], 10, 64)
|
|
if err != nil {
|
|
log.Debugf("vnum had an issue with '%s': %s", v, err)
|
|
return n, err
|
|
}
|
|
n = n*10000 + u
|
|
}
|
|
n = n*10000 + rc
|
|
|
|
return n, nil
|
|
}
|