initial commit
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>404 Not Found</title>
|
||||
<style>
|
||||
:root { color-scheme: light dark; }
|
||||
body {
|
||||
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
||||
line-height: 1.5;
|
||||
max-width: 42rem;
|
||||
margin: 4rem auto;
|
||||
padding: 0 1.5rem;
|
||||
color: #e4e4e7;
|
||||
background: #09090b;
|
||||
}
|
||||
h1 { font-size: 1.75rem; font-weight: 600; margin: 0 0 0.75rem; color: #fafafa; }
|
||||
p { margin: 0.5rem 0; color: #a1a1aa; }
|
||||
.host { color: #f87171; font-weight: 500; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>404 Not Found</h1>
|
||||
<p>{{MESSAGE}}</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
package www
|
||||
|
||||
import "embed"
|
||||
|
||||
// Default pages for unmatched hosts and shared error responses.
|
||||
// Override by placing the same filename under WWW_DIR (default: data/www/).
|
||||
//
|
||||
//go:embed index.html 404.html
|
||||
var defaults embed.FS
|
||||
@@ -0,0 +1,29 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Welcome to Helix Proxy</title>
|
||||
<style>
|
||||
:root { color-scheme: light dark; }
|
||||
body {
|
||||
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
|
||||
line-height: 1.5;
|
||||
max-width: 42rem;
|
||||
margin: 4rem auto;
|
||||
padding: 0 1.5rem;
|
||||
color: #e4e4e7;
|
||||
background: #09090b;
|
||||
}
|
||||
h1 { font-size: 1.75rem; font-weight: 600; margin: 0 0 0.75rem; color: #fafafa; }
|
||||
p { margin: 0.5rem 0; color: #a1a1aa; }
|
||||
code { background: #18181b; padding: 0.15rem 0.4rem; border-radius: 0.25rem; font-size: 0.9em; }
|
||||
.host { color: #34d399; font-weight: 500; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to Helix Proxy</h1>
|
||||
<p>No virtual host is configured for <span class="host">{{HOST}}</span>.</p>
|
||||
<p>Open the admin UI to add proxy hosts, certificates, and streams.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
package www
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"helix-proxy/internal/config"
|
||||
)
|
||||
|
||||
// LoadPage returns HTML for name (e.g. "index.html", "404.html").
|
||||
// A file in WWW_DIR with the same name overrides the embedded default.
|
||||
// Placeholders use the form {{KEY}} and are replaced from vars.
|
||||
func LoadPage(name string, vars map[string]string) []byte {
|
||||
wwwDir := config.Resolve("www")
|
||||
customPath := filepath.Join(wwwDir, name)
|
||||
|
||||
data, err := os.ReadFile(customPath)
|
||||
if err != nil {
|
||||
data, err = defaults.ReadFile(name)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(vars) == 0 {
|
||||
return data
|
||||
}
|
||||
s := string(data)
|
||||
for k, v := range vars {
|
||||
s = strings.ReplaceAll(s, "{{"+k+"}}", v)
|
||||
}
|
||||
return []byte(s)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package www
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"helix-proxy/internal/config"
|
||||
)
|
||||
|
||||
func TestLoadPageEmbeddedDefault(t *testing.T) {
|
||||
t.Setenv("DATA_DIR", t.TempDir())
|
||||
page := LoadPage("index.html", map[string]string{"HOST": "test.example"})
|
||||
if page == nil {
|
||||
t.Fatal("expected embedded index.html")
|
||||
}
|
||||
body := string(page)
|
||||
if !strings.Contains(body, "test.example") || !strings.Contains(body, "Welcome to Helix Proxy") {
|
||||
t.Fatalf("unexpected page: %s", page)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadPageWWWOverride(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
t.Setenv("DATA_DIR", dir)
|
||||
wwwDir := config.Resolve("www")
|
||||
if err := os.MkdirAll(wwwDir, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
custom := []byte("<h1>CUSTOM {{HOST}}</h1>")
|
||||
if err := os.WriteFile(filepath.Join(wwwDir, "index.html"), custom, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
page := LoadPage("index.html", map[string]string{"HOST": "override.example"})
|
||||
if string(page) != "<h1>CUSTOM override.example</h1>" {
|
||||
t.Fatalf("override failed: %q", page)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user