all repos — flounder @ a8a98dc62ceebfb9d27bc574e419066bb6f5cf16

A small site builder for the Gemini protocol

gemini.go (view raw)

  1package main
  2
  3import (
  4	"crypto/tls"
  5	"mime"
  6	"strings"
  7	// "fmt"
  8	gmi "git.sr.ht/~adnano/go-gemini"
  9	"io/ioutil"
 10	"log"
 11	"path"
 12	"path/filepath"
 13	"text/template"
 14	"time"
 15)
 16
 17func gmiIndex(w *gmi.ResponseWriter, r *gmi.Request) {
 18	log.Println("Index request")
 19	t, err := template.ParseFiles("templates/index.gmi")
 20	if err != nil {
 21		log.Fatal(err)
 22	}
 23	files, err := getIndexFiles()
 24	users, err := getActiveUserNames()
 25	if err != nil {
 26		log.Println(err)
 27		w.WriteHeader(40, "Internal server error")
 28	}
 29	data := struct {
 30		Host      string
 31		SiteTitle string
 32		Files     []*File
 33		Users     []string
 34	}{
 35		Host:      c.Host,
 36		SiteTitle: c.SiteTitle,
 37		Files:     files,
 38		Users:     users,
 39	}
 40	t.Execute(w, data)
 41}
 42
 43func gmiPage(w *gmi.ResponseWriter, r *gmi.Request) {
 44	userName := strings.Split(r.URL.Host, ".")[0]
 45	fileName := filepath.Clean(r.URL.Path)
 46	if fileName == "/" {
 47		fileName = "index.gmi"
 48	}
 49	filePath := path.Join(c.FilesDirectory, userName, fileName)
 50	log.Println("Request for gemini file at", filePath)
 51	data, err := ioutil.ReadFile(filePath)
 52
 53	if err != nil {
 54		w.WriteHeader(51, "Not Found")
 55		return
 56	}
 57	ext := filepath.Ext(filePath)
 58	mimetype := mime.TypeByExtension(ext)
 59	w.SetMimetype(mimetype)
 60	_, err = w.Write(data)
 61	if err != nil {
 62		log.Println(err)
 63		w.WriteHeader(40, "Internal server error")
 64		return
 65	}
 66}
 67
 68func runGeminiServer() {
 69	log.Println("Starting gemini server")
 70	var server gmi.Server
 71
 72	hostname := strings.SplitN(c.Host, ":", 2)[0]
 73	// is this necc?
 74	server.CreateCertificate = func(hostname string) (tls.Certificate, error) {
 75		log.Println("Generating certificate for", hostname)
 76		cert, err := gmi.CreateCertificate(gmi.CertificateOptions{
 77			DNSNames: []string{hostname},
 78			Duration: time.Minute, // for testing purposes
 79		})
 80		if err == nil {
 81			// Write the new certificate to disk
 82			err = writeCertificate(path.Join(c.GeminiCertStore, hostname), cert)
 83		}
 84		return cert, err
 85	}
 86
 87	var mux gmi.ServeMux
 88	// replace with wildcard cert
 89	mux.HandleFunc("/", gmiIndex)
 90
 91	var wildcardMux gmi.ServeMux
 92	wildcardMux.HandleFunc("/", gmiPage)
 93	server.Register(hostname, &mux)
 94	server.Register("*."+hostname, &wildcardMux)
 95
 96	err := server.ListenAndServe()
 97	if err != nil {
 98		log.Fatal(err)
 99	}
100}