mirror of
https://git.sr.ht/~yotam/shavit
synced 2024-11-29 20:18:00 +01:00
Initial commit
This commit is contained in:
commit
24a8642761
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
go-gemini-server
|
||||
server.crt
|
||||
server.key
|
||||
/source/*
|
29
config.go
Normal file
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
3
config.toml
Normal file
@ -0,0 +1,3 @@
|
||||
source = "source"
|
||||
tls_certificate = "server.crt"
|
||||
tls_key = "server.key"
|
9
go.mod
Normal file
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
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
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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user