Skip to content

Commit 996bc0c

Browse files
dtomcejunrolled
authored andcommitted
Add SSLHost logic to ModifyResponseHeaders() (#62)
* add SSLHost logic * add empty SSLHost * update match criteria
1 parent 232c938 commit 996bc0c

File tree

2 files changed

+106
-4
lines changed

2 files changed

+106
-4
lines changed

secure.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,15 @@ func (s *Secure) isSSL(r *http.Request) bool {
437437
// Used by http.ReverseProxy.
438438
func (s *Secure) ModifyResponseHeaders(res *http.Response) error {
439439
if res != nil && res.Request != nil {
440-
// Fix Location response header http to https when SSL is enabled.
440+
// Fix Location response header http to https:
441+
// When SSL is enabled,
442+
// And SSLHost is defined,
443+
// And the response location header includes the SSLHost as the domain with a trailing slash,
444+
// Or an exact match to the SSLHost.
441445
location := res.Header.Get("Location")
442-
if s.isSSL(res.Request) && strings.Contains(location, "http:") {
446+
if s.isSSL(res.Request) &&
447+
len(s.opt.SSLHost) > 0 &&
448+
(strings.HasPrefix(location, fmt.Sprintf("http://%s/", s.opt.SSLHost)) || location == fmt.Sprintf("http://%s", s.opt.SSLHost)) {
443449
location = strings.Replace(location, "http:", "https:", 1)
444450
res.Header.Set("Location", location)
445451
}

secure_test.go

+98-2
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,31 @@ func TestModifyResponseHeadersNoSSL(t *testing.T) {
12511251
expect(t, res.Header.Get("Location"), "http://example.com")
12521252
}
12531253

1254-
func TestModifyResponseHeadersWithSSL(t *testing.T) {
1254+
func TestModifyResponseHeadersWithSSLAndDifferentSSLHost(t *testing.T) {
1255+
s := New(Options{
1256+
SSLRedirect: true,
1257+
SSLHost: "secure.example.com",
1258+
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
1259+
})
1260+
1261+
req, _ := http.NewRequest("GET", "/foo", nil)
1262+
req.Host = "www.example.com"
1263+
req.URL.Scheme = "http"
1264+
req.Header.Add("X-Forwarded-Proto", "https")
1265+
1266+
res := &http.Response{}
1267+
res.Header = http.Header{"Location": []string{"http://example.com"}}
1268+
res.Request = req
1269+
1270+
expect(t, res.Header.Get("Location"), "http://example.com")
1271+
1272+
err := s.ModifyResponseHeaders(res)
1273+
expect(t, err, nil)
1274+
1275+
expect(t, res.Header.Get("Location"), "http://example.com")
1276+
}
1277+
1278+
func TestModifyResponseHeadersWithSSLAndNoSSLHost(t *testing.T) {
12551279
s := New(Options{
12561280
SSLRedirect: true,
12571281
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
@@ -1271,7 +1295,79 @@ func TestModifyResponseHeadersWithSSL(t *testing.T) {
12711295
err := s.ModifyResponseHeaders(res)
12721296
expect(t, err, nil)
12731297

1274-
expect(t, res.Header.Get("Location"), "https://example.com")
1298+
expect(t, res.Header.Get("Location"), "http://example.com")
1299+
}
1300+
1301+
func TestModifyResponseHeadersWithSSLAndMatchingSSLHost(t *testing.T) {
1302+
s := New(Options{
1303+
SSLRedirect: true,
1304+
SSLHost: "secure.example.com",
1305+
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
1306+
})
1307+
1308+
req, _ := http.NewRequest("GET", "/foo", nil)
1309+
req.Host = "www.example.com"
1310+
req.URL.Scheme = "http"
1311+
req.Header.Add("X-Forwarded-Proto", "https")
1312+
1313+
res := &http.Response{}
1314+
res.Header = http.Header{"Location": []string{"http://secure.example.com"}}
1315+
res.Request = req
1316+
1317+
expect(t, res.Header.Get("Location"), "http://secure.example.com")
1318+
1319+
err := s.ModifyResponseHeaders(res)
1320+
expect(t, err, nil)
1321+
1322+
expect(t, res.Header.Get("Location"), "https://secure.example.com")
1323+
}
1324+
1325+
func TestModifyResponseHeadersWithSSLAndPortInLocationResponse(t *testing.T) {
1326+
s := New(Options{
1327+
SSLRedirect: true,
1328+
SSLHost: "secure.example.com",
1329+
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
1330+
})
1331+
1332+
req, _ := http.NewRequest("GET", "/foo", nil)
1333+
req.Host = "www.example.com"
1334+
req.URL.Scheme = "http"
1335+
req.Header.Add("X-Forwarded-Proto", "https")
1336+
1337+
res := &http.Response{}
1338+
res.Header = http.Header{"Location": []string{"http://secure.example.com:877"}}
1339+
res.Request = req
1340+
1341+
expect(t, res.Header.Get("Location"), "http://secure.example.com:877")
1342+
1343+
err := s.ModifyResponseHeaders(res)
1344+
expect(t, err, nil)
1345+
1346+
expect(t, res.Header.Get("Location"), "http://secure.example.com:877")
1347+
}
1348+
1349+
func TestModifyResponseHeadersWithSSLAndPathInLocationResponse(t *testing.T) {
1350+
s := New(Options{
1351+
SSLRedirect: true,
1352+
SSLHost: "secure.example.com",
1353+
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
1354+
})
1355+
1356+
req, _ := http.NewRequest("GET", "/foo", nil)
1357+
req.Host = "www.example.com"
1358+
req.URL.Scheme = "http"
1359+
req.Header.Add("X-Forwarded-Proto", "https")
1360+
1361+
res := &http.Response{}
1362+
res.Header = http.Header{"Location": []string{"http://secure.example.com/admin/login"}}
1363+
res.Request = req
1364+
1365+
expect(t, res.Header.Get("Location"), "http://secure.example.com/admin/login")
1366+
1367+
err := s.ModifyResponseHeaders(res)
1368+
expect(t, err, nil)
1369+
1370+
expect(t, res.Header.Get("Location"), "https://secure.example.com/admin/login")
12751371
}
12761372

12771373
/* Test Helpers */

0 commit comments

Comments
 (0)