ToMiddleware converts ProxyConfig to middleware or returns an error for invalid configuration
()
| 304 | |
| 305 | // ToMiddleware converts ProxyConfig to middleware or returns an error for invalid configuration |
| 306 | func (config ProxyConfig) ToMiddleware() (echo.MiddlewareFunc, error) { |
| 307 | if config.Skipper == nil { |
| 308 | config.Skipper = DefaultProxyConfig.Skipper |
| 309 | } |
| 310 | if config.ContextKey == "" { |
| 311 | config.ContextKey = DefaultProxyConfig.ContextKey |
| 312 | } |
| 313 | if config.Balancer == nil { |
| 314 | return nil, errors.New("echo proxy middleware requires balancer") |
| 315 | } |
| 316 | if config.RetryFilter == nil { |
| 317 | config.RetryFilter = func(c *echo.Context, e error) bool { |
| 318 | if httpErr, ok := e.(*echo.HTTPError); ok { |
| 319 | return httpErr.Code == http.StatusBadGateway |
| 320 | } |
| 321 | return false |
| 322 | } |
| 323 | } |
| 324 | if config.ErrorHandler == nil { |
| 325 | config.ErrorHandler = func(c *echo.Context, err error) error { |
| 326 | return err |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | if config.Rewrite != nil { |
| 331 | if config.RegexRewrite == nil { |
| 332 | config.RegexRewrite = make(map[*regexp.Regexp]string) |
| 333 | } |
| 334 | maps.Copy(config.RegexRewrite, rewriteRulesRegex(config.Rewrite)) |
| 335 | } |
| 336 | |
| 337 | return func(next echo.HandlerFunc) echo.HandlerFunc { |
| 338 | return func(c *echo.Context) (err error) { |
| 339 | if config.Skipper(c) { |
| 340 | return next(c) |
| 341 | } |
| 342 | |
| 343 | req := c.Request() |
| 344 | res := c.Response() |
| 345 | if err := rewriteURL(config.RegexRewrite, req); err != nil { |
| 346 | return config.ErrorHandler(c, err) |
| 347 | } |
| 348 | |
| 349 | // Fix header |
| 350 | // Basically it's not good practice to unconditionally pass incoming x-real-ip header to upstream. |
| 351 | // However, for backward compatibility, legacy behavior is preserved unless you configure Echo#IPExtractor. |
| 352 | if req.Header.Get(echo.HeaderXRealIP) == "" || c.Echo().IPExtractor != nil { |
| 353 | req.Header.Set(echo.HeaderXRealIP, c.RealIP()) |
| 354 | } |
| 355 | if req.Header.Get(echo.HeaderXForwardedProto) == "" { |
| 356 | req.Header.Set(echo.HeaderXForwardedProto, c.Scheme()) |
| 357 | } |
| 358 | if c.IsWebSocket() { // For HTTP, this is set by Go HTTP reverse proxy. |
| 359 | // Append, not set, to preserve the incoming chain from upstream proxies. |
| 360 | prior := req.Header[echo.HeaderXForwardedFor] |
| 361 | if len(prior) > 0 { |
| 362 | req.Header.Set(echo.HeaderXForwardedFor, strings.Join(prior, ", ")+", "+c.RealIP()) |
| 363 | } else { |
nothing calls this directly
no test coverage detected