diff options
| author | Xe <me@christine.website> | 2022-09-02 17:36:16 +0000 |
|---|---|---|
| committer | Xe <me@christine.website> | 2022-09-02 17:36:16 +0000 |
| commit | e6329f22d52770cc09e5268183630045e2b038d9 (patch) | |
| tree | 98226898affd326c818e798a81d5fd3bb5be7f75 /cmd | |
| parent | 8214faa30c03d1d127338e4a5106ce9878a66c4c (diff) | |
| download | x-e6329f22d52770cc09e5268183630045e2b038d9.tar.xz x-e6329f22d52770cc09e5268183630045e2b038d9.zip | |
xedn
Signed-off-by: Xe <me@christine.website>
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/xedn/.dockerignore | 1 | ||||
| -rw-r--r-- | cmd/xedn/.gitignore | 1 | ||||
| -rw-r--r-- | cmd/xedn/Dockerfile | 3 | ||||
| -rw-r--r-- | cmd/xedn/build.go | 25 | ||||
| -rw-r--r-- | cmd/xedn/fly.toml | 43 | ||||
| -rw-r--r-- | cmd/xedn/main.go | 131 |
6 files changed, 204 insertions, 0 deletions
diff --git a/cmd/xedn/.dockerignore b/cmd/xedn/.dockerignore new file mode 100644 index 0000000..e796b66 --- /dev/null +++ b/cmd/xedn/.dockerignore @@ -0,0 +1 @@ +*.go diff --git a/cmd/xedn/.gitignore b/cmd/xedn/.gitignore new file mode 100644 index 0000000..17b2f35 --- /dev/null +++ b/cmd/xedn/.gitignore @@ -0,0 +1 @@ +slug.tar.gz diff --git a/cmd/xedn/Dockerfile b/cmd/xedn/Dockerfile new file mode 100644 index 0000000..98553ca --- /dev/null +++ b/cmd/xedn/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine:3.16 +ADD ./slug.tar.gz /app +CMD /app/bin/web diff --git a/cmd/xedn/build.go b/cmd/xedn/build.go new file mode 100644 index 0000000..d84e89e --- /dev/null +++ b/cmd/xedn/build.go @@ -0,0 +1,25 @@ +//+build ignore + +// Builds and deploys the application to minipaas. +package main + +import ( + "context" + "os" + + "within.website/x/internal" + "within.website/x/internal/yeet" +) + +func main() { + internal.HandleStartup() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + env := append(os.Environ(), []string{"CGO_ENABLED=0", "GOOS=linux"}...) + yeet.ShouldWork(ctx, env, yeet.WD, "go", "build", "-v", "-o=web") + yeet.ShouldWork(ctx, env, yeet.WD, "appsluggr", "-web=web") + os.Remove("web") + yeet.ShouldWork(ctx, env, yeet.WD, "flyctl", "deploy", "--now") +} diff --git a/cmd/xedn/fly.toml b/cmd/xedn/fly.toml new file mode 100644 index 0000000..b0c9374 --- /dev/null +++ b/cmd/xedn/fly.toml @@ -0,0 +1,43 @@ +# fly.toml file generated for xedn on 2022-09-02T17:14:40Z + +app = "xedn" + +kill_signal = "SIGINT" +kill_timeout = 5 +processes = [] + +[build] + dockerfile = "./Dockerfile" + +[env] + +[experimental] + allowed_public_ports = [] + auto_rollback = true + +[[services]] + http_checks = [] + internal_port = 8080 + processes = ["app"] + protocol = "tcp" + script_checks = [] + + [services.concurrency] + hard_limit = 25 + soft_limit = 20 + type = "connections" + + [[services.ports]] + force_https = true + handlers = ["http"] + port = 80 + + [[services.ports]] + handlers = ["tls", "http"] + port = 443 + + [[services.tcp_checks]] + grace_period = "1s" + interval = "15s" + restart_limit = 0 + timeout = "2s" diff --git a/cmd/xedn/main.go b/cmd/xedn/main.go new file mode 100644 index 0000000..b0327d4 --- /dev/null +++ b/cmd/xedn/main.go @@ -0,0 +1,131 @@ +// Command quiche is a little cute cache server for my B2 bucket. +package main + +import ( + "bytes" + "context" + "encoding/gob" + "flag" + "fmt" + "io" + "log" + "net/http" + "os" + "strings" + + "github.com/golang/groupcache" + "github.com/sebest/xff" + "tailscale.com/tsnet" + "within.website/ln" + "within.website/ln/ex" + "within.website/ln/opname" + "within.website/x/internal" + "within.website/x/web" +) + +var ( + b2Backend = flag.String("b2-backend", "https://f001.backblazeb2.com", "Backblaze B2 base URL") + addr = flag.String("addr", ":8080", "server address") + peers = flag.String("peers", "http://localhost:8080", "server pool list") +) + +const cacheSize = 128 * 1024 * 1024 // 128 mebibytes + +type CacheData struct { + Headers http.Header + Body []byte +} + +var Group = groupcache.NewGroup("b2-bucket", cacheSize, groupcache.GetterFunc( + func(ctx groupcache.Context, key string, dest groupcache.Sink) error { + ln.Log(context.Background(), ln.F{"key": key}) + + resp, err := http.Get(*b2Backend + key) + if err != nil { + return fmt.Errorf("can't fetch from b2: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return web.NewError(http.StatusOK, resp) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("can't read from b2: %v", err) + } + + result := &CacheData{ + Headers: resp.Header, + Body: body, + } + + var buf bytes.Buffer + err = gob.NewEncoder(&buf).Encode(result) + if err != nil { + return err + } + + dest.SetBytes(buf.Bytes()) + + return nil + }, +)) + +func main() { + internal.HandleStartup() + ctx := opname.With(context.Background(), "startup") + + go func () { + srv := &tsnet.Server{ + Hostname: "xedn-" + os.Getenv("FLY_REGION"), + Logf: log.New(io.Discard, "", 0).Printf, + AuthKey: os.Getenv("TS_AUTHKEY"), + } + + lis, err := srv.Listen("tcp", ":80") + if err != nil { + ln.FatalErr(ctx, err, ln.Action("tsnet listening")) + } + + defer srv.Close() + defer lis.Close() + ln.FatalErr(opname.With(ctx, "metrics-tsnet"), http.Serve(lis, ex.HTTPLog(http.DefaultServeMux))) + } () + + xffMW, err := xff.Default() + if err != nil { + ln.FatalErr(ctx, err) + } + + mux := http.NewServeMux() + mux.HandleFunc("/file/christine-static/", func(w http.ResponseWriter, r *http.Request) { + var b []byte + err := Group.Get(nil, r.URL.Path, groupcache.AllocatingByteSliceSink(&b)) + if err != nil { + http.Error(w, err.Error(), http.StatusNotFound) + return + } + + var result CacheData + err = gob.NewDecoder(bytes.NewBuffer(b)).Decode(&result) + if err != nil { + ln.Error(r.Context(), err) + http.Error(w, "internal cache error", http.StatusInternalServerError) + return + } + + for k, vs := range result.Headers { + for _, v := range vs { + w.Header().Add(k, v) + } + } + w.WriteHeader(http.StatusOK) + w.Write(result.Body) + }) + p := strings.Split(*peers, ",") + pool := groupcache.NewHTTPPool(p[0]) + pool.Set(p...) + ln.Log(context.Background(), ln.F{"addr": *addr}) + http.ListenAndServe(*addr, xffMW.Handler(ex.HTTPLog(mux))) +} |
