Open jwgmeligmeyling opened 3 years ago
For now I cooked up the following partial solution:
public static class ProxyPassReverseConfigurer extends RequestForwardingInterceptorConfigurer<ProxyPassReverseRewriter> {
protected ProxyPassReverseConfigurer() {
super(new ProxyPassReverseRewriter());
}
public ProxyPassReverseConfigurer path(String path) {
this.configuredObject.setPath(path);
return this;
}
public static ProxyPassReverseConfigurer proxyPassReverseRewriter() {
return new ProxyPassReverseConfigurer();
}
}
public static class ProxyPassReverseRewriter implements RequestForwardingInterceptor {
private static final String HEADER_LOCATION = "Location";
private static final String HEADER_URI = "URI";
private static final String HEADER_CONTENT_LOCATION = "Content-Location";
private static final RequestForwardingInterceptorType RESPONSE_LOCATION_HEADER_REWRITER = new RequestForwardingInterceptorType(399);
private String path = "./";
public void setPath(String path) {
this.path = path;
}
@Override
public HttpResponse forward(HttpRequest request, HttpRequestExecution execution) {
URI originalRequestUri = request.getURI();
HttpResponse response = execution.execute(request);
HttpHeaders rewrittenHeaders = copyHeaders(response.getHeaders());
rewriteHeader(originalRequestUri, rewrittenHeaders, HEADER_LOCATION);
rewriteHeader(originalRequestUri, rewrittenHeaders, HEADER_URI);
rewriteHeader(originalRequestUri, rewrittenHeaders, HEADER_CONTENT_LOCATION);
response.setHeaders(rewrittenHeaders);
return response;
}
private void rewriteHeader(URI originalRequestUri , HttpHeaders rewrittenHeaders, String header) {
String headerValue = rewrittenHeaders.getFirst(header);
if (headerValue != null) {
URI uri = URI.create(headerValue);
if (uri.getPath().startsWith(path)) {
// Remove the context path from the redirect URI.
uri = UriComponentsBuilder.fromUri(uri).replacePath(uri.getPath().substring(path.length())).build().toUri();
}
rewrittenHeaders.set(header, uri.toASCIIString());
}
}
@Override
public RequestForwardingInterceptorType getType() {
return RESPONSE_LOCATION_HEADER_REWRITER;
}
}
Hi, currently there is no way to mimic ProxyPassReverse
directive in Charon (besides of what you have already done of course).
I've noticed that the ProxyPassReverse*
directives from Apache are not very flexible because of lack of regex rewriting support.
If ProxyPassReverse*
functionalities were to be added to Charon, I think they should work like regexRequestPathRewriter()
. So I can consider adding regexPathResponseCookiesRewriter()
and regexResponseLocationHeadersRewriter()
.
I'll try to cook up a patch based on your suggestions if I get to it.
Hi There,
i have a similar requirement to change a specific header that contains a location: "X-GWT-Module-Base" i've been trying to add the code from @jwgmeligmeyling but have not succeeded this far.
could you please explain where i connect your code snippet into my charonConfigurer?
I am trying to mimic the following Apache2 configuration with Charon:
I believe
ProxyPass
can be replaced byregexRequestPathRewriter()
andProxyPreserveHost
can be changed by including/excludingrequestHostHeaderRewriter
.It appears as if
rootPathResponseCookiesRewriter
can be used for theProxyPassReverseCookiePath
, however the paths that need to be placed and the path it needs to be changed into are not configurable. This could potentially be an interesting addition. Currently, replacing with root fulfills my needs, so I don't think I need this change right now.Finally I am seeking a replacement for
ProxyPassReverse
. This ensures Location, Content-Location and URI headers in the response are adjusted appropiately for the rewritten path. Is there a rewriter in Charon available that makes this possible?