inital commit
This commit is contained in:
commit
44aeff5e74
3 changed files with 107 additions and 0 deletions
5
go.mod
Normal file
5
go.mod
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
module custom_pb
|
||||||
|
|
||||||
|
go 1.25.0
|
||||||
|
|
||||||
|
require github.com/kulak/gemini v1.2.2
|
||||||
12
go.sum
Normal file
12
go.sum
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/kulak/gemini v1.2.2 h1:wPFOAFFdOf9ZaHcpMwTq1xYUWxmyV3h0uQl0OXCGa+A=
|
||||||
|
github.com/kulak/gemini v1.2.2/go.mod h1:8yiD7yhLkUGvOpdvgd/0nKQD2I0ChIAKD3yHuT13R5k=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
90
main.go
Normal file
90
main.go
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
gemini "github.com/kulak/gemini"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExampleHandler struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h ExampleHandler) ServeGemini(w gemini.ResponseWriter, req *gemini.Request) {
|
||||||
|
log.Printf("request: %s, user: %v", req.URL.Path, strings.Join(userName(req), " "))
|
||||||
|
switch req.URL.Path {
|
||||||
|
case "/":
|
||||||
|
err := w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
|
||||||
|
requireNoError(err)
|
||||||
|
_, err = w.WriteBody([]byte("Hello, world!"))
|
||||||
|
requireNoError(err)
|
||||||
|
case "/user":
|
||||||
|
if req.Certificate() == nil {
|
||||||
|
w.WriteStatusMsg(gemini.StatusCertRequired, "Authentication Required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
|
||||||
|
w.WriteBody([]byte(req.Certificate().Subject.CommonName))
|
||||||
|
case "/die":
|
||||||
|
requireNoError(errors.New("must die"))
|
||||||
|
case "/file":
|
||||||
|
gemini.ServeFileName("cmd/example/hello.gmi", "text/gemini")(w, req)
|
||||||
|
case "/post":
|
||||||
|
if req.URL.Scheme != gemini.SchemaTitan {
|
||||||
|
w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
|
||||||
|
w.WriteBody([]byte("Use titan scheme to upload data"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
payload, err := req.ReadTitanPayload()
|
||||||
|
requireNoError(err)
|
||||||
|
w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
|
||||||
|
w.WriteBody([]byte("Titan Upload Parameters\r\n"))
|
||||||
|
w.WriteBody([]byte(fmt.Sprintf("Upload MIME Type: %s\r\n", req.Titan.Mime)))
|
||||||
|
w.WriteBody([]byte(fmt.Sprintf("Token: %s\r\n", req.Titan.Token)))
|
||||||
|
w.WriteBody([]byte(fmt.Sprintf("Size: %v\r\n", req.Titan.Size)))
|
||||||
|
w.WriteBody([]byte("Payload:\r\n"))
|
||||||
|
w.WriteBody(payload)
|
||||||
|
|
||||||
|
default:
|
||||||
|
w.WriteStatusMsg(gemini.StatusNotFound, req.URL.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func requireNoError(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dateToStr(t time.Time) string {
|
||||||
|
return strconv.FormatInt(t.Unix(), 36)
|
||||||
|
}
|
||||||
|
|
||||||
|
func userName(r *gemini.Request) []string {
|
||||||
|
cert := r.Certificate()
|
||||||
|
if cert == nil {
|
||||||
|
return []string{""}
|
||||||
|
}
|
||||||
|
return []string{cert.Subject.CommonName, cert.SerialNumber.String(), dateToStr(cert.NotBefore), dateToStr(cert.NotAfter)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var host, cert, key string
|
||||||
|
flag.StringVar(&host, "host", ":1965", "listen on host and port. Example: hostname:1965")
|
||||||
|
flag.StringVar(&cert, "cert", "server.crt.pem", "certificate file")
|
||||||
|
flag.StringVar(&key, "key", "server.key.pem", "private key associated with certificate file")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
handler := ExampleHandler{}
|
||||||
|
|
||||||
|
err := gemini.ListenAndServe(host, cert, key, gemini.TrapPanic(handler.ServeGemini))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue