Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support set upstream host #1245

Merged
merged 1 commit into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions docs/07.Reference/7.02.Filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

- [Proxy](#proxy)
- [Health Check](#health-check)
- [Request Host](#request-host)
- [Configuration](#configuration)
- [Results](#results)
- [SimpleHTTPProxy](#simplehttpproxy)
Expand Down Expand Up @@ -248,6 +249,38 @@ pools:
type: contains
```

### Request Host

By default, if the client's request host is `example.com` and the pools.servers.url is IP-based, Easegress will forward the request to the backend with the host `example.com`. However, if `pools.servers.url` is a domain, such as `http://demo.com:9090`, Easegress will automatically update the request's host to `demo.com:9090` before sending it to the backend. To prevent this and retain the original client request host, use the `keepHost` option as shown below:

```yaml
kind: Proxy
name: proxy-example-3
pools:
- servers:
- url: http://demo.com:9090
keepHost: true
loadBalance:
policy: roundRobin
maxRedirection: 10
```

Conversely, if your `pools.servers.url` is IP-based and you prefer the backend request to use this IP, activate the `setUpstreamHost` option as illustrated below:

```yaml
kind: Proxy
name: proxy-example-4
pools:
- setUpstreamHost: true
servers:
- url: http://demo.com:9090
loadBalance:
policy: roundRobin
maxRedirection: 10
```

Note that `keepHost` takes precedence over `setUpstreamHost` because `keepHost` applies to individual servers, whereas `setUpstreamHost` affects the entire pool.

### Configuration
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
Expand Down Expand Up @@ -1746,6 +1779,7 @@ Rules to revise request header.
| circuitBreakerPolicy | string | CircuitBreaker policy name | No |
| failureCodes | []int | Proxy return result of failureCode when backend resposne's status code in failureCodes. The default value is 5xx | No |
| healthCheck | ProxyHealthCheckSpec | Health check. Full example with details in [Proxy Health Check](#health-check) | No |
| setUpstreamHost | bool | Set request host to the host of backend server url if true. Default is false. | No |


### proxy.Server
Expand Down
14 changes: 11 additions & 3 deletions pkg/filters/proxies/httpproxy/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func removeHopByHopHeaders(h http.Header) {
*/
}

func (spCtx *serverPoolContext) prepareRequest(svr *Server, ctx stdcontext.Context, mirror bool) error {
func (spCtx *serverPoolContext) prepareRequest(pool *ServerPool, svr *Server, ctx stdcontext.Context, mirror bool) error {
req := spCtx.req

u := req.Std().URL
Expand All @@ -154,6 +154,7 @@ func (spCtx *serverPoolContext) prepareRequest(svr *Server, ctx stdcontext.Conte
if err != nil {
return err
}
svrHost := stdr.Host

stdr.Header = req.HTTPHeader().Clone()
removeHopByHopHeaders(stdr.Header)
Expand All @@ -164,6 +165,13 @@ func (spCtx *serverPoolContext) prepareRequest(svr *Server, ctx stdcontext.Conte
stdr.Host = req.Host()
}

// set upstream host if server is explicitly told to set the host of the request.
// KeepHost has higher priority than SetUpstreamHost.
if pool.spec.SetUpstreamHost && !svr.KeepHost {
stdr.Host = svrHost
stdr.Header.Add("Host", svrHost)
}

if spCtx.span != nil {
spCtx.span.InjectHTTP(stdr)
}
Expand Down Expand Up @@ -352,7 +360,7 @@ func (sp *ServerPool) handleMirror(spCtx *serverPoolContext) {
return
}

err := spCtx.prepareRequest(svr, spCtx.req.Context(), true)
err := spCtx.prepareRequest(sp, svr, spCtx.req.Context(), true)
if err != nil {
logger.Errorf("%s: failed to prepare request: %v", sp.Name, err)
return
Expand Down Expand Up @@ -463,7 +471,7 @@ func (sp *ServerPool) doHandle(stdctx stdcontext.Context, spCtx *serverPoolConte
// prepare the request to send.
statResult := &gohttpstat.Result{}
stdctx = gohttpstat.WithHTTPStat(stdctx, statResult)
if err := spCtx.prepareRequest(svr, stdctx, false); err != nil {
if err := spCtx.prepareRequest(sp, svr, stdctx, false); err != nil {
logger.Errorf("%s: failed to prepare request: %v", sp.Name, err)
return serverPoolError{http.StatusInternalServerError, resultInternalError}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/filters/proxies/serverpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type ServerPoolBase struct {
type ServerPoolBaseSpec struct {
ServerTags []string `json:"serverTags,omitempty" jsonschema:"uniqueItems=true"`
Servers []*Server `json:"servers,omitempty"`
SetUpstreamHost bool `json:"setUpstreamHost,omitempty"`
ServiceRegistry string `json:"serviceRegistry,omitempty"`
ServiceName string `json:"serviceName,omitempty"`
LoadBalance *LoadBalanceSpec `json:"loadBalance,omitempty"`
Expand Down
Loading