A simple HTTPS proxy server with Apache Camel
我正在尝试使用Apache Camel实现简单的HTTP代理服务。
我的代码如下所示:
1 2 | from("jetty:http://localhost:80?matchOnUriPrefix=true") .recipientList(simple("jetty:${in.header.CamelHttpUrl}?bridgeEndpoint=true&throwExceptionOnFailure=false&disableStreamCache=true")); |
从本质上讲,它是带有动态收件人列表以支持多个目的地的。我还必须添加
尽管如此,它似乎仍然有效。但仅适用于HTTP请求。当我尝试访问HTTPS站点时,总是得到404。
根据日志,码头组件似乎没有找到远程服务器。我不知道为什么。
1 2 3 4 5 6 7 | 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 |
我应该怎么做才能启用此HTTPS支持?标准的骆驼组件是否有可能?
编辑:
我设法将路线定义更新为不使用收件人列表。我不知道这是否可以改善性能(是吗?),但是感觉更好。当不使用
1 2 | from("jetty:http://localhost:80?matchOnUriPrefix=true") .to("http4:dummy?bridgeEndpoint=true&urlRewrite=#urlRewrite&throwExceptionOnFailure=false"); |
以及URL重写器实现:
1 2 3 4 5 6 7 8 9 10 11 | 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; } }; |
编辑2:
我可能应该提到我想拦截那些请求并读取/更改内容(实际上只是HTTP标头)。实际上,我想实现一个MITM代理。
编辑3:
我尝试用
1 2 | from("jetty:http://localhost:80?matchOnUriPrefix=true") .to("log:test") |
用作HTTP代理时,将记录该消息。当我用
我还尝试使用Netty-http组件获得类似结果(路由跟踪器记录了
关键是为码头定义一个处理程序,该处理程序将处理
1 | from("jetty:http://localhost:80?matchOnUriPrefix=true&handlers=#connectHandler") |
在这种情况下,
1 2 3 4 5 6 7 8 9 | class CustomConnectHandler extends ConnectHandler { @Override protected SocketChannel connect(HttpServletRequest request, String host, int port) throws IOException { SocketChannel channel = SocketChannel.open(); channel.socket().setTcpNoDelay(true); channel.socket().connect(new InetSocketAddress("localhost", 443), getConnectTimeout()); return channel; } } |
此端口连接到本地主机上的端口443,并在此处路由SSL数据。因此,我们需要从那里定义另一条路线:
1 | from("jetty:https://localhost:443?matchOnUriPrefix=true") |
(我们可以保留两条单独的路线,或者稍后通过使用SEDA组件将其加入)
要定义自定义SSL上下文参数(密钥库,信任库等),我们可以在端点上使用
接下来,我们需要更改URL。为此,我们用完整的URL填充URI标头(默认情况下仅为相对路径):
1 | .setHeader(Exchange.HTTP_URI, simple("${header.CamelHttpUrl}")) |
我们还需要删除PATH标头,因为HTTP4组件通过连接URI和PATH标头来构建最终URL:
1 | .removeHeader(Exchange.HTTP_PATH) |
最后,我们可以将消息转发到HTTP4组件。我们还应该设置
1 | .to("http4:dummy?throwExceptionOnFailure=false&httpClient.redirectsEnabled=false"); |
我希望这对希望使用Camel实现HTTPS代理并且像我一样挣扎的人们有所帮助。
在大多数计算机系统上,localhost解析为IP地址127.0.0.1
注意:-在使用Fiddler的情况下,这是有效的实现。***
1 2 3 4 5 6 | <camelContext id="context" xmlns="http://camel.apache.org/schema/spring"> <properties> <property key="http.proxyHost" value="127.0.0.1"/> <property key="http.proxyPort" value="8888"/> </properties> </camelContext> |