Java JUnit测试中如何搭建HTTP代理服务器以连接SFTP
Java JUnit测试中如何搭建HTTP代理服务器以连接SFTP
我明白你现在的困境:已经用Testcontainers搭好了SFTP测试服务器,但就是找不到合适的嵌入式HTTP代理来集成到JUnit测试里——之前试了MockServer、Wiremock都没成功,可本地的Squid代理却能正常支持SFTP通过HTTP代理的连接操作。下面给你几个可行的解决方案,都是能直接在Java测试代码里集成的:
1. 用Testcontainers运行Squid代理容器(最推荐)
既然你已经验证过Squid能完美支持你的场景,那直接把Squid容器化到测试流程里是最稳妥的选择,能保证测试环境和你本地验证的环境一致。
步骤:
- 首先,定义一个Squid的Testcontainer,你可以用官方的Squid镜像,或者自定义一个包含允许SFTP(22端口)CONNECT请求配置的镜像:
GenericContainer<?> squidProxy = new GenericContainer<>("sameersbn/squid:3.5.27") .withExposedPorts(3128) // 如果默认配置禁止了22端口的CONNECT,挂载自定义配置文件 .withFileSystemBind("path/to/your/custom/squid.conf", "/etc/squid/squid.conf", BindMode.READ_ONLY); - 自定义
squid.conf需要添加允许CONNECT到22端口的规则,比如:acl connect_ports port 22 http_access allow connect_ports - 在测试启动时先启动Squid容器和你的SFTP Testcontainer,然后让SFTP客户端通过
squidProxy.getHost()和squidProxy.getMappedPort(3128)来配置代理。
2. 使用LittleProxy嵌入式HTTP代理
LittleProxy是纯Java实现的轻量级嵌入式HTTP代理,原生支持CONNECT方法(这是SFTP通过HTTP代理建立TCP隧道必须的),很适合集成到JUnit测试里。
步骤:
- 先引入Maven依赖:
<dependency> <groupId>org.littleshoot</groupId> <artifactId>littleproxy</artifactId> <version>1.1.2</version> <scope>test</scope> </dependency> - 在JUnit测试里启动代理,配置允许转发到你的SFTP服务器:
@BeforeEach void startProxy() { int proxyPort = 8080; // 获取Testcontainers中SFTP服务器的地址和端口 String sftpHost = sftpContainer.getHost(); int sftpPort = sftpContainer.getMappedPort(22); HttpProxyServer proxy = DefaultHttpProxyServer.bootstrap() .withPort(proxyPort) .withTunnelRequestHandler((request, connection) -> { // 允许转发到SFTP服务器的22端口 return new TunnelConnectionHandler(sftpHost, sftpPort); }) .start(); } - 之后你的SFTP客户端就可以用
localhost:8080作为HTTP代理地址来连接SFTP服务器了。
3. 调整MockServer/WireMock的配置(解决之前的问题)
你之前用MockServer或WireMock失败,大概率是没配置对CONNECT请求的转发规则。这两个工具其实都支持代理隧道功能,只要正确配置就能支持SFTP的连接。
以MockServer为例:
@BeforeEach void setupMockServer() { MockServerClient mockServer = new MockServerClient("localhost", 1080); // 转发所有到22端口的CONNECT请求到你的SFTP Testcontainer mockServer.when( request() .withMethod("CONNECT") .withPath(sftpContainer.getHost() + ":" + sftpContainer.getMappedPort(22)) ).forward( forward() .to(sftpContainer.getHost()) .toPort(sftpContainer.getMappedPort(22)) ); }
这样配置后,MockServer就会把针对SFTP服务器的CONNECT请求转发过去,相当于充当了HTTP代理的角色。
关键注意点
无论用哪种方案,都要确保你的HTTP代理支持CONNECT方法——因为SFTP是基于TCP的协议,需要代理建立隧道来转发原始TCP流量,而不是普通的HTTP请求转发,这也是很多通用HTTP工具默认不支持的原因。
备注:内容来源于stack exchange,提问作者abhishek bhardwaj
相关产品推荐
相关产品推荐

