-
Notifications
You must be signed in to change notification settings - Fork 501
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
The Proxy filter lost all response headers set by other filters(eg: CORSAdaptor) before it #713
Comments
@suchen-sci @localvar The solution does not solve the response headers loss problem completely. It only handle the CORS response headers. But there are also other headers loss problem, let me clarify: in our business scene, we have a GlobalFilter before Proxy filter. In this GlobalFilter we need to judge if a JWT token in user cookie is nearly expired, If it is, we need to refresh user cookies by setting multi Set-Cookie response headers. After Proxy filters handling, the Set-Cookie response headers will be lost. So I think we should have a common solution for all response headers as following code,not just for special headers. The current solution code block if r, _ := spCtx.GetOutputResponse().(*httpprot.Response); r != nil {
copyCORSHeaders(resp.HTTPHeader(), r.HTTPHeader())
//omit some lines
} maybe should change as following if r, _ := spCtx.GetOutputResponse().(*httpprot.Response); r != nil {
for k, v := range r.HTTPHeader() {
for _, vv := range v {
if strings.HasPrefix(k, "Access-Control-Allow-") {
resp.Header().Set(k, vv)
} else {
resp.Header().Add(k, vv)
}
}
}
} Note that two nested for loop is to handle same Header names like multi Set-Cookie,the if judgement |
@jthann , got the idea. but we still need to consider these items:
any comments? |
Maybe there are two cases here:
In first case, I think we should not copy the headers. In second case, we should copy the response. Since we provide multiple namespaces, so in practice, first case should not exist. User should use different namespaces for different responses. So we only need to take care about second case, where we should simply copy all headers. Any idea here? |
@suchen-sci agree, but we still need to consider the 3 issues I mentioned before, simply copying all headers may be incorrect. |
@localvar my naive opinions about the 3 issues are:
|
@suchen-sci for the 2nd, I think And notice another issue in the |
@localvar For the 2nd issue,always call |
@jthann @suchen-sci for example: at first, header and you can find a example of multiple namespaces at: #539 (comment) |
@localvar @suchen-sci I just investigate some other gateways and do analysis about how they handle this problem. First /**
* Headers to remove as the result of applying the filter.
*/
public static final Set<String> HEADERS_REMOVED_ON_REQUEST = new HashSet<>(
Arrays.asList("connection", "keep-alive", "transfer-encoding", "te",
"trailer", "proxy-authorization", "proxy-authenticate",
"x-application-context", "upgrade"
// these two are not listed in
// https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3
// "proxy-connection",
// "content-length",
)); It also provides the interface: org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter. Second Third So based on above analysis, the conclusion is that there is not a default solution that will meet all requirements. |
Thanks for the detailed investigation, we will follow your proposal to fix the issue:
|
hi @jthann , my new PR (#727) keeps all the headers of the existing response, largely following the go reverse proxy example at: https://github.com/golang/go/blob/95b68e1e02fa713719f02f6c59fb1532bd05e824/src/net/http/httputil/reverseproxy.go but I haven't added a configuration to let users determine headers they want to discard, I'd like to wait until some users ask for it, I think this could help us to understand the requirement better. |
@localvar Yeah,the solution is okay,Easegress as a platform should solve the most common user requirements and provide a solid foundation for custom development easily. In addition to response headers,there are also request headers cases,for example in microservice authentication,we don't expect request So under this case,Easegress may provide a configuration item to support which sensitive headers to be ignored and not transferred to backend services. |
@jthann , ignore request/response headers are already supported by using a |
Describe the bug
In Easegress v2.0.0,the Proxy filter will lost all response headers set by other filters. For example if using CORSAdaptor before Proxy filter,for simple cors request,it will set Vary Access-Control-Allow-Origin Access-Control-Allow-Credentials headers. All these headers will lost after Proxy filter handling. This will cause simple cors request cannot work properly when api and web page from different domain.
To Reproduce
Using following configuration under Easegress v2.0.0:(
echo-backend
service providing 9095 port is from Easegress examplefrontend
just use ResponseBuilder to build a html page containing javascript that send Cors request to api domain)Make sure adding following configuration to
/etc/hosts
file:Open up chrome web browser and access
http://frontend.work/
,after sending request tohttp://api.backend.work/api
by javascript in html,the browser will report error:CORS error MissingAllowOriginHeader
Expected behavior
The Proxy filter should reserve all response headers set by other filters configuring before it.
The text was updated successfully, but these errors were encountered: