Commit 1183d91c authored by Matt Holt's avatar Matt Holt Committed by GitHub

Merge pull request #1365 from tw4452852/1297

redirect: determine the FromScheme at runtime (#1297)
parents 463c9d9d eeb23a24
......@@ -34,13 +34,14 @@ func (rd Redirect) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
}
func schemeMatches(rule Rule, req *http.Request) bool {
return (rule.FromScheme == "https" && req.TLS != nil) ||
(rule.FromScheme != "https" && req.TLS == nil)
return (rule.FromScheme() == "https" && req.TLS != nil) ||
(rule.FromScheme() != "https" && req.TLS == nil)
}
// Rule describes an HTTP redirect rule.
type Rule struct {
FromScheme, FromPath, To string
FromScheme func() string
FromPath, To string
Code int
Meta bool
httpserver.RequestMatcher
......
......@@ -47,16 +47,16 @@ func TestRedirect(t *testing.T) {
return 0, nil
}),
Rules: []Rule{
{FromPath: "/from", To: "/to", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
{FromPath: "/a", To: "/b", Code: http.StatusTemporaryRedirect, RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "http" }, FromPath: "/from", To: "/to", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "http" }, FromPath: "/a", To: "/b", Code: http.StatusTemporaryRedirect, RequestMatcher: httpserver.IfMatcher{}},
// These http and https schemes would never actually be mixed in the same
// redirect rule with Caddy because http and https schemes have different listeners,
// so they don't share a redirect rule. So although these tests prove something
// impossible with Caddy, it's extra bulletproofing at very little cost.
{FromScheme: "http", FromPath: "/scheme", To: "https://localhost/scheme", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: "https", FromPath: "/scheme2", To: "http://localhost/scheme2", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: "", FromPath: "/scheme3", To: "https://localhost/scheme3", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "http" }, FromPath: "/scheme", To: "https://localhost/scheme", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "https" }, FromPath: "/scheme2", To: "http://localhost/scheme2", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "" }, FromPath: "/scheme3", To: "https://localhost/scheme3", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
},
}
......@@ -90,7 +90,7 @@ func TestRedirect(t *testing.T) {
func TestParametersRedirect(t *testing.T) {
re := Redirect{
Rules: []Rule{
{FromPath: "/", Meta: false, To: "http://example.com{uri}", RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "http" }, FromPath: "/", Meta: false, To: "http://example.com{uri}", RequestMatcher: httpserver.IfMatcher{}},
},
}
......@@ -108,7 +108,7 @@ func TestParametersRedirect(t *testing.T) {
re = Redirect{
Rules: []Rule{
{FromPath: "/", Meta: false, To: "http://example.com/a{path}?b=c&{query}", RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "http" }, FromPath: "/", Meta: false, To: "http://example.com/a{path}?b=c&{query}", RequestMatcher: httpserver.IfMatcher{}},
},
}
......@@ -127,8 +127,8 @@ func TestParametersRedirect(t *testing.T) {
func TestMetaRedirect(t *testing.T) {
re := Redirect{
Rules: []Rule{
{FromPath: "/whatever", Meta: true, To: "/something", RequestMatcher: httpserver.IfMatcher{}},
{FromPath: "/", Meta: true, To: "https://example.com/", RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "http" }, FromPath: "/whatever", Meta: true, To: "/something", RequestMatcher: httpserver.IfMatcher{}},
{FromScheme: func() string { return "http" }, FromPath: "/", Meta: true, To: "https://example.com/", RequestMatcher: httpserver.IfMatcher{}},
},
}
......
......@@ -34,10 +34,11 @@ func redirParse(c *caddy.Controller) ([]Rule, error) {
cfg := httpserver.GetConfig(c)
initRule := func(rule *Rule, defaultCode string, args []string) error {
rule.FromScheme = func() string {
if cfg.TLS.Enabled {
rule.FromScheme = "https"
} else {
rule.FromScheme = "http"
return "https"
}
return "http"
}
var (
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment