diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 8ebd774..cd1c1fc 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -26,7 +26,6 @@ archives: {{- else }}{{ .Arch }}{{ end }} formats: ["tar.gz"] files: - - web/**/* - README.md dockers: @@ -37,8 +36,6 @@ dockers: goos: linux goarch: amd64 dockerfile: Dockerfile.release - extra_files: - - web build_flag_templates: - "--platform=linux/amd64" - "--label=org.opencontainers.image.title={{ .ProjectName }}" @@ -51,8 +48,6 @@ dockers: goos: linux goarch: arm64 dockerfile: Dockerfile.release - extra_files: - - web build_flag_templates: - "--platform=linux/arm64" - "--label=org.opencontainers.image.title={{ .ProjectName }}" diff --git a/Dockerfile b/Dockerfile index 5e2546f..6acea40 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,6 @@ RUN useradd -m -u 10001 -s /bin/bash appuser WORKDIR /app COPY --from=builder /app/safebin . -COPY --from=builder /app/web ./web RUN mkdir -p /app/storage && chown 10001:10001 /app/storage VOLUME ["/app/storage"] diff --git a/Dockerfile.release b/Dockerfile.release index 51444ca..3f61504 100644 --- a/Dockerfile.release +++ b/Dockerfile.release @@ -9,7 +9,6 @@ RUN useradd -m -u 10001 -s /bin/bash appuser WORKDIR /app COPY safebin . -COPY web ./web RUN mkdir -p /app/storage && chown 10001:10001 /app/storage VOLUME ["/app/storage"] diff --git a/internal/app/config.go b/internal/app/config.go index b0a5be3..203bab8 100644 --- a/internal/app/config.go +++ b/internal/app/config.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "html/template" + "io/fs" "log/slog" "os" "strconv" @@ -36,7 +37,7 @@ const ( DBFileName = "safebin.db" DBBucketName = "files" - TempDirName = "tmp" + TempDirName = "tmp" ) type Config struct { @@ -50,6 +51,7 @@ type App struct { Tmpl *template.Template Logger *slog.Logger DB *bbolt.DB + Assets fs.FS } func LoadConfig() Config { @@ -93,6 +95,6 @@ func getEnvInt(key string, fallback int) int { return fallback } -func ParseTemplates() *template.Template { - return template.Must(template.ParseGlob("./web/templates/*.html")) +func ParseTemplates(fsys fs.FS) *template.Template { + return template.Must(template.ParseFS(fsys, "*.html")) } diff --git a/internal/app/retention_test.go b/internal/app/retention_test.go index a9e9906..069c1a3 100644 --- a/internal/app/retention_test.go +++ b/internal/app/retention_test.go @@ -29,8 +29,8 @@ func TestCalculateRetention(t *testing.T) { { name: "Half size file (Somewhere in between)", fileSize: 50 * MegaByte, - wantMin: 24 * time.Hour, - wantMax: MaxRetention, + wantMin: 24 * time.Hour, + wantMax: MaxRetention, }, { name: "Oversized file (Min retention)", diff --git a/internal/app/server.go b/internal/app/server.go index c10c8bf..8fd3e52 100644 --- a/internal/app/server.go +++ b/internal/app/server.go @@ -5,13 +5,29 @@ import ( "fmt" "net/http" "path/filepath" + "strings" ) func (app *App) Routes() *http.ServeMux { mux := http.NewServeMux() - fileServer := http.FileServer(http.Dir("./web/static")) - mux.Handle("GET /static/", http.StripPrefix("/static/", fileServer)) + fileServer := http.FileServer(http.FS(app.Assets)) + + staticHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "" || strings.HasSuffix(r.URL.Path, "/") { + http.NotFound(w, r) + return + } + + if strings.HasSuffix(r.URL.Path, ".html") { + http.NotFound(w, r) + return + } + + fileServer.ServeHTTP(w, r) + }) + + mux.Handle("GET /static/", http.StripPrefix("/static/", staticHandler)) mux.HandleFunc("GET /{$}", app.HandleHome) mux.HandleFunc("POST /{$}", app.HandleUpload) mux.HandleFunc("POST /upload/chunk", app.HandleChunk) @@ -22,7 +38,7 @@ func (app *App) Routes() *http.ServeMux { } func (app *App) HandleHome(writer http.ResponseWriter, request *http.Request) { - err := app.Tmpl.ExecuteTemplate(writer, "base", map[string]any{ + err := app.Tmpl.ExecuteTemplate(writer, "layout", map[string]any{ "MaxMB": app.Conf.MaxMB, "Host": request.Host, }) diff --git a/internal/app/server_test.go b/internal/app/server_test.go index 4a34343..0565b0e 100644 --- a/internal/app/server_test.go +++ b/internal/app/server_test.go @@ -3,7 +3,6 @@ package app import ( "bytes" "fmt" - "html/template" "io" "log/slog" "mime/multipart" @@ -19,12 +18,14 @@ func setupTestApp(t *testing.T) (*App, string) { storageDir := t.TempDir() os.MkdirAll(filepath.Join(storageDir, TempDirName), 0700) - tmplDir := filepath.Join(storageDir, "templates") - os.MkdirAll(tmplDir, 0700) - os.WriteFile(filepath.Join(tmplDir, "base.html"), []byte(`{{define "base"}}{{template "content" .}}{{end}}`), 0600) - os.WriteFile(filepath.Join(tmplDir, "index.html"), []byte(`{{define "content"}}OK{{end}}`), 0600) + webDir := filepath.Join(storageDir, "web") + os.MkdirAll(webDir, 0700) - tmpl := template.Must(template.New("base").Parse(`{{define "base"}}OK{{end}}`)) + os.WriteFile(filepath.Join(webDir, "layout.html"), []byte(`{{define "layout"}}{{template "content" .}}{{end}}`), 0600) + os.WriteFile(filepath.Join(webDir, "home.html"), []byte(`{{define "content"}}OK{{end}}`), 0600) + + testFS := os.DirFS(webDir) + tmpl := ParseTemplates(testFS) db, err := InitDB(storageDir) if err != nil { @@ -39,6 +40,7 @@ func setupTestApp(t *testing.T) (*App, string) { }, Logger: discardLogger(), Tmpl: tmpl, + Assets: testFS, DB: db, } diff --git a/main.go b/main.go index 50965ed..5544e43 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( "syscall" "github.com/skidoodle/safebin/internal/app" + "github.com/skidoodle/safebin/web" ) func main() { @@ -46,7 +47,8 @@ func main() { application := &app.App{ Conf: cfg, Logger: logger, - Tmpl: app.ParseTemplates(), + Tmpl: app.ParseTemplates(web.Assets), + Assets: web.Assets, DB: db, } diff --git a/web/static/js/app.js b/web/app.js similarity index 100% rename from web/static/js/app.js rename to web/app.js diff --git a/web/embed.go b/web/embed.go new file mode 100644 index 0000000..3116ea5 --- /dev/null +++ b/web/embed.go @@ -0,0 +1,6 @@ +package web + +import "embed" + +//go:embed *.html *.css *.js *.ico +var Assets embed.FS diff --git a/web/favicon.ico b/web/favicon.ico new file mode 100644 index 0000000..d3edef5 Binary files /dev/null and b/web/favicon.ico differ diff --git a/web/templates/index.html b/web/home.html similarity index 100% rename from web/templates/index.html rename to web/home.html diff --git a/web/templates/base.html b/web/layout.html similarity index 87% rename from web/templates/base.html rename to web/layout.html index a981e7a..161dcc4 100644 --- a/web/templates/base.html +++ b/web/layout.html @@ -1,12 +1,12 @@ -{{define "base"}} +{{define "layout"}}
- +