Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
caddyhttp: Add default SNI tests (#3146)
* added sni tests * set the default sni when there is no host to match * removed invalid sni test. Disabled tests that rely on host headers. * readded SNI tests. Added logging of config load times
Mark Sargent committed
Mar 18, 2020 at 07:39 UTC
3f48a2eb455167af8d77c5c4543bd17a80a93260
5 files changed
+116
-11
caddyconfig/httpcaddyfile/httptype.go
+1
@@ -530,6 +530,7 @@ func (st *ServerType) serversFromPairings(
530
"sni": caddyconfig.JSON(hosts, warnings), // make sure to match all hosts, not just auto-HTTPS-qualified ones
531
}
532
} else {
533
+ cp.DefaultSNI = defaultSNI
534
hasCatchAllTLSConnPolicy = true
535
}
536
caddytest/a.caddy.localhost.crt
new
+23
@@ -0,0 +1,23 @@
1
+-----BEGIN CERTIFICATE-----
2
+MIID5zCCAs8CFG4+w/pqR5AZQ+aVB330uRRRKMF0MA0GCSqGSIb3DQEBCwUAMIGv
3
+MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxGzAZBgNVBAoMEkxvY2FsIERldmVs
4
+b3BlbWVudDEbMBkGA1UEBwwSTG9jYWwgRGV2ZWxvcGVtZW50MRowGAYDVQQDDBFh
5
+LmNhZGR5LmxvY2FsaG9zdDEbMBkGA1UECwwSTG9jYWwgRGV2ZWxvcGVtZW50MSAw
6
+HgYJKoZIhvcNAQkBFhFhZG1pbkBjYWRkeS5sb2NhbDAeFw0yMDAzMTMxODUwMTda
7
+Fw0zMDAzMTExODUwMTdaMIGvMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxGzAZ
8
+BgNVBAoMEkxvY2FsIERldmVsb3BlbWVudDEbMBkGA1UEBwwSTG9jYWwgRGV2ZWxv
9
+cGVtZW50MRowGAYDVQQDDBFhLmNhZGR5LmxvY2FsaG9zdDEbMBkGA1UECwwSTG9j
10
+YWwgRGV2ZWxvcGVtZW50MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBjYWRkeS5sb2Nh
11
+bDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMd9pC9wF7j0459FndPs
12
+Deud/rq41jEZFsVOVtjQgjS1A5ct6NfeMmSlq8i1F7uaTMPZjbOHzY6y6hzLc9+y
13
+/VWNgyUC543HjXnNTnp9Xug6tBBxOxvRMw5mv2nAyzjBGDePPgN84xKhOXG2Wj3u
14
+fOZ+VPVISefRNvjKfN87WLJ0B0HI9wplG5ASVdPQsWDY1cndrZgt2sxQ/3fjIno4
15
+VvrgRWC9Penizgps/a0ZcFZMD/6HJoX/mSZVa1LjopwbMTXvyHCpXkth21E+rBt6
16
+I9DMHerdioVQcX25CqPmAwePxPZSNGEQo/Qu32kzcmscmYxTtYBhDa+yLuHgGggI
17
+j7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAP/94KPtkpYtkWADnhtzDmgQ6Q1pH
18
+SubTUZdCwQtm6/LrvpT+uFNsOj4L3Mv3TVUnIQDmKd5VvR42W2MRBiTN2LQptgEn
19
+C7g9BB+UA9kjL3DPk1pJMjzxLHohh0uNLi7eh4mAj8eNvjz9Z4qMWPQoVS0y7/ZK
20
+cCBRKh2GkIqKm34ih6pX7xmMpPEQsFoTVPRHYJfYD1SZ8Iui+EN+7WqLuJWPsPXw
21
+JM1HuZKn7pZmJU2MZZBsrupHGUvNMbBg2mFJcxt4D1VvU+p+a67PSjpFQ6dJG2re
22
+pZoF+N1vMGAFkxe6UqhcC/bXDX+ILVQHJ+RNhzDO6DcWf8dRrC2LaJk3WA==
23
+-----END CERTIFICATE-----
caddytest/a.caddy.localhost.key
new
+27
@@ -0,0 +1,27 @@
1
+-----BEGIN RSA PRIVATE KEY-----
2
+MIIEpAIBAAKCAQEAx32kL3AXuPTjn0Wd0+wN653+urjWMRkWxU5W2NCCNLUDly3o
3
+194yZKWryLUXu5pMw9mNs4fNjrLqHMtz37L9VY2DJQLnjceNec1Oen1e6Dq0EHE7
4
+G9EzDma/acDLOMEYN48+A3zjEqE5cbZaPe585n5U9UhJ59E2+Mp83ztYsnQHQcj3
5
+CmUbkBJV09CxYNjVyd2tmC3azFD/d+MiejhW+uBFYL096eLOCmz9rRlwVkwP/ocm
6
+hf+ZJlVrUuOinBsxNe/IcKleS2HbUT6sG3oj0Mwd6t2KhVBxfbkKo+YDB4/E9lI0
7
+YRCj9C7faTNyaxyZjFO1gGENr7Iu4eAaCAiPsQIDAQABAoIBAQDD/YFIBeWYlifn
8
+e9risQDAIrp3sk7lb9O6Rwv1+Wxi4hBEABvJsYhq74VFK/3EF4UhyWR5JIvkjYyK
9
+e6w887oGyoA05ZSe65XoO7fFidSrbbkoikZbPv3dQT7/ZCWEfdkQBNAVVyY0UGeC
10
+e3hPbjYRsb5AOSQ694X9idqC6uhqcOrBDjITFrctUoP4S6l9A6a+mLSUIwiICcuh
11
+mrNl+j0lzy7DMXRp/Z5Hyo5kuUlrC0dCLa1UHqtrrK7MR55AVEOihSNp1w+OC+vw
12
+f0VjE4JUtO7RQEQUmD1tDfLXwNfMFeWaobB2W0WMvRg0IqoitiqPxsPHRm56OxfM
13
+SRo/Q7QBAoGBAP8DapzBMuaIcJ7cE8Yl07ZGndWWf8buIKIItGF8rkEO3BXhrIke
14
+EmpOi+ELtpbMOG0APhORZyQ58f4ZOVrqZfneNKtDiEZV4mJZaYUESm1pU+2Y6+y5
15
+g4bpQSVKN0ow0xR+MH7qDYtSlsmBU7qAOz775L7BmMA1Bnu72aN/H1JBAoGBAMhD
16
+OzqCSakHOjUbEd22rPwqWmcIyVyo04gaSmcVVT2dHbqR4/t0gX5a9D9U2qwyO6xi
17
+/R+PXyMd32xIeVR2D/7SQ0x6dK68HXICLV8ofHZ5UQcHbxy5og4v/YxSZVTkN374
18
+cEsUeyB0s/UPOHLktFU5hpIlON72/Rp7b+pNIwFxAoGAczpq+Qu/YTWzlcSh1r4O
19
+7OT5uqI3eH7vFehTAV3iKxl4zxZa7NY+wfRd9kFhrr/2myIp6pOgBFl+hC+HoBIc
20
+JAyIxf5M3GNAWOpH6MfojYmzV7/qktu8l8BcJGplk0t+hVsDtMUze4nFAqZCXBpH
21
+Kw2M7bjyuZ78H/rgu6TcVUECgYEAo1M5ldE2U/VCApeuLX1TfWDpU8i1uK0zv3d5
22
+oLKkT1i5KzTak3SEO9HgC1qf8PoS8tfUio26UICHe99rnHehOfivzEq+qNdgyF+A
23
+M3BoeZMdgzcL5oh640k+Zte4LtDlddcWdhUhCepD7iPYrNNbQ3pkBwL2a9lRuOxc
24
+7OC2IPECgYBH8f3OrwXjDltIG1dDvuDPNljxLZbFEFbQyVzMePYNftgZknAyGEdh
25
+NW/LuWeTzstnmz/s6RE3jN5ZrrMa4sW77VA9+yU9QW2dkHqFyukQ4sfuNg6kDDNZ
26
++lqZYMCLw0M5P9fIbmnIYwey7tXkHfmzoCpnYHGQDN6hL0Bh0zGwmg==
27
+-----END RSA PRIVATE KEY-----
caddytest/caddytest.go
+13
-4
@@ -45,6 +45,11 @@ type configLoadError struct {
45
46
func (e configLoadError) Error() string { return e.Response }
47
48
+func timeElapsed(start time.Time, name string) {
49
+ elapsed := time.Since(start)
50
+ log.Printf("%s took %s", name, elapsed)
51
+}
52
+
53
// InitServer this will configure the server with a configurion of a specific
54
// type. The configType must be either "json" or the adapter type.
55
func InitServer(t *testing.T, rawConfig string, configType string) {
@@ -83,6 +88,8 @@ func initServer(t *testing.T, rawConfig string, configType string) error {
88
client := &http.Client{
89
Timeout: time.Second * 2,
90
}
91
+
92
+ start := time.Now()
93
req, err := http.NewRequest("POST", fmt.Sprintf("http://localhost:%d/load", Default.AdminPort), strings.NewReader(rawConfig))
94
if err != nil {
95
t.Errorf("failed to create request. %s", err)
@@ -100,6 +107,8 @@ func initServer(t *testing.T, rawConfig string, configType string) error {
107
t.Errorf("unable to contact caddy server. %s", err)
108
return err
109
}
110
+ timeElapsed(start, "caddytest: config load time")
111
+
112
defer res.Body.Close()
113
body, err := ioutil.ReadAll(res.Body)
114
if err != nil {
@@ -208,7 +217,7 @@ func AssertLoadError(t *testing.T, rawConfig string, configType string, expected
217
func AssertGetResponse(t *testing.T, requestURI string, statusCode int, expectedBody string) (*http.Response, string) {
218
resp, body := AssertGetResponseBody(t, requestURI, statusCode)
219
if !strings.Contains(body, expectedBody) {
211
- t.Errorf("expected response body \"%s\" but got \"%s\"", expectedBody, body)
220
+ t.Errorf("requesting \"%s\" expected response body \"%s\" but got \"%s\"", requestURI, expectedBody, body)
221
}
222
return resp, string(body)
223
}
@@ -229,7 +238,7 @@ func AssertGetResponseBody(t *testing.T, requestURI string, expectedStatusCode i
238
defer resp.Body.Close()
239
240
if expectedStatusCode != resp.StatusCode {
232
- t.Errorf("expected status code: %d but got %d", expectedStatusCode, resp.StatusCode)
241
+ t.Errorf("requesting \"%s\" expected status code: %d but got %d", requestURI, expectedStatusCode, resp.StatusCode)
242
}
243
244
body, err := ioutil.ReadAll(resp.Body)
@@ -260,12 +269,12 @@ func AssertRedirect(t *testing.T, requestURI string, expectedToLocation string,
269
}
270
271
if expectedStatusCode != resp.StatusCode {
263
- t.Errorf("expected status code: %d but got %d", expectedStatusCode, resp.StatusCode)
272
+ t.Errorf("requesting \"%s\" expected status code: %d but got %d", requestURI, expectedStatusCode, resp.StatusCode)
273
}
274
275
loc, err := resp.Location()
276
if expectedToLocation != loc.String() {
268
- t.Errorf("expected location: \"%s\" but got \"%s\"", expectedToLocation, loc.String())
277
+ t.Errorf("requesting \"%s\" expected location: \"%s\" but got \"%s\"", requestURI, expectedToLocation, loc.String())
278
}
279
280
return resp
caddytest/integration/caddyfile_test.go
+52
-7
@@ -17,13 +17,13 @@ func TestRespond(t *testing.T) {
17
18
localhost:9080 {
19
respond /version 200 {
20
- body "hello from a.caddy.localhost"
20
+ body "hello from localhost"
21
}
22
}
23
`, "caddyfile")
24
25
// act and assert
26
- caddytest.AssertGetResponse(t, "http://localhost:9080/version", 200, "hello from a.caddy.localhost")
26
+ caddytest.AssertGetResponse(t, "http://localhost:9080/version", 200, "hello from localhost")
27
}
28
29
func TestRedirect(t *testing.T) {
@@ -40,7 +40,7 @@ func TestRedirect(t *testing.T) {
40
redir / http://localhost:9080/hello 301
41
42
respond /hello 200 {
43
- body "hello from b"
43
+ body "hello from localhost"
44
}
45
}
46
`, "caddyfile")
@@ -49,7 +49,7 @@ func TestRedirect(t *testing.T) {
49
caddytest.AssertRedirect(t, "http://localhost:9080/", "http://localhost:9080/hello", 301)
50
51
// follow redirect
52
- caddytest.AssertGetResponse(t, "http://localhost:9080/", 200, "hello from b")
52
+ caddytest.AssertGetResponse(t, "http://localhost:9080/", 200, "hello from localhost")
53
}
54
55
func TestDuplicateHosts(t *testing.T) {
@@ -78,8 +78,52 @@ func TestDefaultSNI(t *testing.T) {
78
}
79
80
127.0.0.1:9443 {
81
- tls /caddy.localhost.crt /caddy.localhost.key {
82
- }
81
+ tls /caddy.localhost.crt /caddy.localhost.key
82
+ respond /version 200 {
83
+ body "hello from a"
84
+ }
85
+ }
86
+ `, "caddyfile")
87
+
88
+ // act and assert
89
+ caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a")
90
+}
91
+
92
+func TestDefaultSNIWithNamedHostAndExplicitIP(t *testing.T) {
93
+
94
+ // arrange
95
+ caddytest.InitServer(t, `
96
+ {
97
+ http_port 9080
98
+ https_port 9443
99
+ default_sni a.caddy.localhost
100
+ }
101
+
102
+ a.caddy.localhost:9443, 127.0.0.1:9443 {
103
+ tls /a.caddy.localhost.crt /a.caddy.localhost.key
104
+ respond /version 200 {
105
+ body "hello from a"
106
+ }
107
+ }
108
+ `, "caddyfile")
109
+
110
+ // act and assert
111
+ // makes a request with no sni
112
+ caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a")
113
+}
114
+
115
+func TestDefaultSNIWithPortMappingOnly(t *testing.T) {
116
+
117
+ // arrange
118
+ caddytest.InitServer(t, `
119
+ {
120
+ http_port 9080
121
+ https_port 9443
122
+ default_sni a.caddy.localhost
123
+ }
124
+
125
+ :9443 {
126
+ tls /a.caddy.localhost.crt /a.caddy.localhost.key
127
respond /version 200 {
128
body "hello from a.caddy.localhost"
129
}
@@ -87,5 +131,6 @@ func TestDefaultSNI(t *testing.T) {
131
`, "caddyfile")
132
133
// act and assert
90
- caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a.caddy.localhost")
134
+ // makes a request with no sni
135
+ caddytest.AssertGetResponse(t, "https://127.0.0.1:9443/version", 200, "hello from a")
136
}