You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
1.7 KiB

package main
import (
"crypto/tls"
"crypto/x509/pkix"
"log"
"time"
"io"
"strings"
ipfs "github.com/ipfs/go-ipfs-api"
html "github.com/LukeEmmet/html2gemini"
"git.sr.ht/~adnano/go-gemini"
"git.sr.ht/~adnano/go-gemini/certificate"
)
var shell = ipfs.NewShell("localhost:5001")
func tryIPFS(path ...string) (io.ReadCloser, string, error) {
var doc io.ReadCloser
var err error
for _, loc := range path {
doc, err = shell.Cat(loc)
if err == nil {
return doc, loc, nil
}
}
return doc, "", err
}
func handleIPFS(w *gemini.ResponseWriter, r *gemini.Request) {
path := r.URL.Path
doc, red, err := tryIPFS(path, path+"/index.gmi", path+"/index.html")
if err != nil {
w.Header(gemini.StatusNotFound, "Error requesting over IPFS: " + err.Error())
return
}
defer doc.Close()
if path != red {
w.Header(gemini.StatusRedirect, red)
return
}
if strings.HasSuffix(path, ".html") {
gmi, err := html.FromReader(doc, html.TextifyTraverseContext{})
if err == nil {
io.WriteString(w, gmi)
return
}
}
io.Copy(w, doc)
}
func main() {
var server gemini.Server
server.ReadTimeout = 30 * time.Second
server.WriteTimeout = 1 * time.Minute
if err := server.Certificates.Load("./certs"); 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.Handle("/", gemini.FileServer(gemini.Dir("./pages")))
mux.HandleFunc("/ipfs/", handleIPFS)
mux.HandleFunc("/ipns/", handleIPFS)
server.Handle(":1965", &mux)
if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}