CI / test (push) Failing after 2m18s
A website on 0.0.0.0 and websites on named addresses can use the same port. An https resource with the redirect on also uses port 80 at its address, so a raw port there is refused, in either order. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
77 lines
3.9 KiB
Go
77 lines
3.9 KiB
Go
package hammerhead
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// websites share a port by hostname, and a website on every address steps aside for one that names an address
|
|
func TestWebsitesShareAPortAndWildcardsStepAside(t *testing.T) {
|
|
s, err := New(t.TempDir(), Options{AdminEmail: "admin@test.local", AdminPassword: "password123", MasterKey: key})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer s.Close()
|
|
do := apiClient(t, s)
|
|
var me struct{ Orgs []struct{ ID string } }
|
|
_, b := do("GET", "/api/me", nil)
|
|
json.Unmarshal(b, &me)
|
|
org := me.Orgs[0].ID
|
|
var edge, site struct{ ID string }
|
|
_, b = do("POST", "/api/edges", map[string]any{"name": "e", "tunnelAddr": "203.0.113.5:51820"})
|
|
json.Unmarshal(b, &edge)
|
|
_, b = do("POST", "/api/orgs/"+org+"/sites", map[string]any{"name": "home"})
|
|
json.Unmarshal(b, &site)
|
|
if code, b := do("POST", "/api/orgs/"+org+"/domains", map[string]any{"name": "example.test", "edgeId": edge.ID, "ip": "203.0.113.10"}); code != 200 {
|
|
t.Fatalf("domain: %d %s", code, b)
|
|
}
|
|
base := "/api/orgs/" + org + "/mappings"
|
|
open := func(m map[string]any) (int, string) {
|
|
m["edgeId"] = edge.ID
|
|
m["enabled"] = true
|
|
m["targets"] = []any{map[string]any{"siteId": site.ID, "host": "127.0.0.1", "port": 8080}}
|
|
code, b := do("POST", base, m)
|
|
return code, string(b)
|
|
}
|
|
want := func(code int, got int, body, what string) {
|
|
t.Helper()
|
|
if code != got {
|
|
t.Errorf("%s: got %d, want %d (%s)", what, got, code, body)
|
|
}
|
|
}
|
|
|
|
c, body := open(map[string]any{"proto": "https", "bindIp": "0.0.0.0", "port": 443, "hostname": "a.example.test"})
|
|
want(200, c, body, "first website on every address")
|
|
c, body = open(map[string]any{"proto": "https", "bindIp": "203.0.113.10", "port": 443, "hostname": "b.example.test"})
|
|
want(200, c, body, "a website naming an address shares the port with the wildcard one")
|
|
c, body = open(map[string]any{"proto": "https", "bindIp": "203.0.113.11", "port": 443, "hostname": "c.example.test"})
|
|
want(200, c, body, "a second named address")
|
|
c, body = open(map[string]any{"proto": "https", "bindIp": "203.0.113.10", "port": 443, "hostname": "d.example.test"})
|
|
want(200, c, body, "another hostname on a named address")
|
|
// still refused: the same hostname twice on one listener, a raw port on a website's port, and another protocol
|
|
c, body = open(map[string]any{"proto": "https", "bindIp": "203.0.113.10", "port": 443, "hostname": "b.example.test"})
|
|
want(400, c, body, "the same hostname twice on one address")
|
|
c, body = open(map[string]any{"proto": "tcp", "bindIp": "0.0.0.0", "port": 443})
|
|
want(400, c, body, "a raw port on top of websites")
|
|
c, body = open(map[string]any{"proto": "http", "bindIp": "203.0.113.10", "port": 443, "hostname": "e.example.test"})
|
|
want(400, c, body, "http on an https port")
|
|
|
|
// the HTTP to HTTPS redirect also uses port 80 at its address
|
|
c, body = open(map[string]any{"proto": "tcp", "bindIp": "203.0.113.20", "port": 80})
|
|
want(200, c, body, "a raw port 80 on its own address")
|
|
c, body = open(map[string]any{"proto": "https", "bindIp": "203.0.113.20", "port": 8443, "hostname": "f.example.test", "redirectHttp": true})
|
|
want(400, c, body, "a redirect onto a raw port 80")
|
|
if !strings.Contains(body, "port 80") {
|
|
t.Errorf("the error should name port 80: %s", body)
|
|
}
|
|
c, body = open(map[string]any{"proto": "https", "bindIp": "203.0.113.20", "port": 8443, "hostname": "f.example.test"})
|
|
want(200, c, body, "the same website without the redirect")
|
|
c, body = open(map[string]any{"proto": "https", "bindIp": "203.0.113.21", "port": 443, "hostname": "g.example.test", "redirectHttp": true})
|
|
want(200, c, body, "a redirect where port 80 is free")
|
|
c, body = open(map[string]any{"proto": "tcp", "bindIp": "203.0.113.21", "port": 80})
|
|
want(400, c, body, "a raw port 80 where a redirect lives")
|
|
c, body = open(map[string]any{"proto": "http", "bindIp": "203.0.113.21", "port": 80, "hostname": "h.example.test"})
|
|
want(200, c, body, "an http website beside a redirect on port 80")
|
|
}
|