Skip to content

Commit 69f477b

Browse files
committed
refactor middlewares
1 parent 15edd3f commit 69f477b

File tree

8 files changed

+87
-104
lines changed

8 files changed

+87
-104
lines changed

context/keys/keys.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ package keys
22

33
import (
44
"context"
5+
"net/http"
6+
"strings"
7+
8+
"github.com/labstack/echo/v4"
9+
"github.com/webdevelop-pro/go-common/context/keys"
510
)
611

712
type ContextKey rune
@@ -14,8 +19,6 @@ const (
1419
IdentityID
1520
LogInfo
1621
RequestLogID
17-
LogObjectType
18-
LogObjectID
1922
)
2023

2124
func GetAsString(ctx context.Context, key ContextKey) string {
@@ -43,3 +46,36 @@ func SetCtxValues(ctx context.Context, values map[ContextKey]any) context.Contex
4346

4447
return ctx
4548
}
49+
50+
func GetIPAddress(headers http.Header) string {
51+
// ToDo
52+
// Use echo context.RealIP()
53+
ip := "127.0.0.1"
54+
if xOFF := headers.Get("X-Original-Forwarded-For"); xOFF != "" {
55+
i := strings.Index(xOFF, ", ")
56+
if i == -1 {
57+
i = len(xOFF)
58+
}
59+
ip = xOFF[:i]
60+
} else if xFF := headers.Get("X-Forwarded-For"); xFF != "" {
61+
i := strings.Index(xFF, ", ")
62+
if i == -1 {
63+
i = len(xFF)
64+
}
65+
ip = xFF[:i]
66+
} else if xrIP := headers.Get("X-Real-IP"); xrIP != "" {
67+
ip = xrIP
68+
}
69+
return ip
70+
}
71+
72+
// Set values in ctx for
73+
// RequestID, IPAddress
74+
func SetDefaultHTTPCtx(ctx context.Context, headers http.Header) context.Context {
75+
requestID := headers.Get(echo.HeaderXRequestID)
76+
IP := GetIPAddress(headers)
77+
78+
ctx = keys.SetCtxValue(ctx, keys.RequestID, requestID)
79+
ctx = keys.SetCtxValue(ctx, keys.IPAddress, IP)
80+
return ctx
81+
}

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
- [ ] eliminate go-echo-swagger, upload swagger files to docs.<domain>.com/service. Go-echo-swagger adds a lot of dependencies and slows down every request
66
- [ ] [server/middleware/ip_address.go#L18](use echo.RealIP()) instead of our custom code
77
- [ ] Set up proper middleware to get user ip address correctly, https://echo.labstack.com/docs/ip-address
8-
- [ ] create an ability to install each folder individually, similary to [pgtype](https://github.com/jackc/pgx/tree/master/pgtype). Cause right now if you need only `configurator` you will also install a lot of dependencies
8+
- [ ] move consts from keys/keys.go to the package where they used
99

server/config.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,7 @@
11
package server
22

3-
import (
4-
"github.com/labstack/echo/v4"
5-
echoMW "github.com/labstack/echo/v4/middleware"
6-
"github.com/webdevelop-pro/go-common/server/middleware"
7-
)
8-
93
// Config is struct to configure HTTP server
104
type Config struct {
115
Host string `required:"true"`
126
Port string `required:"true"`
137
}
14-
15-
func DefaultMiddlewares(middlewares ...echo.MiddlewareFunc) []echo.MiddlewareFunc {
16-
defaults := []echo.MiddlewareFunc{
17-
// Set context logger
18-
middleware.SetIPAddress,
19-
middleware.DefaultCTXValues,
20-
middleware.SetRequestTime,
21-
middleware.LogRequests,
22-
// Trace ID middleware generates a unique id for a request.
23-
echoMW.RequestIDWithConfig(echoMW.RequestIDConfig{
24-
RequestIDHandler: func(c echo.Context, requestID string) {
25-
c.Set(echo.HeaderXRequestID, requestID)
26-
},
27-
}),
28-
}
29-
if len(middlewares) > 0 {
30-
defaults = append(defaults, middlewares...)
31-
}
32-
return defaults
33-
}

server/http.go

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
echoMW "github.com/labstack/echo/v4/middleware"
1010
"github.com/labstack/gommon/log"
1111
"github.com/webdevelop-pro/go-common/configurator"
12+
"github.com/webdevelop-pro/go-common/context/keys"
1213
"github.com/webdevelop-pro/go-common/logger"
1314
"github.com/webdevelop-pro/go-common/validator"
1415
"go.uber.org/fx"
@@ -50,8 +51,18 @@ func (s *HTTPServer) AddRoute(route *route.Route) {
5051
s.Echo.Add(route.Method, route.Path, route.Handler, route.Middlewares...)
5152
}
5253

53-
// NewHTTPServer returns new API instance.
54-
func NewHTTPServer(e *echo.Echo, l logger.Logger, cfg *Config) *HTTPServer {
54+
// NewServer returns new API instance.
55+
func NewServer() *HTTPServer {
56+
var (
57+
cfg = &Config{}
58+
l = logger.NewComponentLogger(context.TODO(), component)
59+
)
60+
61+
if err := configurator.NewConfiguration(cfg); err != nil {
62+
l.Fatal().Err(err).Msg("failed to get configuration of server")
63+
}
64+
65+
e := echo.New()
5566
// sets CORS headers if Origin is present
5667
e.Use(
5768
echoMW.CORSWithConfig(echoMW.CORSConfig{
@@ -75,13 +86,6 @@ func NewHTTPServer(e *echo.Echo, l logger.Logger, cfg *Config) *HTTPServer {
7586
// get an instance of a validator
7687
e.Validator = validator.New()
7788

78-
// Add prometheus metrics
79-
e.Use(echoprometheus.NewMiddleware(component))
80-
e.GET("/metrics", echoprometheus.NewHandler())
81-
82-
// Set docs middleware
83-
// setDocsMiddleware(e)
84-
8589
// avoid any native logging of echo, because we use custom library for logging
8690
e.HideBanner = true // don't log the banner on startup
8791
e.HidePort = true // hide log about port server started on
@@ -94,17 +98,34 @@ func NewHTTPServer(e *echo.Echo, l logger.Logger, cfg *Config) *HTTPServer {
9498
}
9599
}
96100

97-
func New() *HTTPServer {
98-
var (
99-
cfg = &Config{}
100-
l = logger.NewComponentLogger(context.TODO(), component)
101-
)
101+
// NewServerWithMiddlewares returns new API instance with default middlewares
102+
func NewServerWithMiddlewares() *HTTPServer {
103+
server := NewServer()
104+
AddDefaultMiddlewares(server.Echo)
105+
AddPrometheus(server.Echo)
106+
return server
107+
}
102108

103-
if err := configurator.NewConfiguration(cfg); err != nil {
104-
l.Fatal().Err(err).Msg("failed to get configuration of server")
105-
}
109+
func AddPrometheus(e *echo.Echo) *echo.Echo {
110+
// Add prometheus metrics
111+
e.Use(echoprometheus.NewMiddleware(component))
112+
e.GET("/metrics", echoprometheus.NewHandler())
113+
}
106114

107-
return NewHTTPServer(echo.New(), l, cfg)
115+
func AddDefaultMiddlewares(e *echo.Echo) *echo.Echo {
116+
// Set context logger
117+
e.Use(middleware.SetIPAddress)
118+
e.Use(middleware.SetRequestTime)
119+
e.Use(middleware.LogRequests)
120+
// Trace ID middleware generates a unique id for a request.
121+
e.Use(echoMW.RequestIDWithConfig(echoMW.RequestIDConfig{
122+
RequestIDHandler: func(c echo.Context, requestID string) {
123+
c.Set(echo.HeaderXRequestID, requestID)
124+
125+
ctx := context.WithValue(c.Request().Context(), keys.RequestID, requestID)
126+
c.SetRequest(c.Request().WithContext(ctx))
127+
},
128+
}))
108129
}
109130

110131
// StartServer is function that registers start of http server in lifecycle

server/http_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func TestHTTPCtx(t *testing.T) {
2222
"X-Forwarded-For": {"31.6.1.12"},
2323
}
2424

25-
ctx = middleware.SetDefaultHTTPCtx(ctx, headers)
25+
ctx = keys.SetDefaultHTTPCtx(ctx, headers)
2626

2727
assert.Equal(t, headers["X-Request-Id"][0], keys.GetCtxValue(ctx, keys.RequestID))
2828
assert.Equal(t, headers["X-Forwarded-For"][0], keys.GetCtxValue(ctx, keys.IPAddress))

server/middleware/ctx.go

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,17 @@ package middleware
22

33
import (
44
"context"
5-
"net/http"
65

76
"github.com/labstack/echo/v4"
87
"github.com/webdevelop-pro/go-common/context/keys"
98
)
109

1110
func SetDefaultCTX(echoCtx echo.Context) context.Context {
12-
ctx := SetDefaultHTTPCtx(echoCtx.Request().Context(), echoCtx.Request().Header)
11+
ctx := keys.SetDefaultHTTPCtx(echoCtx.Request().Context(), echoCtx.Request().Header)
1312
if val, ok := ctx.Value(keys.RequestID).(string); ok && val == "" {
1413
if requestID, ok := echoCtx.Get(echo.HeaderXRequestID).(string); ok {
1514
ctx = keys.SetCtxValue(ctx, keys.RequestID, requestID)
1615
}
1716
}
1817
return ctx
1918
}
20-
21-
func SetDefaultHTTPCtx(ctx context.Context, headers http.Header) context.Context {
22-
requestID := headers.Get(echo.HeaderXRequestID)
23-
IP := GetIPAddress(headers)
24-
25-
ctx = keys.SetCtxValue(ctx, keys.RequestID, requestID)
26-
ctx = keys.SetCtxValue(ctx, keys.IPAddress, IP)
27-
return ctx
28-
}
29-
30-
// Set values in ctx for
31-
// RequestID, IPAddress
32-
func DefaultCTXValues(next echo.HandlerFunc) echo.HandlerFunc {
33-
return func(echoCtx echo.Context) error {
34-
ctx := SetDefaultCTX(echoCtx)
35-
echoCtx.SetRequest(echoCtx.Request().WithContext(ctx))
36-
37-
// next handler
38-
return next(echoCtx)
39-
}
40-
}

server/middleware/ip_address.go

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,19 @@
11
package middleware
22

33
import (
4-
"net/http"
5-
"strings"
4+
"context"
65

76
"github.com/labstack/echo/v4"
7+
"github.com/webdevelop-pro/go-common/context/keys"
88
)
99

10-
const (
11-
// ContextKey is the key used to lookup ip address
12-
// request from the echo.Context.
13-
IPAddressContextKey = "ip-address"
14-
)
15-
16-
func GetIPAddress(headers http.Header) string {
17-
// ToDo
18-
// Use echo context.RealIP()
19-
ip := "127.0.0.1"
20-
if xOFF := headers.Get("X-Original-Forwarded-For"); xOFF != "" {
21-
i := strings.Index(xOFF, ", ")
22-
if i == -1 {
23-
i = len(xOFF)
24-
}
25-
ip = xOFF[:i]
26-
} else if xFF := headers.Get("X-Forwarded-For"); xFF != "" {
27-
i := strings.Index(xFF, ", ")
28-
if i == -1 {
29-
i = len(xFF)
30-
}
31-
ip = xFF[:i]
32-
} else if xrIP := headers.Get("X-Real-IP"); xrIP != "" {
33-
ip = xrIP
34-
}
35-
return ip
36-
}
37-
3810
func SetIPAddress(next echo.HandlerFunc) echo.HandlerFunc {
3911
return func(c echo.Context) error {
40-
ip := GetIPAddress(c.Request().Header)
41-
c.Set(IPAddressContextKey, ip)
12+
ip := keys.GetIPAddress(c.Request().Header)
13+
c.Set(keys.IPAddress, ip)
4214

15+
ctx := context.WithValue(c.Request().Context(), keys.IPAddress, ip)
16+
c.SetRequest(c.Request().WithContext(ctx))
4317
return next(c)
4418
}
4519
}

server/middleware/logger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func SetLogger(next echo.HandlerFunc) echo.HandlerFunc {
1212
return func(c echo.Context) error {
1313
// get request's context
1414
ctx := c.Request().Context()
15-
ipAddress, _ := c.Get(IPAddressContextKey).(string)
15+
ipAddress, _ := c.Get(keys.IPAddress).(string)
1616
identityID, _ := keys.GetCtxValue(ctx, keys.IdentityID).(string)
1717
requestID, _ := keys.GetCtxValue(ctx, keys.RequestID).(string)
1818
msgID, _ := keys.GetCtxValue(ctx, keys.MSGID).(string)

0 commit comments

Comments
 (0)