updated favicons, fix domain rerouting, fix deploy provisioning

This commit is contained in:
Evan Jarrett
2026-02-08 20:50:31 -06:00
parent 4d9452bb75
commit bc034e3465
9 changed files with 180 additions and 32 deletions

View File

@@ -256,6 +256,11 @@ func cmdProvision(token, zone, plan, sshKeyPath, s3Secret string) error {
saveState(state)
}
// Always reconcile forwarded headers rule (handles existing LBs)
if err := ensureLBForwardedHeaders(ctx, svc, state.LB.UUID); err != nil {
return fmt.Errorf("LB forwarded headers: %w", err)
}
// Always reconcile TLS certs (handles partial failures and re-runs)
tlsDomains := []string{cfg.BaseDomain}
tlsDomains = append(tlsDomains, cfg.RegistryDomains...)
@@ -566,6 +571,14 @@ func createLoadBalancer(ctx context.Context, svc *service.Service, cfg *InfraCon
{Name: "public"},
},
Rules: []request.LoadBalancerFrontendRule{
{
Name: "set-forwarded-headers",
Priority: 1,
Matchers: []upcloud.LoadBalancerMatcher{},
Actions: []upcloud.LoadBalancerAction{
request.NewLoadBalancerSetForwardedHeadersAction(),
},
},
{
Name: "route-hold",
Priority: 10,
@@ -720,6 +733,45 @@ func ensureLBCertificates(ctx context.Context, svc *service.Service, lbUUID stri
return nil
}
// ensureLBForwardedHeaders ensures the "https" frontend has a set_forwarded_headers rule.
// This makes the LB set X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Port headers,
// overwriting any pre-existing values (prevents spoofing).
func ensureLBForwardedHeaders(ctx context.Context, svc *service.Service, lbUUID string) error {
rules, err := svc.GetLoadBalancerFrontendRules(ctx, &request.GetLoadBalancerFrontendRulesRequest{
ServiceUUID: lbUUID,
FrontendName: "https",
})
if err != nil {
return fmt.Errorf("get frontend rules: %w", err)
}
for _, r := range rules {
if r.Name == "set-forwarded-headers" {
fmt.Println(" Forwarded headers rule: exists")
return nil
}
}
_, err = svc.CreateLoadBalancerFrontendRule(ctx, &request.CreateLoadBalancerFrontendRuleRequest{
ServiceUUID: lbUUID,
FrontendName: "https",
Rule: request.LoadBalancerFrontendRule{
Name: "set-forwarded-headers",
Priority: 1,
Matchers: []upcloud.LoadBalancerMatcher{},
Actions: []upcloud.LoadBalancerAction{
request.NewLoadBalancerSetForwardedHeadersAction(),
},
},
})
if err != nil {
return fmt.Errorf("create forwarded headers rule: %w", err)
}
fmt.Println(" Forwarded headers rule: created")
return nil
}
// lookupObjectStorage discovers details of an existing Managed Object Storage.
func lookupObjectStorage(ctx context.Context, svc *service.Service, uuid string) (ObjectStorageState, error) {
storage, err := svc.GetManagedObjectStorage(ctx, &request.GetManagedObjectStorageRequest{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
pkg/appview/public/atcr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,17 +1,78 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512"><svg version="1.1" id="svg1" width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs1">
<rect x="264" y="264" width="203.43417" height="218.82669" id="rect63"></rect>
</defs>
<g id="g1">
<rect style="fill:#5ecac1;fill-opacity:1;stroke:#000000;stroke-width:18.0441;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" id="rect16" width="246.95587" height="246.95584" x="9.0220766" y="9.0220766"></rect>
<rect style="fill:#254365;fill-opacity:1;stroke:#000000;stroke-width:18.0441;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" id="rect17" width="246.95587" height="246.95584" x="9.0220766" y="256.02206"></rect>
<rect style="fill:#f29b54;fill-opacity:1;stroke:#000000;stroke-width:18.0012;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal" id="rect18" width="246.99879" height="246.99883" x="256.00061" y="9.0005999"></rect>
<rect style="display:inline;fill:#47a5d8;fill-opacity:1;stroke:#000000;stroke-width:18.0441;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke" id="rect19" width="246.95586" height="246.95587" x="256.02206" y="256.02206"></rect>
<path id="use60" style="fill:#193045;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0;paint-order:normal" d="m 309,42 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 c 0,-5.54 -4.014,-10 -9,-10 z"></path>
<path id="use60-1" style="fill:#193045;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0;paint-order:normal" d="m 57,42 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 C 66,46.46 61.986,42 57,42 Z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 52 c 0,-5.54 -4.014,-10 -9,-10 z"></path>
<path id="use60-3" style="fill:#193045;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0;paint-order:normal" d="m 57,288 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 298 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 298 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 298 c 0,-5.54 -4.014,-10 -9,-10 z m 48,0 c -4.986,0 -9,4.46 -9,10 v 160 c 0,5.54 4.014,10 9,10 4.986,0 9,-4.46 9,-10 V 298 c 0,-5.54 -4.014,-10 -9,-10 z"></path>
<text xml:space="preserve" id="text63" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:151.33px;font-family:'Noto Sans Telugu';-inkscape-font-specification:'Noto Sans Telugu';text-align:center;writing-mode:lr-tb;direction:ltr;white-space:pre;shape-inside:url(#rect63);shape-padding:0;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:18;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0;paint-order:normal" x="126" y="0" transform="matrix(1.4849596,0,0,1.4775815,-169.00723,-145.87951)"><tspan x="300.94749" y="401.69141" id="tspan2"><tspan style="font-style:italic;font-weight:bold;font-family:'Droid Sans Thai';-inkscape-font-specification:'Droid Sans Thai Bold Italic'" id="tspan1">@</tspan></tspan></text>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
width="511.99997"
height="512"
id="svg5"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs5" />
<g
id="g1">
<rect
style="fill:#5ecac1;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="teal"
width="256"
height="256"
x="0"
y="0" />
<rect
style="fill:#254365;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="blue-dark"
width="256"
height="256"
x="0"
y="256" />
<rect
style="fill:#f29b54;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
id="orange"
width="256"
height="256"
x="256"
y="0"
ry="0" />
<rect
style="display:inline;fill:#47a5d8;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
id="blue-light"
width="256"
height="256"
x="256"
y="256" />
<path
id="use60"
style="fill:#193045;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0;paint-order:normal"
d="M 313.33334,40 C 308.16267,40 304,44.162668 304,49.333334 V 198.66665 c 0,5.17067 4.16267,9.33335 9.33334,9.33335 5.17065,0 9.33332,-4.16268 9.33332,-9.33335 V 49.333334 C 322.66666,44.162668 318.50399,40 313.33334,40 Z m 49.77777,0 c -5.17066,0 -9.33333,4.162668 -9.33333,9.333334 V 198.66665 c 0,5.17067 4.16267,9.33335 9.33333,9.33335 5.17066,0 9.33333,-4.16268 9.33333,-9.33335 V 49.333334 C 372.44444,44.162668 368.28177,40 363.11111,40 Z m 49.77778,0 c -5.17066,0 -9.33333,4.162668 -9.33333,9.333334 V 198.66665 c 0,5.17067 4.16267,9.33335 9.33333,9.33335 5.17066,0 9.33333,-4.16268 9.33333,-9.33335 V 49.333334 C 422.22222,44.162668 418.05955,40 412.88889,40 Z m 49.77777,0 c -5.17065,0 -9.33332,4.162668 -9.33332,9.333334 V 198.66665 c 0,5.17067 4.16267,9.33335 9.33332,9.33335 C 467.83733,208 472,203.83732 472,198.66665 V 49.333334 C 472,44.162668 467.83733,40 462.66666,40 Z" />
<path
id="use60-1"
style="fill:#193045;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0;paint-order:normal"
d="M 49.333334,40 C 44.162667,40 40,44.162668 40,49.333333 V 198.66664 C 40,203.83732 44.162667,208 49.333334,208 c 5.170665,0 9.333333,-4.16268 9.333333,-9.33336 V 49.333333 C 58.666667,44.162668 54.503999,40 49.333334,40 Z m 49.777781,0 c -5.170672,0 -9.333336,4.162668 -9.333336,9.333333 V 198.66664 c 0,5.17068 4.162664,9.33336 9.333336,9.33336 5.170645,0 9.333325,-4.16268 9.333325,-9.33336 V 49.333333 C 108.44444,44.162668 104.28176,40 99.111115,40 Z m 49.777765,0 c -5.17064,0 -9.33332,4.162668 -9.33332,9.333333 V 198.66664 c 0,5.17068 4.16268,9.33336 9.33332,9.33336 5.17066,0 9.33334,-4.16268 9.33334,-9.33336 V 49.333333 C 158.22222,44.162668 154.05954,40 148.88888,40 Z m 49.77777,0 c -5.17064,0 -9.33332,4.162668 -9.33332,9.333333 V 198.66664 c 0,5.17068 4.16268,9.33336 9.33332,9.33336 C 203.83733,208 208,203.83732 208,198.66664 V 49.333333 C 208,44.162668 203.83733,40 198.66665,40 Z" />
<path
id="use60-3"
style="fill:#193045;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0;paint-order:normal"
d="M 49.333334,304 C 44.162667,304 40,308.16267 40,313.33334 V 462.66666 C 40,467.83733 44.162667,472 49.333334,472 c 5.170665,0 9.333333,-4.16267 9.333333,-9.33334 V 313.33334 C 58.666667,308.16267 54.503999,304 49.333334,304 Z m 49.777777,0 c -5.170668,0 -9.333332,4.16267 -9.333332,9.33334 v 149.33332 c 0,5.17067 4.162664,9.33334 9.333332,9.33334 5.170659,0 9.333329,-4.16267 9.333329,-9.33334 V 313.33334 c 0,-5.17067 -4.16267,-9.33334 -9.333329,-9.33334 z m 49.777779,0 c -5.17065,0 -9.33333,4.16267 -9.33333,9.33334 v 149.33332 c 0,5.17067 4.16268,9.33334 9.33333,9.33334 5.17065,0 9.33333,-4.16267 9.33333,-9.33334 V 313.33334 c 0,-5.17067 -4.16268,-9.33334 -9.33333,-9.33334 z m 49.77777,0 c -5.17065,0 -9.33333,4.16267 -9.33333,9.33334 v 149.33332 c 0,5.17067 4.16268,9.33334 9.33333,9.33334 C 203.83733,472 208,467.83733 208,462.66666 V 313.33334 C 208,308.16267 203.83733,304 198.66666,304 Z" />
<path
style="font-style:italic;font-weight:bold;font-size:151.33px;font-family:'Droid Sans Thai';-inkscape-font-specification:'Droid Sans Thai Bold Italic';text-align:center;white-space:pre;fill:#ffffff;stroke-width:24.8853;stroke-linejoin:round;stroke-opacity:0"
d="m 376.56929,472 q -17.82771,0 -31.46068,-5.42608 -13.63295,-5.21741 -22.86141,-14.8174 -9.01873,-9.59999 -13.63297,-22.33043 Q 304,416.69565 304,402.08695 q 0,-18.9913 5.03371,-34.43478 5.24343,-15.44346 14.4719,-27.33912 9.4382,-11.89566 21.81274,-20.03479 12.37453,-8.13914 26.84645,-12.10436 Q 386.84643,304 402.36705,304 q 21.81272,0 37.33333,7.51305 15.52059,7.51302 23.9101,21.70435 Q 472,347.40869 472,367.44346 q 0,9.8087 -2.30712,19.40873 -2.09736,9.39129 -6.29212,17.73913 -4.19476,8.13911 -10.48691,14.39998 -6.0824,6.05217 -14.05242,9.59999 -7.97004,3.54785 -17.61797,3.54785 -8.1798,0 -14.26219,-3.54785 -6.08238,-3.75651 -7.97003,-11.47826 h -1.04869 q -4.40451,6.88696 -10.48689,11.06088 -5.87266,3.96523 -15.73035,3.96523 -11.53557,0 -19.50563,-7.30436 -7.97002,-7.51304 -7.97002,-24.20868 0,-8.34785 2.30711,-16.48698 2.51685,-8.34781 6.92136,-15.65217 4.61422,-7.30433 11.11611,-12.73044 6.50186,-5.63477 14.89137,-8.76521 8.38952,-3.13044 18.24719,-3.13044 11.32584,0 19.2959,1.66957 7.97003,1.66957 14.26218,3.96521 l -10.90637,42.78261 q -1.0487,4.59131 -1.88765,7.93044 -0.83895,3.13044 -0.83895,6.46958 0,3.75651 1.6779,5.42607 1.6779,1.46088 4.19476,1.46088 4.4045,0 8.38951,-2.50436 3.98501,-2.71303 7.13108,-7.30434 3.14607,-4.59131 5.45317,-10.43479 2.30712,-6.05217 3.56556,-12.52173 1.25841,-6.46958 1.25841,-12.93913 0,-13.77391 -5.45317,-23.7913 -5.24345,-10.01741 -16.1498,-15.44348 -10.90638,-5.4261 -27.89514,-5.4261 -12.37453,0 -23.49064,3.54783 -11.11609,3.33913 -20.13482,10.01738 -9.01876,6.46959 -15.73036,15.86088 -6.50185,9.39131 -10.06741,21.28697 -3.56554,11.89566 -3.56554,25.87826 0,14.1913 5.24344,26.29565 5.24346,12.10436 16.77902,19.40868 11.53561,7.09566 30.20227,7.09566 13.00373,0 23.49064,-2.29565 Q 413.2734,448 424.17977,443.82608 v 18.99132 q -9.85767,3.96521 -21.81272,6.46955 Q 390.62173,472 376.56929,472 Z m 0.62921,-58.43478 q 8.17977,0 13.21348,-7.51305 5.24346,-7.72174 8.59926,-20.03478 l 5.87265,-22.53914 q -1.88764,-0.41737 -3.77528,-0.62607 -1.88762,-0.41741 -4.61422,-0.41741 -7.34082,0 -12.79402,3.75653 -5.45317,3.54783 -9.01872,9.3913 -3.56555,5.63477 -5.45319,12.10436 -1.6779,6.26086 -1.6779,11.68695 0,7.93045 2.93634,11.06087 2.93631,3.13044 6.7116,3.13044 z"
id="text63"
aria-label="@" />
<rect
style="fill:#000000;fill-opacity:1;stroke-width:0;stroke-linejoin:round;stroke-opacity:0;paint-order:markers fill stroke"
id="rect1"
width="512"
height="16"
x="0"
y="248" />
<rect
style="fill:#000000;fill-opacity:1;stroke-width:0;stroke-linejoin:round;stroke-opacity:0;paint-order:markers fill stroke"
id="rect2"
width="16"
height="512"
x="248"
y="0" />
</g>
</svg></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
<style
id="style4">@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: none; } }
</style></svg>
</style>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -9,12 +9,14 @@ import (
"log/slog"
"net"
"net/http"
"net/url"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/distribution/distribution/v3/registry/api/errcode"
"github.com/distribution/distribution/v3/registry/handlers"
"github.com/go-chi/chi/v5"
chimiddleware "github.com/go-chi/chi/v5/middleware"
@@ -239,10 +241,10 @@ func NewAppViewServer(cfg *Config, branding *BrandingOverrides) (*AppViewServer,
mainRouter.Use(chimiddleware.GetHead)
mainRouter.Use(routes.CORSMiddleware())
// Registry domain redirect middleware
// Domain routing middleware
if len(cfg.Server.RegistryDomains) > 0 {
mainRouter.Use(RegistryDomainRedirect(cfg.Server.RegistryDomains, cfg.Server.BaseURL))
slog.Info("Registry domain redirect enabled",
mainRouter.Use(DomainRoutingMiddleware(cfg.Server.RegistryDomains, cfg.Server.BaseURL))
slog.Info("Domain routing middleware enabled",
"registry_domains", cfg.Server.RegistryDomains,
"ui_base_url", cfg.Server.BaseURL)
}
@@ -580,15 +582,29 @@ func (s *AppViewServer) createTokenIssuer() (*token.Issuer, error) {
)
}
// RegistryDomainRedirect redirects all non-registry requests from registry
// domains to the UI domain. Only /v2 and /v2/* pass through for Docker clients.
// Uses 307 (Temporary Redirect) to preserve POST method/body.
func RegistryDomainRedirect(registryDomains []string, uiBaseURL string) func(http.Handler) http.Handler {
domains := make(map[string]bool, len(registryDomains))
// DomainRoutingMiddleware enforces three-tier domain routing:
//
// 1. UI domain (BaseURL hostname): serves web UI, auth, and static assets.
// Blocks /v2/* with an OCI UNSUPPORTED error — registry API lives on
// the dedicated registry domain(s).
// 2. Registry domains: allows /v2/* for Docker clients. Redirects everything
// else to the UI domain with 307 Temporary Redirect.
// 3. Unknown domains (CDN origins, IPs, etc.): redirects all requests to the
// UI domain with 307, except /health for load balancer probes.
func DomainRoutingMiddleware(registryDomains []string, uiBaseURL string) func(http.Handler) http.Handler {
regDomains := make(map[string]bool, len(registryDomains))
for _, d := range registryDomains {
domains[d] = true
regDomains[d] = true
}
// Extract UI hostname from BaseURL (e.g., "https://seamark.dev" -> "seamark.dev")
var uiHost string
if parsed, err := url.Parse(uiBaseURL); err == nil {
uiHost = parsed.Hostname()
}
primaryReg := primaryRegistryDomain(registryDomains)
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
host := r.Host
@@ -596,19 +612,38 @@ func RegistryDomainRedirect(registryDomains []string, uiBaseURL string) func(htt
host = host[:idx]
}
if domains[host] {
path := r.URL.Path
if path == "/v2" || path == "/v2/" || strings.HasPrefix(path, "/v2/") {
path := r.URL.Path
isV2 := path == "/v2" || path == "/v2/" || strings.HasPrefix(path, "/v2/")
switch {
case host == uiHost:
// UI domain: block /v2/*, serve everything else
if isV2 {
if err := errcode.ServeJSON(w, errcode.ErrorCodeUnsupported.WithMessage(
fmt.Sprintf("registry API is not available on this domain, use %s", primaryReg),
)); err != nil {
slog.Error("failed to write OCI error response", "error", err)
}
return
}
next.ServeHTTP(w, r)
case regDomains[host]:
// Registry domain: allow /v2/*, redirect everything else
if isV2 {
next.ServeHTTP(w, r)
return
}
http.Redirect(w, r, uiBaseURL+r.URL.RequestURI(), http.StatusTemporaryRedirect)
target := uiBaseURL + r.URL.RequestURI()
http.Redirect(w, r, target, http.StatusTemporaryRedirect)
return
default:
// Unknown domain: allow /health, redirect everything else
if path == "/health" {
next.ServeHTTP(w, r)
return
}
http.Redirect(w, r, uiBaseURL+r.URL.RequestURI(), http.StatusTemporaryRedirect)
}
next.ServeHTTP(w, r)
})
}
}