Commit eeb23a24 authored by Tw's avatar Tw

redirect: determine the FromScheme at runtime (#1297)

Signed-off-by: default avatarTw <tw19881113@gmail.com>
parent ecf852ea
...@@ -34,15 +34,16 @@ func (rd Redirect) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error ...@@ -34,15 +34,16 @@ func (rd Redirect) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
} }
func schemeMatches(rule Rule, req *http.Request) bool { func schemeMatches(rule Rule, req *http.Request) bool {
return (rule.FromScheme == "https" && req.TLS != nil) || return (rule.FromScheme() == "https" && req.TLS != nil) ||
(rule.FromScheme != "https" && req.TLS == nil) (rule.FromScheme() != "https" && req.TLS == nil)
} }
// Rule describes an HTTP redirect rule. // Rule describes an HTTP redirect rule.
type Rule struct { type Rule struct {
FromScheme, FromPath, To string FromScheme func() string
Code int FromPath, To string
Meta bool Code int
Meta bool
httpserver.RequestMatcher httpserver.RequestMatcher
} }
......
...@@ -47,16 +47,16 @@ func TestRedirect(t *testing.T) { ...@@ -47,16 +47,16 @@ func TestRedirect(t *testing.T) {
return 0, nil return 0, nil
}), }),
Rules: []Rule{ Rules: []Rule{
{FromPath: "/from", To: "/to", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}}, {FromScheme: func() string { return "http" }, 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: "/a", To: "/b", Code: http.StatusTemporaryRedirect, RequestMatcher: httpserver.IfMatcher{}},
// These http and https schemes would never actually be mixed in the same // 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, // 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 // 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. // 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: func() string { return "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: func() string { return "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 "" }, FromPath: "/scheme3", To: "https://localhost/scheme3", Code: http.StatusMovedPermanently, RequestMatcher: httpserver.IfMatcher{}},
}, },
} }
...@@ -90,7 +90,7 @@ func TestRedirect(t *testing.T) { ...@@ -90,7 +90,7 @@ func TestRedirect(t *testing.T) {
func TestParametersRedirect(t *testing.T) { func TestParametersRedirect(t *testing.T) {
re := Redirect{ re := Redirect{
Rules: []Rule{ 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) { ...@@ -108,7 +108,7 @@ func TestParametersRedirect(t *testing.T) {
re = Redirect{ re = Redirect{
Rules: []Rule{ 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) { ...@@ -127,8 +127,8 @@ func TestParametersRedirect(t *testing.T) {
func TestMetaRedirect(t *testing.T) { func TestMetaRedirect(t *testing.T) {
re := Redirect{ re := Redirect{
Rules: []Rule{ Rules: []Rule{
{FromPath: "/whatever", Meta: true, To: "/something", RequestMatcher: httpserver.IfMatcher{}}, {FromScheme: func() string { return "http" }, 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: "/", Meta: true, To: "https://example.com/", RequestMatcher: httpserver.IfMatcher{}},
}, },
} }
......
...@@ -34,10 +34,11 @@ func redirParse(c *caddy.Controller) ([]Rule, error) { ...@@ -34,10 +34,11 @@ func redirParse(c *caddy.Controller) ([]Rule, error) {
cfg := httpserver.GetConfig(c) cfg := httpserver.GetConfig(c)
initRule := func(rule *Rule, defaultCode string, args []string) error { initRule := func(rule *Rule, defaultCode string, args []string) error {
if cfg.TLS.Enabled { rule.FromScheme = func() string {
rule.FromScheme = "https" if cfg.TLS.Enabled {
} else { return "https"
rule.FromScheme = "http" }
return "http"
} }
var ( 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