commit inicial

This commit is contained in:
sejo 2022-01-20 14:44:06 -06:00
commit 51a832af15
5 changed files with 203 additions and 0 deletions

30
LICENSE.txt Normal file
View File

@ -0,0 +1,30 @@
CHAOTIC SOFTWARE : BEWARE
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Don't expect support, ongoing development, or maintenance. side effects
may include uncomfortable clarity, dry mouth, and/or spiritual revolt.
For your own sanity, PLEASE FORK NOW!
For more information, please refer to <gemini://xj-ix.luxe/wiki/chaotic-software/>

18
README.md Normal file
View File

@ -0,0 +1,18 @@
# chamorrx
pequeño servidor gemini en go
basado en el ejemplo de servidor de [go-gemini](https://git.sr.ht/~adnano/go-gemini) y algunos aspectos del servidor de [flounder](https://git.alexwennerberg.com/flounder/)
# config
el servidor espera una configuración con el siguiente formato, para indicar los hosts que existirán y desde dónde se servirán:
```
example.com /var/gemini/ejemplo
otrohost.com /var/gemini/otroejemplo
```
# licencia
> THIS IS CHAOTIC SOFTWARE BEWARE <gemini://sunshinegardens.org/~xj9/wiki/chaotic-software/>

10
go.mod Normal file
View File

@ -0,0 +1,10 @@
module chamorrx
go 1.17
require git.sr.ht/~adnano/go-gemini v0.2.2
require (
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
golang.org/x/text v0.3.3 // indirect
)

9
go.sum Normal file
View File

@ -0,0 +1,9 @@
git.sr.ht/~adnano/go-gemini v0.2.2 h1:p2owKzrQ1wTgvPS5CZCPYArQyNUL8ZgYOHHrTjH9sdI=
git.sr.ht/~adnano/go-gemini v0.2.2/go.mod h1:hQ75Y0i5jSFL+FQ7AzWVAYr5LQsaFC7v3ZviNyj46dY=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

136
servidor.go Normal file
View File

@ -0,0 +1,136 @@
// servidor gemini basado en el ejemplo de go-gemini y algo del código de flounder
// https://git.sr.ht/~adnano/go-gemini
// https://git.alexwennerberg.com/flounder/
package main
import (
"context"
"log"
"os"
"os/signal"
"time"
"io"
"bufio"
"path"
"path/filepath"
"strings"
"git.sr.ht/~adnano/go-gemini"
"git.sr.ht/~adnano/go-gemini/certificate"
)
// de flounder: https://git.alexwennerberg.com/flounder/file/utils.go.html
func cleanPath(thepath string) string {
res := filepath.FromSlash(path.Clean("/" + strings.Trim(thepath, "/")))
if strings.Contains(res, "..") { // sanity check
return ""
}
return res
}
// mapa de hosts : directorios
var mapa map[string]string
// inspirada por gmiPage de flounder: https://git.alexwennerberg.com/flounder/file/gemini.go.html
func gmiHandler(_ context.Context, w gemini.ResponseWriter, r *gemini.Request) {
fileName := cleanPath(r.URL.Path)
// obtiene el hostname sin el puerto
host := strings.SplitN(r.URL.Host, ":", 2)[0]
// utiliza el directorio indicado por el mapa
dir := mapa[host]
fullPath := path.Join(dir, fileName)
if strings.Contains(fileName, "atom.xml") {
_, err := os.Stat(fullPath)
if err == nil {
// inspirado de ServeFile en fs.go:
f, _ := os.Open(fullPath)
defer f.Close()
w.SetMediaType("application/atom+xml")
io.Copy(w, f)
return
}
}
gemini.ServeFile(w, os.DirFS(dir), fileName)
}
func main() {
config, err := os.Open("config.txt")
log.Println("cargando configuración...")
if err != nil {
log.Fatal(err)
}
defer config.Close()
scanner := bufio.NewScanner(config)
mapa = make(map[string]string)
for scanner.Scan(){
campos := strings.SplitN( scanner.Text(), " ", 2 )
mapa[ campos[0] ] = campos[1]
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
log.Println("configuración cargada!")
log.Println("registrando certificados...")
certificates := &certificate.Store{}
for host,_ := range mapa {
certificates.Register(host)
}
if err := certificates.Load("certs"); err != nil {
log.Fatal(err)
}
log.Println("certificados listos!")
log.Println("iniciando servidor...")
mux := &gemini.Mux{}
mux.HandleFunc("/", gmiHandler)
server := &gemini.Server{
Addr: ":1965",
Handler: gemini.LoggingMiddleware(mux),
ReadTimeout: 30 * time.Second,
WriteTimeout: 1 * time.Minute,
GetCertificate: certificates.Get,
}
// Listen for interrupt signal
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
errch := make(chan error)
go func() {
ctx := context.Background()
errch <- server.ListenAndServe(ctx)
}()
select {
case err := <-errch:
log.Fatal(err)
case <-c:
// Shutdown the server
log.Println("Shutting down...")
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err := server.Shutdown(ctx)
if err != nil {
log.Fatal(err)
}
}
}