Skip to content

Commit 2769113

Browse files
alexaandruvishr
authored andcommitted
Applied a little DRY to the redirect middleware (#1053)
1 parent 40cae83 commit 2769113

File tree

1 file changed

+55
-117
lines changed

1 file changed

+55
-117
lines changed

middleware/redirect.go

Lines changed: 55 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,28 @@ import (
66
"github.com/labstack/echo"
77
)
88

9-
type (
10-
// RedirectConfig defines the config for Redirect middleware.
11-
RedirectConfig struct {
12-
// Skipper defines a function to skip middleware.
13-
Skipper Skipper
14-
15-
// Status code to be used when redirecting the request.
16-
// Optional. Default value http.StatusMovedPermanently.
17-
Code int `yaml:"code"`
18-
}
19-
)
9+
// RedirectConfig defines the config for Redirect middleware.
10+
type RedirectConfig struct {
11+
// Skipper defines a function to skip middleware.
12+
Skipper
13+
14+
// Status code to be used when redirecting the request.
15+
// Optional. Default value http.StatusMovedPermanently.
16+
Code int `yaml:"code"`
17+
}
2018

21-
const (
22-
www = "www"
23-
)
19+
// redirectLogic represents a function that given a tls flag, host and uri
20+
// can both: 1) determine if redirect is needed (will set ok accordingly) and
21+
// 2) return the appropriate redirect url.
22+
type redirectLogic func(tls bool, scheme, host, uri string) (ok bool, url string)
2423

25-
var (
26-
// DefaultRedirectConfig is the default Redirect middleware config.
27-
DefaultRedirectConfig = RedirectConfig{
28-
Skipper: DefaultSkipper,
29-
Code: http.StatusMovedPermanently,
30-
}
31-
)
24+
const www = "www"
25+
26+
// DefaultRedirectConfig is the default Redirect middleware config.
27+
var DefaultRedirectConfig = RedirectConfig{
28+
Skipper: DefaultSkipper,
29+
Code: http.StatusMovedPermanently,
30+
}
3231

3332
// HTTPSRedirect redirects http requests to https.
3433
// For example, http://labstack.com will be redirect to https://labstack.com.
@@ -41,29 +40,12 @@ func HTTPSRedirect() echo.MiddlewareFunc {
4140
// HTTPSRedirectWithConfig returns an HTTPSRedirect middleware with config.
4241
// See `HTTPSRedirect()`.
4342
func HTTPSRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
44-
// Defaults
45-
if config.Skipper == nil {
46-
config.Skipper = DefaultTrailingSlashConfig.Skipper
47-
}
48-
if config.Code == 0 {
49-
config.Code = DefaultRedirectConfig.Code
50-
}
51-
52-
return func(next echo.HandlerFunc) echo.HandlerFunc {
53-
return func(c echo.Context) error {
54-
if config.Skipper(c) {
55-
return next(c)
56-
}
57-
58-
req := c.Request()
59-
host := req.Host
60-
uri := req.RequestURI
61-
if !c.IsTLS() {
62-
return c.Redirect(config.Code, "https://"+host+uri)
63-
}
64-
return next(c)
43+
return redirect(config, func(isTLS bool, _, host, uri string) (ok bool, url string) {
44+
if ok = !isTLS; ok {
45+
url = "https://" + host + uri
6546
}
66-
}
47+
return
48+
})
6749
}
6850

6951
// HTTPSWWWRedirect redirects http requests to https www.
@@ -77,29 +59,12 @@ func HTTPSWWWRedirect() echo.MiddlewareFunc {
7759
// HTTPSWWWRedirectWithConfig returns an HTTPSRedirect middleware with config.
7860
// See `HTTPSWWWRedirect()`.
7961
func HTTPSWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
80-
// Defaults
81-
if config.Skipper == nil {
82-
config.Skipper = DefaultTrailingSlashConfig.Skipper
83-
}
84-
if config.Code == 0 {
85-
config.Code = DefaultRedirectConfig.Code
86-
}
87-
88-
return func(next echo.HandlerFunc) echo.HandlerFunc {
89-
return func(c echo.Context) error {
90-
if config.Skipper(c) {
91-
return next(c)
92-
}
93-
94-
req := c.Request()
95-
host := req.Host
96-
uri := req.RequestURI
97-
if !c.IsTLS() && host[:3] != www {
98-
return c.Redirect(config.Code, "https://www."+host+uri)
99-
}
100-
return next(c)
62+
return redirect(config, func(isTLS bool, _, host, uri string) (ok bool, url string) {
63+
if ok = !isTLS && host[:3] != www; ok {
64+
url = "https://www." + host + uri
10165
}
102-
}
66+
return
67+
})
10368
}
10469

10570
// HTTPSNonWWWRedirect redirects http requests to https non www.
@@ -113,32 +78,15 @@ func HTTPSNonWWWRedirect() echo.MiddlewareFunc {
11378
// HTTPSNonWWWRedirectWithConfig returns an HTTPSRedirect middleware with config.
11479
// See `HTTPSNonWWWRedirect()`.
11580
func HTTPSNonWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
116-
// Defaults
117-
if config.Skipper == nil {
118-
config.Skipper = DefaultTrailingSlashConfig.Skipper
119-
}
120-
if config.Code == 0 {
121-
config.Code = DefaultRedirectConfig.Code
122-
}
123-
124-
return func(next echo.HandlerFunc) echo.HandlerFunc {
125-
return func(c echo.Context) error {
126-
if config.Skipper(c) {
127-
return next(c)
128-
}
129-
130-
req := c.Request()
131-
host := req.Host
132-
uri := req.RequestURI
133-
if !c.IsTLS() {
134-
if host[:3] == www {
135-
return c.Redirect(config.Code, "https://"+host[4:]+uri)
136-
}
137-
return c.Redirect(config.Code, "https://"+host+uri)
81+
return redirect(config, func(isTLS bool, _, host, uri string) (ok bool, url string) {
82+
if ok = !isTLS; ok {
83+
if host[:3] == www {
84+
host = host[4:]
13885
}
139-
return next(c)
86+
url = "https://" + host + uri
14087
}
141-
}
88+
return
89+
})
14290
}
14391

14492
// WWWRedirect redirects non www requests to www.
@@ -152,30 +100,12 @@ func WWWRedirect() echo.MiddlewareFunc {
152100
// WWWRedirectWithConfig returns an HTTPSRedirect middleware with config.
153101
// See `WWWRedirect()`.
154102
func WWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
155-
// Defaults
156-
if config.Skipper == nil {
157-
config.Skipper = DefaultTrailingSlashConfig.Skipper
158-
}
159-
if config.Code == 0 {
160-
config.Code = DefaultRedirectConfig.Code
161-
}
162-
163-
return func(next echo.HandlerFunc) echo.HandlerFunc {
164-
return func(c echo.Context) error {
165-
if config.Skipper(c) {
166-
return next(c)
167-
}
168-
169-
req := c.Request()
170-
scheme := c.Scheme()
171-
host := req.Host
172-
if host[:3] != www {
173-
uri := req.RequestURI
174-
return c.Redirect(config.Code, scheme+"://www."+host+uri)
175-
}
176-
return next(c)
103+
return redirect(config, func(_ bool, scheme, host, uri string) (ok bool, url string) {
104+
if ok = host[:3] != www; ok {
105+
url = scheme + "://www." + host + uri
177106
}
178-
}
107+
return
108+
})
179109
}
180110

181111
// NonWWWRedirect redirects www requests to non www.
@@ -189,6 +119,15 @@ func NonWWWRedirect() echo.MiddlewareFunc {
189119
// NonWWWRedirectWithConfig returns an HTTPSRedirect middleware with config.
190120
// See `NonWWWRedirect()`.
191121
func NonWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
122+
return redirect(config, func(isTLS bool, scheme, host, uri string) (ok bool, url string) {
123+
if ok = host[:3] == www; ok {
124+
url = scheme + "://" + host[4:] + uri
125+
}
126+
return
127+
})
128+
}
129+
130+
func redirect(config RedirectConfig, cb redirectLogic) echo.MiddlewareFunc {
192131
if config.Skipper == nil {
193132
config.Skipper = DefaultTrailingSlashConfig.Skipper
194133
}
@@ -202,13 +141,12 @@ func NonWWWRedirectWithConfig(config RedirectConfig) echo.MiddlewareFunc {
202141
return next(c)
203142
}
204143

205-
req := c.Request()
206-
scheme := c.Scheme()
144+
req, scheme := c.Request(), c.Scheme()
207145
host := req.Host
208-
if host[:3] == www {
209-
uri := req.RequestURI
210-
return c.Redirect(config.Code, scheme+"://"+host[4:]+uri)
146+
if ok, url := cb(c.IsTLS(), scheme, host, req.RequestURI); ok {
147+
return c.Redirect(config.Code, url)
211148
}
149+
212150
return next(c)
213151
}
214152
}

0 commit comments

Comments
 (0)