mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-10-30 11:46:16 +00:00
105 lines
2.8 KiB
Go
105 lines
2.8 KiB
Go
package main
|
|
|
|
// Gemini-related stuff. This is currently a proof-of-concept implementation, no one really uses it.
|
|
// Maybe we should deprecate it until we find power to do it properly?
|
|
//
|
|
// When this stuff gets more serious, a separate module will be needed.
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509/pkix"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.sr.ht/~adnano/go-gemini"
|
|
"git.sr.ht/~adnano/go-gemini/certificate"
|
|
|
|
"github.com/bouncepaw/mycorrhiza/cfg"
|
|
"github.com/bouncepaw/mycorrhiza/hyphae"
|
|
"github.com/bouncepaw/mycorrhiza/markup"
|
|
"github.com/bouncepaw/mycorrhiza/util"
|
|
)
|
|
|
|
func geminiHomeHypha(w *gemini.ResponseWriter, rq *gemini.Request) {
|
|
log.Println(rq.URL)
|
|
_, _ = io.WriteString(w, `# MycorrhizaWiki
|
|
|
|
You have successfully served the wiki through Gemini. Currently, support is really work-in-progress; you should resort to using Mycorrhiza through the web protocols.
|
|
|
|
Visit home hypha:
|
|
=> /hypha/`+cfg.HomeHypha)
|
|
}
|
|
|
|
func geminiHypha(w *gemini.ResponseWriter, rq *gemini.Request) {
|
|
log.Println(rq.URL)
|
|
var (
|
|
hyphaName = geminiHyphaNameFromRq(rq, "page", "hypha")
|
|
h = hyphae.ByName(hyphaName)
|
|
hasAmnt = h.Exists && h.BinaryPath != ""
|
|
contents string
|
|
)
|
|
if h.Exists {
|
|
fileContentsT, errT := ioutil.ReadFile(h.TextPath)
|
|
if errT == nil {
|
|
md := markup.Doc(hyphaName, string(fileContentsT))
|
|
contents = md.AsGemtext()
|
|
}
|
|
}
|
|
if hasAmnt {
|
|
_, _ = io.WriteString(w, "This hypha has an attachment\n")
|
|
}
|
|
_, _ = io.WriteString(w, contents)
|
|
}
|
|
|
|
func handleGemini() {
|
|
if cfg.GeminiCertificatePath == "" {
|
|
return
|
|
}
|
|
certPath, err := filepath.Abs(cfg.GeminiCertificatePath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
var server gemini.Server
|
|
server.ReadTimeout = 30 * time.Second
|
|
server.WriteTimeout = 1 * time.Minute
|
|
if err := server.Certificates.Load(certPath); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
server.CreateCertificate = func(hostname string) (tls.Certificate, error) {
|
|
return certificate.Create(certificate.CreateOptions{
|
|
Subject: pkix.Name{
|
|
CommonName: hostname,
|
|
},
|
|
DNSNames: []string{hostname},
|
|
Duration: 365 * 24 * time.Hour,
|
|
})
|
|
}
|
|
|
|
var mux gemini.ServeMux
|
|
mux.HandleFunc("/", geminiHomeHypha)
|
|
mux.HandleFunc("/hypha/", geminiHypha)
|
|
mux.HandleFunc("/page/", geminiHypha)
|
|
|
|
server.Handle("localhost", &mux)
|
|
if err := server.ListenAndServe(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// geminiHyphaNameFromRq extracts hypha name from gemini request. You have to also pass the action which is embedded in the url or several actions. For url /hypha/hypha, the action would be "hypha".
|
|
func geminiHyphaNameFromRq(rq *gemini.Request, actions ...string) string {
|
|
p := rq.URL.Path
|
|
for _, action := range actions {
|
|
if strings.HasPrefix(p, "/"+action+"/") {
|
|
return util.CanonicalName(strings.TrimPrefix(p, "/"+action+"/"))
|
|
}
|
|
}
|
|
log.Fatal("HyphaNameFromRq: no matching action passed")
|
|
return ""
|
|
}
|