From c5eb13032ef01a305e80f953ceac080645b454ee Mon Sep 17 00:00:00 2001 From: Arpit Jain Date: Thu, 5 Nov 2026 08:30:56 -0800 Subject: [PATCH] fix(vhost): match virtual host names case-insensitively Co-Authored-By: Claude Signed-off-by: Arpit Jain --- vhost.go | 15 +++++++++++++-- vhost_test.go | 7 +++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/vhost.go b/vhost.go index 25dfd7925..aa7dd5919 100644 --- a/vhost.go +++ b/vhost.go @@ -3,14 +3,25 @@ package echo -import "net/http" +import ( + "net/http" + "strings" +) // NewVirtualHostHandler creates instance of Echo that routes requests to given virtual hosts // when hosts in request does not exist in given map the request is served by returned Echo instance. +// +// Host names are matched case-insensitively (RFC 9110 Section 4.2.3), so a request with +// `Host: Example.com` reaches the instance registered as `example.com`. The map is copied, +// later changes to it have no effect. func NewVirtualHostHandler(vhosts map[string]*Echo) *Echo { e := New() + hosts := make(map[string]*Echo, len(vhosts)) + for host, vhost := range vhosts { + hosts[strings.ToLower(host)] = vhost + } e.serveHTTPFunc = func(w http.ResponseWriter, r *http.Request) { - if vh, ok := vhosts[r.Host]; ok { + if vh, ok := hosts[strings.ToLower(r.Host)]; ok { vh.ServeHTTP(w, r) return } diff --git a/vhost_test.go b/vhost_test.go index ca3809ca1..6142bd1f9 100644 --- a/vhost_test.go +++ b/vhost_test.go @@ -72,6 +72,13 @@ func TestVirtualHostHandler(t *testing.T) { expectBody: http.StatusText(http.StatusOK), expectStatus: http.StatusOK, }, + { + name: "OK Host Root, host in different case", + whenHost: "OK.Com", + whenPath: "/", + expectBody: http.StatusText(http.StatusOK), + expectStatus: http.StatusOK, + }, { name: "Teapot Host Root", whenHost: "teapot.com",