http.go

 1package server
 2
 3import (
 4	"html/template"
 5	"log"
 6	"net"
 7	"net/http"
 8	"strconv"
 9	"strings"
10	"time"
11
12	"github.com/charmbracelet/soft-serve/server/config"
13)
14
15func newHTTPServer(cfg *config.Config) *http.Server {
16	r := http.NewServeMux()
17	r.HandleFunc("/", repoIndexHandler(cfg))
18	return &http.Server{
19		Addr:              net.JoinHostPort(cfg.Host, strconv.Itoa(cfg.HTTP.Port)),
20		Handler:           r,
21		ReadHeaderTimeout: time.Second * 10,
22		ReadTimeout:       time.Second * 10,
23		WriteTimeout:      time.Second * 10,
24		MaxHeaderBytes:    http.DefaultMaxHeaderBytes,
25	}
26}
27
28var repoIndexHTMLTpl = template.Must(template.New("index").Parse(`<!DOCTYPE html>
29<html lang="en">
30<head>
31 	<meta name="go-import" content="{{ .Config.HTTP.Domain }}/{{ .Repo }} git ssh://{{ .Config.Host }}:{{ .Config.SSH.Port }}/{{ .Repo }}">
32</head>
33</html>`))
34
35func repoIndexHandler(cfg *config.Config) func(w http.ResponseWriter, r *http.Request) {
36	return func(w http.ResponseWriter, r *http.Request) {
37		repo := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/")[0]
38		log.Println("serving index for", repo)
39		if err := repoIndexHTMLTpl.Execute(w, struct {
40			Repo   string
41			Config config.Config
42		}{
43			Repo:   repo,
44			Config: *cfg,
45		}); err != nil {
46			http.Error(w, err.Error(), http.StatusInternalServerError)
47			return
48		}
49	}
50}