diff options
Diffstat (limited to 'echo')
-rw-r--r-- | echo/echo_default.go | 2 | ||||
-rw-r--r-- | echo/middleware/https_redirect.go (renamed from echo/middleware/redirect.go) | 2 | ||||
-rw-r--r-- | echo/middleware/www_redirect.go | 77 |
3 files changed, 79 insertions, 2 deletions
diff --git a/echo/echo_default.go b/echo/echo_default.go index 067e52f..916cbd0 100644 --- a/echo/echo_default.go +++ b/echo/echo_default.go | |||
@@ -306,7 +306,7 @@ func (w *EchoWrapper) configureRedirects(c *EchoConfig, bindings *AddressPortCon | |||
306 | })) | 306 | })) |
307 | 307 | ||
308 | if c.RedirectToWWW { | 308 | if c.RedirectToWWW { |
309 | w.Use(middleware.WWWRedirectWithConfig(middleware.RedirectConfig{ | 309 | w.Use(glmw.WWWRedirectWithConfig(glmw.WWWRedirectConfig{ |
310 | Skipper: metricsSkipper, | 310 | Skipper: metricsSkipper, |
311 | })) | 311 | })) |
312 | } | 312 | } |
diff --git a/echo/middleware/redirect.go b/echo/middleware/https_redirect.go index 134bfee..311f1c9 100644 --- a/echo/middleware/redirect.go +++ b/echo/middleware/https_redirect.go | |||
@@ -69,7 +69,7 @@ func HTTPSRedirectWithConfig(config HTTPSRedirectConfig) echo.MiddlewareFunc { | |||
69 | redir = fmt.Sprintf("https://%s:%d%s", host, config.Port, req.RequestURI) | 69 | redir = fmt.Sprintf("https://%s:%d%s", host, config.Port, req.RequestURI) |
70 | } | 70 | } |
71 | 71 | ||
72 | return c.Redirect(http.StatusMovedPermanently, redir) | 72 | return c.Redirect(config.Code, redir) |
73 | } | 73 | } |
74 | } | 74 | } |
75 | } | 75 | } |
diff --git a/echo/middleware/www_redirect.go b/echo/middleware/www_redirect.go new file mode 100644 index 0000000..905a5cf --- /dev/null +++ b/echo/middleware/www_redirect.go | |||
@@ -0,0 +1,77 @@ | |||
1 | package middleware | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "net" | ||
6 | "net/http" | ||
7 | "strings" | ||
8 | |||
9 | "github.com/labstack/echo/v4" | ||
10 | "github.com/labstack/echo/v4/middleware" | ||
11 | ) | ||
12 | |||
13 | /* | ||
14 | WWW Redirect Middleware | ||
15 | |||
16 | This is a duplicate of existing functionality in Echo. This exists | ||
17 | because we don't want to prefix www to a request that is an IP address | ||
18 | only, only requests that use hostnames. | ||
19 | */ | ||
20 | |||
21 | type WWWRedirectConfig struct { | ||
22 | Skipper middleware.Skipper | ||
23 | Code int | ||
24 | } | ||
25 | |||
26 | var DefaultWWWRedirectConfig = WWWRedirectConfig{ | ||
27 | Skipper: middleware.DefaultSkipper, | ||
28 | Code: http.StatusMovedPermanently, | ||
29 | } | ||
30 | |||
31 | func WWWRedirect() echo.MiddlewareFunc { | ||
32 | return WWWRedirectWithConfig(DefaultWWWRedirectConfig) | ||
33 | } | ||
34 | |||
35 | func WWWRedirectWithConfig(config WWWRedirectConfig) echo.MiddlewareFunc { | ||
36 | if config.Skipper == nil { | ||
37 | config.Skipper = DefaultWWWRedirectConfig.Skipper | ||
38 | } | ||
39 | if config.Code == 0 { | ||
40 | config.Code = DefaultWWWRedirectConfig.Code | ||
41 | } | ||
42 | |||
43 | return func(next echo.HandlerFunc) echo.HandlerFunc { | ||
44 | return func(c echo.Context) error { | ||
45 | req := c.Request() | ||
46 | |||
47 | if config.Skipper(c) || strings.HasPrefix(req.Host, "www.") { | ||
48 | return next(c) | ||
49 | } | ||
50 | |||
51 | host, _, err := net.SplitHostPort(req.Host) | ||
52 | if err != nil { | ||
53 | return echo.ErrBadRequest | ||
54 | } | ||
55 | |||
56 | // Never prefix an IP with www | ||
57 | // | ||
58 | // We have to parse the hostname for something that looks like an IP | ||
59 | // because the golang http server removes the header from the header | ||
60 | // map and there's no good way to unambiguously determine if this was | ||
61 | // a raw IP request or if a hostname was submitted. | ||
62 | // | ||
63 | // TLS connections could use the req.TLS.ServerName property which | ||
64 | // should have the correct hostname but there's no such thing for HTTP. | ||
65 | // Instead we just try to parse anything that makes it to this point | ||
66 | // because it should be a small one-time cost for a few requests. | ||
67 | if ip := net.ParseIP(host); ip != nil { | ||
68 | return next(c) | ||
69 | } | ||
70 | |||
71 | return c.Redirect( | ||
72 | config.Code, | ||
73 | fmt.Sprintf("https://www.%s%s", req.Host, req.RequestURI), | ||
74 | ) | ||
75 | } | ||
76 | } | ||
77 | } | ||