2021-02-09 14:35:02 +00:00
package main
2021-05-11 08:33:00 +00:00
// 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.
2021-02-09 14:35:02 +00:00
import (
"crypto/tls"
"crypto/x509/pkix"
2021-05-11 08:33:00 +00:00
"io"
2021-02-09 14:35:02 +00:00
"io/ioutil"
"log"
"path/filepath"
2021-05-11 08:33:00 +00:00
"strings"
2021-02-09 14:35:02 +00:00
"time"
"git.sr.ht/~adnano/go-gemini"
"git.sr.ht/~adnano/go-gemini/certificate"
2021-05-11 08:33:00 +00:00
"github.com/bouncepaw/mycorrhiza/cfg"
2021-02-17 18:41:35 +00:00
"github.com/bouncepaw/mycorrhiza/hyphae"
2021-02-09 14:35:02 +00:00
"github.com/bouncepaw/mycorrhiza/markup"
2021-05-11 08:33:00 +00:00
"github.com/bouncepaw/mycorrhiza/util"
2021-02-09 14:35:02 +00:00
)
func geminiHomeHypha ( w * gemini . ResponseWriter , rq * gemini . Request ) {
log . Println ( rq . URL )
2021-05-11 08:33:00 +00:00
_ , _ = io . WriteString ( w , ` # MycorrhizaWiki
2021-02-09 14:35:02 +00:00
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 :
2021-05-11 08:33:00 +00:00
= > / hypha / ` + cfg . HomeHypha )
2021-02-09 14:35:02 +00:00
}
func geminiHypha ( w * gemini . ResponseWriter , rq * gemini . Request ) {
log . Println ( rq . URL )
var (
2021-02-17 18:41:35 +00:00
hyphaName = geminiHyphaNameFromRq ( rq , "page" , "hypha" )
h = hyphae . ByName ( hyphaName )
hasAmnt = h . Exists && h . BinaryPath != ""
contents string
2021-02-09 14:35:02 +00:00
)
2021-02-17 18:41:35 +00:00
if h . Exists {
fileContentsT , errT := ioutil . ReadFile ( h . TextPath )
2021-02-09 14:35:02 +00:00
if errT == nil {
md := markup . Doc ( hyphaName , string ( fileContentsT ) )
contents = md . AsGemtext ( )
}
}
if hasAmnt {
2021-05-11 08:33:00 +00:00
_ , _ = io . WriteString ( w , "This hypha has an attachment\n" )
2021-02-09 14:35:02 +00:00
}
2021-05-11 08:33:00 +00:00
_ , _ = io . WriteString ( w , contents )
2021-02-09 14:35:02 +00:00
}
func handleGemini ( ) {
2021-05-09 09:36:39 +00:00
if cfg . GeminiCertificatePath == "" {
2021-02-09 14:35:02 +00:00
return
}
2021-05-09 09:36:39 +00:00
certPath , err := filepath . Abs ( cfg . GeminiCertificatePath )
2021-02-09 14:35:02 +00:00
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 )
}
}
2021-05-11 08:33:00 +00:00
// 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 ""
}