I am trying to implement a simple HTTP proxy service with Apache Camel. My code looks like this:
from("jetty:http://localhost:80?matchOnUriPrefix=true")
.recipientList(simple("jetty:${in.header.CamelHttpUrl}?bridgeEndpoint=true&throwExceptionOnFailure=false&disableStreamCache=true"));
It is essentially this with a dynamic recipient list to support multiple destinations. I also had to add the disableStreamCache=true bit, otherwise I would get weird exceptions with path duplication (like /index.html would become /index.html/index.html).
Nevertheless, it seems to work. But only with HTTP requests. When I try accessing an HTTPS site, I always get a 404.
According to the logs, the jetty component just doesn't seem to find the remote server. I have no idea why.
01:36:37.495 [qtp85415531-22 - www.google.cz:443] DEBUG org.eclipse.jetty.server.Server - REQUEST www.google.cz:443 on AsyncHttpConnection@6964b063,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=-5,l=17,c=0},r=1
01:36:37.495 [qtp85415531-22 - www.google.cz:443] DEBUG o.e.j.server.handler.ContextHandler - scope null||www.google.cz:443 @ o.e.j.s.ServletContextHandler{/,null}
01:36:37.495 [qtp85415531-22 - www.google.cz:443] DEBUG o.e.j.server.handler.ContextHandler - context=null||www.google.cz:443 @ o.e.j.s.ServletContextHandler{/,null}
01:36:37.495 [qtp85415531-22 - www.google.cz:443] DEBUG o.e.jetty.servlet.ServletHandler - servlet null||www.google.cz:443 -> null
01:36:37.495 [qtp85415531-22 - www.google.cz:443] DEBUG o.e.jetty.servlet.ServletHandler - chain=null
01:36:37.495 [qtp85415531-22 - www.google.cz:443] DEBUG o.e.jetty.servlet.ServletHandler - Not Found www.google.cz:443
01:36:37.495 [qtp85415531-22 - www.google.cz:443] DEBUG org.eclipse.jetty.server.Server - RESPONSE www.google.cz:443 200 handled=false
What should I do to enable this HTTPS support? Is it even possible with standard Camel components?
Edit:
I managed to update my route definition to not use a recipient list. I don't know whether this improves anything performance-wise (does it?) but it feels better. I was also able to remove the path duplication problem when not using disableStreamCache=true by this.
from("jetty:http://localhost:80?matchOnUriPrefix=true")
.to("http4:dummy?bridgeEndpoint=true&urlRewrite=#urlRewrite&throwExceptionOnFailure=false");
And the URL rewriter implementation:
UrlRewrite urlRewrite = new HttpServletUrlRewrite() {
@Override
public String rewrite(String url, String relativeUrl, Producer producer, HttpServletRequest request) throws Exception {
return request.getRequestURL().toString();
}
@Override
public String rewrite(String url, String relativeUrl, Producer producer) throws Exception {
return null;
}
};
Edit 2:
I should probably mention that I would like to intercept those requests and read/alter content (actually only HTTP headers). In effect I would like to implement an MITM proxy.
Edit 3:
I tried replacing the target component with log to see whether the request gets through:
from("jetty:http://localhost:80?matchOnUriPrefix=true")
.to("log:test")
The message gets logged when used as a proxy with HTTP. It also gets logged when I replace the URI with jetty:https://localhost?matchOnUriPrefix=true and try opening https://localhost directly in the browser. However, when trying to use this as a proxy with HTTPS, I cannot get it to log. It seems like the Jetty component doesn't support this behavior. Is it correct?
I also tried using the Netty-http component with similar results (route tracer logged the CONNECT request but the message doesn't get passed to the Log component)