cmd/wol-proxy: show a loading page for / (#381)
When requesting / wol-proxy will show a loading page that polls /status every second. When the upstream server is ready the loading page will refresh causing the actual root page to be displayed
This commit is contained in:
@@ -11,7 +11,7 @@ llama-swap is a light weight, transparent proxy server that provides automatic m
|
|||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
- `make test-dev` - Use this when making iterative changes. Runs `go test` and `staticcheck`. Fix any static checking errors.
|
- `make test-dev` - Use this when making iterative changes. Runs `go test` and `staticcheck`. Fix any static checking errors. Use this only when changes are made to any code under the `proxy/` directory
|
||||||
- `make test-all` - runs at the end before completing work. Includes long running concurrency tests.
|
- `make test-all` - runs at the end before completing work. Includes long running concurrency tests.
|
||||||
|
|
||||||
## Workflow Tasks
|
## Workflow Tasks
|
||||||
|
|||||||
64
cmd/wol-proxy/index.html
Normal file
64
cmd/wol-proxy/index.html
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Loading...</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.stats {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #333;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.stats-label {
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="loader">
|
||||||
|
<p>Waking up upstream server...</p>
|
||||||
|
<div class="stats">
|
||||||
|
<div><span class="stats-label">Time elapsed:</span> <span id="elapsed">0s</span></div>
|
||||||
|
<div><span id="attempts"> </span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
var startTime = Date.now();
|
||||||
|
var attempts = 0;
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
var elapsed = (Date.now() - startTime) / 1000;
|
||||||
|
document.getElementById('elapsed').textContent = elapsed.toFixed(1) + 's';
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
// Check status every second
|
||||||
|
setInterval(function() {
|
||||||
|
attempts++;
|
||||||
|
var dots = '.'.repeat((attempts % 10) || 10);
|
||||||
|
document.getElementById('attempts').textContent = dots;
|
||||||
|
|
||||||
|
fetch('/status')
|
||||||
|
.then(function(r) { return r.text(); })
|
||||||
|
.then(function(t) {
|
||||||
|
if (t.indexOf('status: ready') !== -1) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function() {});
|
||||||
|
}, 1000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
|
_ "embed"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -19,6 +20,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed index.html
|
||||||
|
var loadingPageHTML string
|
||||||
|
|
||||||
var (
|
var (
|
||||||
flagMac = flag.String("mac", "", "mac address to send WoL packet to")
|
flagMac = flag.String("mac", "", "mac address to send WoL packet to")
|
||||||
flagUpstream = flag.String("upstream", "", "upstream proxy address to send requests to")
|
flagUpstream = flag.String("upstream", "", "upstream proxy address to send requests to")
|
||||||
@@ -230,6 +234,15 @@ func (p *proxyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if err := sendMagicPacket(*flagMac); err != nil {
|
if err := sendMagicPacket(*flagMac); err != nil {
|
||||||
slog.Warn("failed to send magic WoL packet", "error", err)
|
slog.Warn("failed to send magic WoL packet", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For root path requests, return loading page with status polling
|
||||||
|
if path == "/" {
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, loadingPageHTML)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(250 * time.Millisecond)
|
ticker := time.NewTicker(250 * time.Millisecond)
|
||||||
timeout, cancel := context.WithTimeout(context.Background(), time.Duration(*flagTimeout)*time.Second)
|
timeout, cancel := context.WithTimeout(context.Background(), time.Duration(*flagTimeout)*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|||||||
Reference in New Issue
Block a user