1
0
mirror of https://git.sr.ht/~yotam/shavit synced 2024-11-26 10:23:47 +01:00

Initial commit

This commit is contained in:
Yotam Nachum 2019-11-01 13:04:47 +02:00
commit 24a8642761
6 changed files with 116 additions and 0 deletions

4
.gitignore vendored Normal file

@ -0,0 +1,4 @@
go-gemini-server
server.crt
server.key
/source/*

29
config.go Normal file

@ -0,0 +1,29 @@
package main
import (
"fmt"
"io/ioutil"
"github.com/BurntSushi/toml"
)
type Config struct {
SourceDir string `toml:"source"`
TLSCert string `toml:"tls_certificate"`
TLSKey string `toml:"tls_key"`
}
func getConfig(path string) (Config, error) {
raw, err := ioutil.ReadFile(path)
if err != nil {
return Config{}, fmt.Errorf("failed to read config file: %v", err)
}
var cfg Config
err = toml.Unmarshal(raw, &cfg)
if err != nil {
return Config{}, fmt.Errorf("failed to parse config file: %v", err)
}
return cfg, nil
}

3
config.toml Normal file

@ -0,0 +1,3 @@
source = "source"
tls_certificate = "server.crt"
tls_key = "server.key"

9
go.mod Normal file

@ -0,0 +1,9 @@
module git.sr.ht/~yotam/go-gemini-server
go 1.12
require (
git.sr.ht/~yotam/go-gemini v0.0.0-20191101110121-e84e0b63cd37
github.com/BurntSushi/toml v0.3.1
github.com/pelletier/go-toml v1.6.0 // indirect
)

10
go.sum Normal file

@ -0,0 +1,10 @@
git.sr.ht/~yotam/go-gemini v0.0.0-20191101110121-e84e0b63cd37 h1:NWDz215k8nz6PGmbCb1YsUWrp9ocqnyKLnUoDCzzgU8=
git.sr.ht/~yotam/go-gemini v0.0.0-20191101110121-e84e0b63cd37/go.mod h1:KxQlipD0Ti7MfV3itYJfuvgcvd+SOlRTtbOK+A0DCCE=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

61
main.go Normal file

@ -0,0 +1,61 @@
package main
import (
"log"
"net/url"
"os"
"path/filepath"
"strings"
"git.sr.ht/~yotam/go-gemini"
)
type MainHandler struct {
source string
}
func (h MainHandler) Handle(r gemini.Request) gemini.Response {
u, err := url.Parse(r.URL)
if err != nil {
return gemini.Response{gemini.StatusBadRequest, err.Error(), nil}
}
itemPath, err := filepath.Abs(filepath.Join(h.source, u.Path))
if err != nil {
return gemini.Response{gemini.StatusTemporaryFailure, err.Error(), nil}
}
log.Println("Serving file from", itemPath)
if !strings.HasPrefix(itemPath, h.source) {
return gemini.Response{gemini.StatusBadRequest, "Permission denied", nil}
}
if _, err := os.Stat(itemPath); os.IsNotExist(err) {
return gemini.Response{gemini.StatusNotFound, "Not found", nil}
}
file, err := os.Open(itemPath)
if err != nil {
return gemini.Response{gemini.StatusTemporaryFailure, err.Error(), nil}
}
return gemini.Response{gemini.StatusSuccess, "text/gemini", file}
}
func main() {
cfg, err := getConfig("config.toml")
if err != nil {
log.Fatal(err)
}
absSourceDir, err := filepath.Abs(cfg.SourceDir)
if err != nil {
log.Fatal(err)
}
err = gemini.ListenAndServe("", cfg.TLSCert, cfg.TLSKey, MainHandler{absSourceDir})
if err != nil {
log.Fatal(err)
}
}