aboutsummaryrefslogtreecommitdiff
path: root/echo/middleware/redirect.go
blob: 134bfee70db8b14272572b165efeeb29642d22fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package middleware

/*
HTTP to HTTPS Redirect Middleware

This is a duplicate of existing functionality in Echo because the Echo default
middleware doesn't support redirecting to a different HTTPS port which is
needed in dev environments and some prod environments where the server runs on
an off-port.
*/

import (
	"fmt"
	"net"
	"net/http"

	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
)

type HTTPSRedirectConfig struct {
	Skipper middleware.Skipper
	Port    int
	Code    int
}

var DefaultHTTPSRedirectConfig = HTTPSRedirectConfig{
	Skipper: middleware.DefaultSkipper,
	Port:    443,
	Code:    http.StatusMovedPermanently,
}

func HTTPSRedirect() echo.MiddlewareFunc {
	return HTTPSRedirectWithConfig(DefaultHTTPSRedirectConfig)
}

func HTTPSRedirectWithConfig(config HTTPSRedirectConfig) echo.MiddlewareFunc {
	if config.Skipper == nil {
		config.Skipper = DefaultHTTPSRedirectConfig.Skipper
	}
	if config.Code == 0 {
		config.Code = DefaultHTTPSRedirectConfig.Code
	}
	if config.Port == 0 {
		config.Port = DefaultHTTPSRedirectConfig.Port
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.Skipper(c) || c.Scheme() == "https" {
				return next(c)
			}

			var err error
			req := c.Request()

			host := req.URL.Host
			if host == "" {
				host, _, err = net.SplitHostPort(req.Host)
				if err != nil {
					return echo.ErrBadRequest
				}
			}

			// Browers assume 443 if it's an https request, otherwise the port
			// needs to be specified in the URL
			redir := fmt.Sprintf("https://%s%s", host, req.RequestURI)
			if config.Port != 443 {
				redir = fmt.Sprintf("https://%s:%d%s", host, config.Port, req.RequestURI)
			}

			return c.Redirect(http.StatusMovedPermanently, redir)
		}
	}
}