diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index e0a6c1cc..15cfe1e0 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -530,6 +530,7 @@ func (st *ServerType) serversFromPairings( "sni": caddyconfig.JSON(hosts, warnings), // make sure to match all hosts, not just auto-HTTPS-qualified ones } } else { + cp.DefaultSNI = defaultSNI hasCatchAllTLSConnPolicy = true } diff --git a/caddytest/a.caddy.localhost.crt b/caddytest/a.caddy.localhost.crt new file mode 100644 index 00000000..79880609 --- /dev/null +++ b/caddytest/a.caddy.localhost.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID5zCCAs8CFG4+w/pqR5AZQ+aVB330uRRRKMF0MA0GCSqGSIb3DQEBCwUAMIGv +MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxGzAZBgNVBAoMEkxvY2FsIERldmVs +b3BlbWVudDEbMBkGA1UEBwwSTG9jYWwgRGV2ZWxvcGVtZW50MRowGAYDVQQDDBFh +LmNhZGR5LmxvY2FsaG9zdDEbMBkGA1UECwwSTG9jYWwgRGV2ZWxvcGVtZW50MSAw +HgYJKoZIhvcNAQkBFhFhZG1pbkBjYWRkeS5sb2NhbDAeFw0yMDAzMTMxODUwMTda +Fw0zMDAzMTExODUwMTdaMIGvMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxGzAZ +BgNVBAoMEkxvY2FsIERldmVsb3BlbWVudDEbMBkGA1UEBwwSTG9jYWwgRGV2ZWxv +cGVtZW50MRowGAYDVQQDDBFhLmNhZGR5LmxvY2FsaG9zdDEbMBkGA1UECwwSTG9j +YWwgRGV2ZWxvcGVtZW50MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBjYWRkeS5sb2Nh +bDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMd9pC9wF7j0459FndPs +Deud/rq41jEZFsVOVtjQgjS1A5ct6NfeMmSlq8i1F7uaTMPZjbOHzY6y6hzLc9+y +/VWNgyUC543HjXnNTnp9Xug6tBBxOxvRMw5mv2nAyzjBGDePPgN84xKhOXG2Wj3u +fOZ+VPVISefRNvjKfN87WLJ0B0HI9wplG5ASVdPQsWDY1cndrZgt2sxQ/3fjIno4 +VvrgRWC9Penizgps/a0ZcFZMD/6HJoX/mSZVa1LjopwbMTXvyHCpXkth21E+rBt6 +I9DMHerdioVQcX25CqPmAwePxPZSNGEQo/Qu32kzcmscmYxTtYBhDa+yLuHgGggI +j7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAP/94KPtkpYtkWADnhtzDmgQ6Q1pH +SubTUZdCwQtm6/LrvpT+uFNsOj4L3Mv3TVUnIQDmKd5VvR42W2MRBiTN2LQptgEn +C7g9BB+UA9kjL3DPk1pJMjzxLHohh0uNLi7eh4mAj8eNvjz9Z4qMWPQoVS0y7/ZK +cCBRKh2GkIqKm34ih6pX7xmMpPEQsFoTVPRHYJfYD1SZ8Iui+EN+7WqLuJWPsPXw +JM1HuZKn7pZmJU2MZZBsrupHGUvNMbBg2mFJcxt4D1VvU+p+a67PSjpFQ6dJG2re +pZoF+N1vMGAFkxe6UqhcC/bXDX+ILVQHJ+RNhzDO6DcWf8dRrC2LaJk3WA== +-----END CERTIFICATE----- diff --git a/caddytest/a.caddy.localhost.key b/caddytest/a.caddy.localhost.key new file mode 100644 index 00000000..332ea747 --- /dev/null +++ b/caddytest/a.caddy.localhost.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAx32kL3AXuPTjn0Wd0+wN653+urjWMRkWxU5W2NCCNLUDly3o +194yZKWryLUXu5pMw9mNs4fNjrLqHMtz37L9VY2DJQLnjceNec1Oen1e6Dq0EHE7 +G9EzDma/acDLOMEYN48+A3zjEqE5cbZaPe585n5U9UhJ59E2+Mp83ztYsnQHQcj3 +CmUbkBJV09CxYNjVyd2tmC3azFD/d+MiejhW+uBFYL096eLOCmz9rRlwVkwP/ocm +hf+ZJlVrUuOinBsxNe/IcKleS2HbUT6sG3oj0Mwd6t2KhVBxfbkKo+YDB4/E9lI0 +YRCj9C7faTNyaxyZjFO1gGENr7Iu4eAaCAiPsQIDAQABAoIBAQDD/YFIBeWYlifn +e9risQDAIrp3sk7lb9O6Rwv1+Wxi4hBEABvJsYhq74VFK/3EF4UhyWR5JIvkjYyK +e6w887oGyoA05ZSe65XoO7fFidSrbbkoikZbPv3dQT7/ZCWEfdkQBNAVVyY0UGeC +e3hPbjYRsb5AOSQ694X9idqC6uhqcOrBDjITFrctUoP4S6l9A6a+mLSUIwiICcuh +mrNl+j0lzy7DMXRp/Z5Hyo5kuUlrC0dCLa1UHqtrrK7MR55AVEOihSNp1w+OC+vw +f0VjE4JUtO7RQEQUmD1tDfLXwNfMFeWaobB2W0WMvRg0IqoitiqPxsPHRm56OxfM +SRo/Q7QBAoGBAP8DapzBMuaIcJ7cE8Yl07ZGndWWf8buIKIItGF8rkEO3BXhrIke +EmpOi+ELtpbMOG0APhORZyQ58f4ZOVrqZfneNKtDiEZV4mJZaYUESm1pU+2Y6+y5 +g4bpQSVKN0ow0xR+MH7qDYtSlsmBU7qAOz775L7BmMA1Bnu72aN/H1JBAoGBAMhD +OzqCSakHOjUbEd22rPwqWmcIyVyo04gaSmcVVT2dHbqR4/t0gX5a9D9U2qwyO6xi +/R+PXyMd32xIeVR2D/7SQ0x6dK68HXICLV8ofHZ5UQcHbxy5og4v/YxSZVTkN374 +cEsUeyB0s/UPOHLktFU5hpIlON72/Rp7b+pNIwFxAoGAczpq+Qu/YTWzlcSh1r4O +7OT5uqI3eH7vFehTAV3iKxl4zxZa7NY+wfRd9kFhrr/2myIp6pOgBFl+hC+HoBIc +JAyIxf5M3GNAWOpH6MfojYmzV7/qktu8l8BcJGplk0t+hVsDtMUze4nFAqZCXBpH +Kw2M7bjyuZ78H/rgu6TcVUECgYEAo1M5ldE2U/VCApeuLX1TfWDpU8i1uK0zv3d5 +oLKkT1i5KzTak3SEO9HgC1qf8PoS8tfUio26UICHe99rnHehOfivzEq+qNdgyF+A +M3BoeZMdgzcL5oh640k+Zte4LtDlddcWdhUhCepD7iPYrNNbQ3pkBwL2a9lRuOxc +7OC2IPECgYBH8f3OrwXjDltIG1dDvuDPNljxLZbFEFbQyVzMePYNftgZknAyGEdh +NW/LuWeTzstnmz/s6RE3jN5ZrrMa4sW77VA9+yU9QW2dkHqFyukQ4sfuNg6kDDNZ ++lqZYMCLw0M5P9fIbmnIYwey7tXkHfmzoCpnYHGQDN6hL0Bh0zGwmg== +-----END RSA PRIVATE KEY----- diff --git a/caddytest/caddytest.go b/caddytest/caddytest.go index 04b65ba8..89e457ce 100644 --- a/caddytest/caddytest.go +++ b/caddytest/caddytest.go @@ -45,6 +45,11 @@ type configLoadError struct { func (e configLoadError) Error() string { return e.Response } +func timeElapsed(start time.Time, name string) { + elapsed := time.Since(start) + log.Printf("%s took %s", name, elapsed) +} + // InitServer this will configure the server with a configurion of a specific // type. The configType must be either "json" or the adapter type. func InitServer(t *testing.T, rawConfig string, configType string) { @@ -83,6 +88,8 @@ func initServer(t *testing.T, rawConfig string, configType string) error { client := &http.Client{ Timeout: time.Second * 2, } + + start := time.Now() req, err := http.NewRequest("POST", fmt.Sprintf("http://localhost:%d/load", Default.AdminPort), strings.NewReader(rawConfig)) if err != nil { t.Errorf("failed to create request. %s", err) @@ -100,6 +107,8 @@ func initServer(t *testing.T, rawConfig string, configType string) error { t.Errorf("unable to contact caddy server. %s", err) return err } + timeElapsed(start, "caddytest: config load time") + defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { @@ -208,7 +217,7 @@ func AssertLoadError(t *testing.T, rawConfig string, configType string, expected func AssertGetResponse(t *testing.T, requestURI string, statusCode int, expectedBody string) (*http.Response, string) { resp, body := AssertGetResponseBody(t, requestURI, statusCode) if !strings.Contains(body, expectedBody) { - t.Errorf("expected response body \"%s\" but got \"%s\"", expectedBody, body) + t.Errorf("requesting \"%s\" expected response body \"%s\" but got \"%s\"", requestURI, expectedBody, body) } return resp, string(body) } @@ -229,7 +238,7 @@ func AssertGetResponseBody(t *testing.T, requestURI string, expectedStatusCode i defer resp.Body.Close() if expectedStatusCode != resp.StatusCode { - t.Errorf("expected status code: %d but got %d", expectedStatusCode, resp.StatusCode) + t.Errorf("requesting \"%s\" expected status code: %d but got %d", requestURI, expectedStatusCode, resp.StatusCode) } body, err := ioutil.ReadAll(resp.Body) @@ -260,12 +269,12 @@ func AssertRedirect(t *testing.T, requestURI string, expectedToLocation string, } if expectedStatusCode != resp.StatusCode { - t.Errorf("expected status code: %d but got %d", expectedStatusCode, resp.StatusCode) + t.Errorf("requesting \"%s\" expected status code: %d but got %d", requestURI, expectedStatusCode, resp.StatusCode) } loc, err := resp.Location() if expectedToLocation != loc.String() { - t.Errorf("expected location: \"%s\" but got \"%s\"", expectedToLocation, loc.String()) + t.Errorf("requesting \"%s\" expected location: \"%s\" but got \"%s\"", requestURI, expectedToLocation, loc.String()) } return resp diff --git a/caddytest/integration/caddyfile_test.go b/caddytest/integration/caddyfile_test.go index 33b4b2d9..3e89a26a 100644 --- a/caddytest/integration/caddyfile_test.go +++ b/caddytest/integration/caddyfile_test.go @@ -17,13 +17,13 @@ func TestRespond(t *testing.T) { localhost:9080 { respond /version 200 { - body "hello from a.caddy.localhost" + body "hello from localhost" } } `, "caddyfile") // act and assert - caddytest.AssertGetResponse(t, "http://localhost:9080/version", 200, "hello from a.caddy.localhost") + caddytest.AssertGetResponse(t, "http://localhost:9080/version", 200, "hello from localhost") } func TestRedirect(t *testing.T) { @@ -40,7 +40,7 @@ func TestRedirect(t *testing.T) { redir / http://localhost:9080/hello 301 respond /hello 200 { - body "hello from b" + body "hello from localhost" } } `, "caddyfile") @@ -49,7 +49,7 @@ func TestRedirect(t *testing.T) { caddytest.AssertRedirect(t, "http://localhost:9080/", "http://localhost:9080/hello", 301) // follow redirect - caddytest.AssertGetResponse(t, "http://localhost:9080/", 200, "hello from b") + caddytest.AssertGetResponse(t, "http://localhost:9080/", 200, "hello from localhost") } func TestDuplicateHosts(t *testing.T) { @@ -78,8 +78,52 @@ func TestDefaultSNI(t *testing.T) { } 127.0.0.1:9443 { - tls /caddy.localhost.crt /caddy.localhost.key { - } + tls /caddy.localhost.crt /caddy.localhost.key + respond /version 200 { + body "hello from a" + } + } + `, "caddyfile") + + // act and assert + caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a") +} + +func TestDefaultSNIWithNamedHostAndExplicitIP(t *testing.T) { + + // arrange + caddytest.InitServer(t, ` + { + http_port 9080 + https_port 9443 + default_sni a.caddy.localhost + } + + a.caddy.localhost:9443, 127.0.0.1:9443 { + tls /a.caddy.localhost.crt /a.caddy.localhost.key + respond /version 200 { + body "hello from a" + } + } + `, "caddyfile") + + // act and assert + // makes a request with no sni + caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a") +} + +func TestDefaultSNIWithPortMappingOnly(t *testing.T) { + + // arrange + caddytest.InitServer(t, ` + { + http_port 9080 + https_port 9443 + default_sni a.caddy.localhost + } + + :9443 { + tls /a.caddy.localhost.crt /a.caddy.localhost.key respond /version 200 { body "hello from a.caddy.localhost" } @@ -87,5 +131,6 @@ func TestDefaultSNI(t *testing.T) { `, "caddyfile") // act and assert - caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a.caddy.localhost") + // makes a request with no sni + caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a") }