Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.rx.net.Sockets Maven / Gradle / Ivy
package org.rx.net;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.bootstrap.ServerBootstrapConfig;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.compression.ZlibCodecFactory;
import io.netty.handler.codec.compression.ZlibWrapper;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.util.NetUtil;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.rx.bean.$;
import org.rx.bean.FlagsEnum;
import org.rx.core.*;
import org.rx.exception.InvalidException;
import org.rx.io.Files;
import org.rx.net.dns.DnsClient;
import org.rx.net.dns.DnsServer;
import org.rx.util.function.BiAction;
import org.rx.util.function.BiFunc;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.net.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static org.rx.bean.$.$;
import static org.rx.core.Extends.quietly;
import static org.rx.core.Sys.fastCacheKey;
import static org.rx.core.Sys.toJsonString;
@Slf4j
public final class Sockets {
public interface ReactorNames {
String SHARED_TCP = "_TCP";
String SHARED_UDP = "_UDP";
String RPC = "RPC";
String DNS = "DNS";
String SS = "SS";
}
public static final String ZIP_ENCODER = "ZIP_ENCODER";
public static final String ZIP_DECODER = "ZIP_DECODER";
public static final LengthFieldPrepender INT_LENGTH_PREPENDER = new LengthFieldPrepender(4);
static final String M_0 = "lookupAllHostAddr";
static final LoggingHandler DEFAULT_LOG = new LoggingHandler(LogLevel.INFO);
static final Map reactors = new ConcurrentHashMap<>();
static String loopbackAddr;
static volatile DnsServer.ResolveInterceptor nsInterceptor;
//region netty
public static void injectNameService(List nameServerList) {
if (CollectionUtils.isEmpty(nameServerList)) {
throw new InvalidException("Empty server list");
}
DnsClient client = new DnsClient(nameServerList);
injectNameService(client::resolveAll);
}
@SneakyThrows
public static void injectNameService(@NonNull DnsServer.ResolveInterceptor interceptor) {
if (nsInterceptor == null) {
synchronized (Sockets.class) {
if (nsInterceptor == null) {
nsInterceptor = interceptor;
Class> type = InetAddress.class;
try {
Field field = type.getDeclaredField("nameService");
Reflects.setAccess(field);
field.set(null, nsProxy(field.get(null)));
} catch (NoSuchFieldException e) {
Field field = type.getDeclaredField("nameServices");
Reflects.setAccess(field);
List nsList = (List) field.get(null);
nsList.set(0, nsProxy(nsList.get(0)));
}
}
}
}
nsInterceptor = interceptor;
}
private static Object nsProxy(Object ns) {
Class> type = ns.getClass();
InetAddress[] empty = new InetAddress[0];
return Proxy.newProxyInstance(type.getClassLoader(), type.getInterfaces(), (pObject, method, args) -> {
if (Strings.hashEquals(method.getName(), M_0)) {
String host = (String) args[0];
//If all interceptors can't handle it, the source object will process it.
try {
List addresses = nsInterceptor.resolveHost(host);
if (!CollectionUtils.isEmpty(addresses)) {
return addresses.toArray(empty);
}
} catch (Exception e) {
log.info("nsProxy {}", e.getMessage());
}
}
return Reflects.invokeMethod(method, ns, args);
});
}
public static EventLoopGroup reactor(String reactorName, boolean isTcp) {
return reactors.computeIfAbsent(reactorName, k -> {
int amount = RxConfig.INSTANCE.getNet().getReactorThreadAmount();
return isTcp && Epoll.isAvailable() ? new EpollEventLoopGroup(amount) : new NioEventLoopGroup(amount);
});
}
//Don't use executor
private static EventLoopGroup newEventLoop(int threadAmount) {
return Epoll.isAvailable() ? new EpollEventLoopGroup(threadAmount) : new NioEventLoopGroup(threadAmount);
}
public static Class extends SocketChannel> channelClass() {
return Epoll.isAvailable() ? EpollSocketChannel.class : NioSocketChannel.class;
}
//region tcp
public static ServerBootstrap serverBootstrap(BiAction initChannel) {
return serverBootstrap(null, initChannel);
}
public static ServerBootstrap serverBootstrap(SocketConfig config, BiAction initChannel) {
if (config == null) {
config = new SocketConfig();
}
MemoryMode mode = config.getMemoryMode();
int connectTimeoutMillis = config.getConnectTimeoutMillis();
boolean highNetwork = connectTimeoutMillis <= SocketConfig.DELAY_TIMEOUT_MILLIS;
int bossThreadAmount = 1; //Equal to the number of bind(), default 1
AdaptiveRecvByteBufAllocator recvByteBufAllocator = mode.adaptiveRecvByteBufAllocator(false);
WriteBufferWaterMark writeBufferWaterMark = mode.writeBufferWaterMark();
ServerBootstrap b = new ServerBootstrap()
.group(newEventLoop(bossThreadAmount), config.isUseSharedTcpEventLoop() ? reactor(ReactorNames.SHARED_TCP, true) : newEventLoop(0))
.channel(Epoll.isAvailable() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, mode.getBacklog())
// .option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeoutMillis)
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.option(ChannelOption.RCVBUF_ALLOCATOR, recvByteBufAllocator)
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark)
.childOption(ChannelOption.TCP_NODELAY, highNetwork)
// .childOption(ChannelOption.SO_KEEPALIVE, !highNetwork)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.childOption(ChannelOption.RCVBUF_ALLOCATOR, recvByteBufAllocator)
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark)
.childHandler(WaterMarkHandler.DEFAULT);
if (config.isEnableLog()) {
//netty log
b.handler(DEFAULT_LOG);
}
if (initChannel != null) {
b.childHandler(new ChannelInitializer() {
@SneakyThrows
@Override
protected void initChannel(SocketChannel socketChannel) {
initChannel.invoke(socketChannel);
}
});
}
return b;
}
public static void closeBootstrap(ServerBootstrap bootstrap) {
if (bootstrap == null) {
return;
}
ServerBootstrapConfig config = bootstrap.config();
EventLoopGroup group = config.group();
if (group != null) {
group.shutdownGracefully();
}
group = config.childGroup();
if (group != null && !reactors.containsValue(group)) {
group.shutdownGracefully();
}
}
public static Bootstrap bootstrap(SocketConfig config, BiAction initChannel) {
return bootstrap(ReactorNames.SHARED_TCP, config, initChannel);
}
public static Bootstrap bootstrap(String reactorName, SocketConfig config, BiAction initChannel) {
return bootstrap(reactor(reactorName, true), config, initChannel);
}
public static Bootstrap bootstrap(@NonNull EventLoopGroup eventLoopGroup, SocketConfig config, BiAction initChannel) {
if (config == null) {
config = new SocketConfig();
}
MemoryMode mode = config.getMemoryMode();
int connectTimeoutMillis = config.getConnectTimeoutMillis();
boolean highNetwork = connectTimeoutMillis <= SocketConfig.DELAY_TIMEOUT_MILLIS;
AdaptiveRecvByteBufAllocator recvByteBufAllocator = mode.adaptiveRecvByteBufAllocator(false);
WriteBufferWaterMark writeBufferWaterMark = mode.writeBufferWaterMark();
Bootstrap b = new Bootstrap()
.group(eventLoopGroup)
.channel(channelClass())
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeoutMillis)
.option(ChannelOption.TCP_NODELAY, highNetwork)
// .option(ChannelOption.SO_KEEPALIVE, !highNetwork)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.option(ChannelOption.RCVBUF_ALLOCATOR, recvByteBufAllocator)
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark)
.handler(WaterMarkHandler.DEFAULT);
if (config.isEnableLog()) {
b.handler(DEFAULT_LOG);
}
if (initChannel != null) {
b.handler(new ChannelInitializer() {
@SneakyThrows
@Override
protected void initChannel(SocketChannel socketChannel) {
initChannel.invoke(socketChannel);
}
});
}
return b;
}
@SneakyThrows
public static void addFrontendHandler(Channel channel, SocketConfig config) {
FlagsEnum flags = config.getTransportFlags();
if (flags == null) {
return;
}
ChannelPipeline pipeline = channel.pipeline();
if (flags.has(TransportFlags.FRONTEND_SSL)) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
pipeline.addLast(sslCtx.newHandler(channel.alloc()));
}
if (flags.has(TransportFlags.FRONTEND_AES)) {
if (config.getAesKey() == null) {
throw new InvalidException("AES key is empty");
}
pipeline.addLast(new AESCodec(config.getAesKey()).channelHandlers());
}
if (flags.has(TransportFlags.FRONTEND_COMPRESS)) {
pipeline.addLast(ZIP_ENCODER, ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP))
.addLast(ZIP_DECODER, ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
}
}
@SneakyThrows
public static void addBackendHandler(Channel channel, SocketConfig config, InetSocketAddress remoteEndpoint) {
FlagsEnum flags = config.getTransportFlags();
if (flags == null) {
return;
}
ChannelPipeline pipeline = channel.pipeline();
if (flags.has(TransportFlags.BACKEND_SSL)) {
SslContext sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
pipeline.addLast(sslCtx.newHandler(channel.alloc(), remoteEndpoint.getHostString(), remoteEndpoint.getPort()));
}
if (flags.has(TransportFlags.BACKEND_AES)) {
if (config.getAesKey() == null) {
throw new InvalidException("AES key is empty");
}
pipeline.addLast(new AESCodec(config.getAesKey()).channelHandlers());
}
if (flags.has(TransportFlags.BACKEND_COMPRESS)) {
pipeline.addLast(ZIP_ENCODER, ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP))
.addLast(ZIP_DECODER, ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
}
}
//endregion
public static Bootstrap udpBootstrap(MemoryMode mode, BiAction initChannel) {
return udpBootstrap(ReactorNames.SHARED_UDP, mode, false, initChannel);
}
public static Bootstrap udpBootstrap(String reactorName, MemoryMode mode, BiAction initChannel) {
return udpBootstrap(reactorName, mode, false, initChannel);
}
public static Bootstrap udpBootstrap(MemoryMode mode, boolean multicast, BiAction initChannel) {
return udpBootstrap(ReactorNames.SHARED_UDP, mode, multicast, initChannel);
}
//BlockingOperationException 因为执行sync()-wait和notify的是同一个EventLoop中的线程
//DefaultDatagramChannelConfig
@SneakyThrows
static Bootstrap udpBootstrap(@NonNull String reactorName, MemoryMode mode, boolean multicast, BiAction initChannel) {
if (mode == null) {
mode = MemoryMode.LOW;
}
NetworkInterface mif = null;
if (multicast) {
// MulticastSocket ms = new MulticastSocket();
// mif = ms.getNetworkInterface();
mif = NetworkInterface.getByInetAddress(Sockets.getLocalAddress(true));
}
Bootstrap b = new Bootstrap().group(reactor(reactorName, false))
// .option(ChannelOption.SO_BROADCAST, true)
.option(ChannelOption.RCVBUF_ALLOCATOR, mode.adaptiveRecvByteBufAllocator(true))
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, mode.writeBufferWaterMark())
.handler(WaterMarkHandler.DEFAULT);
if (multicast) {
b.channelFactory(() -> new NioDatagramChannel(InternetProtocolFamily.IPv4))
.option(ChannelOption.IP_MULTICAST_IF, mif)
.option(ChannelOption.SO_REUSEADDR, true);
} else {
b.channel(NioDatagramChannel.class);
}
b.handler(DEFAULT_LOG);
if (initChannel != null) {
b.handler(new ChannelInitializer() {
@SneakyThrows
@Override
protected void initChannel(NioDatagramChannel socketChannel) {
initChannel.invoke(socketChannel);
}
});
}
return b;
}
public static void writeAndFlush(Channel channel, @NonNull Queue> packs) {
EventLoop eventLoop = channel.eventLoop();
if (eventLoop.inEventLoop()) {
Object pack;
while ((pack = packs.poll()) != null) {
channel.write(pack).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
channel.flush();
return;
}
eventLoop.execute(() -> {
Object pack;
while ((pack = packs.poll()) != null) {
channel.write(pack).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
channel.flush();
});
}
public static void closeOnFlushed(Channel channel) {
if (channel == null || !channel.isActive()) {
return;
}
channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
public static ByteBuf getMessageBuf(Object msg) {
if (msg instanceof DatagramPacket) {
return ((DatagramPacket) msg).content();
} else if (msg instanceof ByteBuf) {
return (ByteBuf) msg;
} else {
throw new InvalidException("Unsupported msg type: {}", msg.getClass());
}
}
public static String protocolName(Channel channel) {
return channel instanceof NioDatagramChannel ? "UDP" : "TCP";
}
public static ChannelFutureListener logBind(int port) {
return f -> {
String pn = protocolName(f.channel());
if (!f.isSuccess()) {
log.error("{} Listen on port {} fail", pn, port, f.cause());
return;
}
log.info("{} Listened on {}", pn, f.channel().localAddress());
};
}
public static ChannelFutureListener logConnect(InetSocketAddress endpoint) {
return f -> {
if (!f.isSuccess()) {
log.error("TCP Connect {} fail", endpoint, f.cause());
return;
}
log.info("TCP Connected {}", endpoint);
};
}
public static void dumpPipeline(String name, Channel channel) {
if (log.isTraceEnabled()) {
ChannelPipeline pipeline = channel.pipeline();
List inboundHandlers = new LinkedList<>();
List outboundHandlers = new LinkedList<>();
log.trace(name + " list:");
for (Map.Entry entry : pipeline) {
String prefix;
ChannelHandler handler = entry.getValue();
if (handler instanceof ChannelInboundHandler) {
prefix = "in";
inboundHandlers.add((ChannelInboundHandler) handler);
} else if (handler instanceof ChannelOutboundHandler) {
prefix = "out";
outboundHandlers.add((ChannelOutboundHandler) handler);
} else {
prefix = "?";
log.trace(String.format("%s %s: %s", prefix, entry.getKey(), entry.getValue()));
}
}
log.trace(name + " sorted:");
for (ChannelInboundHandler handler : inboundHandlers) {
log.trace(String.format("in %s", handler));
}
for (ChannelOutboundHandler handler : outboundHandlers) {
log.trace(String.format("out %s", handler));
}
}
}
//endregion
//region Address
public static boolean isBypass(Iterable bypassList, String host) {
if (bypassList == null) {
return false;
}
for (String regex : bypassList) {
if (Files.wildcardMatch(host, regex)) {
return true;
}
}
return false;
}
@SneakyThrows
public static boolean isLanIp(InetAddress ip) {
String hostAddress = ip.getHostAddress();
if (Strings.hashEquals(getLoopbackHostAddress(), hostAddress)) {
return true;
}
return isBypass(RxConfig.INSTANCE.getNet().getLanIps(), hostAddress);
}
public static boolean isValidIp(String ip) {
return NetUtil.isValidIpV4Address(ip) || NetUtil.isValidIpV6Address(ip);
}
public static String getLoopbackHostAddress() {
if (loopbackAddr == null) {
loopbackAddr = getLoopbackAddress().getHostAddress();
}
return loopbackAddr;
}
public static InetAddress getLoopbackAddress() {
return InetAddress.getLoopbackAddress();
}
@SneakyThrows
public static InetAddress getAnyLocalAddress() {
return InetAddress.getByName("0.0.0.0");
}
public static InetAddress getLocalAddress() {
return getLocalAddress(false);
}
@SneakyThrows
public static InetAddress getLocalAddress(boolean supportsMulticast) {
Inet4Address first = Linq.from(getLocalAddresses(supportsMulticast)).orderByDescending(Inet4Address::isSiteLocalAddress).firstOrDefault();
if (first != null) {
return first;
}
return InetAddress.getLocalHost(); //may return 127.0.0.1
}
@SneakyThrows
public static List getLocalAddresses(boolean supportsMulticast) {
List ips = new ArrayList<>();
Enumeration networks = NetworkInterface.getNetworkInterfaces();
while (networks.hasMoreElements()) {
NetworkInterface network = networks.nextElement();
if (network.isLoopback() || network.isVirtual() || !network.isUp() || (supportsMulticast && !network.supportsMulticast())) {
continue;
}
Enumeration addresses = network.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr.isLoopbackAddress() || addr.isAnyLocalAddress()
// || !addr.isSiteLocalAddress() //k8s会获取不到
|| !(addr instanceof Inet4Address)) {
continue;
}
// log.info("DUMP: {} - {} {} - {} {} - {} {} {}", addr.isMulticastAddress(),
// addr.isSiteLocalAddress(), addr.isLinkLocalAddress(),
// addr.isMCSiteLocal(), addr.isMCLinkLocal(),
// addr.isMCGlobal(), addr.isMCOrgLocal(), addr.isMCNodeLocal());
ips.add((Inet4Address) addr);
}
}
if (supportsMulticast && ips.isEmpty()) {
throw new InvalidException("Not multicast network found");
}
return ips;
}
public static InetSocketAddress newLoopbackEndpoint(int port) {
return new InetSocketAddress(getLoopbackAddress(), port);
}
public static InetSocketAddress newAnyEndpoint(int port) {
return new InetSocketAddress(getAnyLocalAddress(), port);
}
public static InetSocketAddress newEndpoint(String endpoint, int port) {
return newEndpoint(parseEndpoint(endpoint), port);
}
public static InetSocketAddress newEndpoint(@NonNull InetSocketAddress endpoint, int port) {
if (endpoint.getPort() == port) {
return endpoint;
}
return new InetSocketAddress(endpoint.getAddress(), port);
}
@SneakyThrows
public static List newAllEndpoints(@NonNull InetSocketAddress endpoint) {
return Linq.from(InetAddress.getAllByName(endpoint.getHostString())).select(p -> new InetSocketAddress(p, endpoint.getPort())).toList();
}
public static InetSocketAddress parseEndpoint(@NonNull String endpoint) {
int i = endpoint.lastIndexOf(":");
if (i == -1) {
throw new InvalidException("Invalid endpoint {}", endpoint);
}
String ip = endpoint.substring(0, i);
int port = Integer.parseInt(endpoint.substring(i + 1));
return new InetSocketAddress(ip, port);
// return InetSocketAddress.createUnresolved(ip, port); //DNS issues
}
public static String toString(InetSocketAddress endpoint) {
if (endpoint == null) {
return "NULL";
}
return String.format("%s:%s", endpoint.getHostString(), endpoint.getPort());
}
public static void closeOnFlushed(Socket socket) {
if (socket.isClosed()) {
return;
}
quietly(() -> {
if (socket.isConnected()) {
socket.setSoLinger(true, 2);
if (!socket.isOutputShutdown()) {
socket.shutdownOutput();
}
if (!socket.isInputShutdown()) {
socket.shutdownInput();
}
}
socket.close();
});
}
public static Linq socketInfos(SocketProtocol protocol) {
try (ShellCommand cmd = new ShellCommand("netstat -aon")) {
List list = new ArrayList<>();
cmd.onPrintOut.combine((s, e) -> {
String line = e.getLine();
if (!line.contains(protocol.name())) {
return;
}
String[] arr = Linq.from(Strings.split(line, " ")).select(String::trim).where(p -> !p.isEmpty()).toArray();
try {
SocketProtocol p = SocketProtocol.valueOf(arr[0]);
SocketInfo sockInfo;
if (p == SocketProtocol.TCP) {
sockInfo = new SocketInfo(p, parseEndpoint(arr[1]), parseEndpoint(arr[2]),
TcpStatus.valueOf(arr[3]), Long.parseLong(arr[4]));
} else {
sockInfo = new SocketInfo(p, parseEndpoint(arr[1]), null,
null, Long.parseLong(arr[3]));
}
list.add(sockInfo);
} catch (Exception ex) {
log.error("Parse line {} fail", toJsonString(arr), ex);
}
});
cmd.start().waitFor();
Linq q = Linq.from(list, true);
q.forEach(p -> p.setProcessName(processName(p.pid)));
return q;
}
}
static String processName(long pid) {
return Cache.getOrSet(fastCacheKey("processName", pid), k -> {
$ name = $();
try (ShellCommand cmd = new ShellCommand(String.format("tasklist /fi \"pid eq %s\"", pid))) {
String t = String.format(" %s", pid);
cmd.onPrintOut.combine((s, e) -> {
int i = e.getLine().indexOf(t);
if (i == -1) {
return;
}
name.v = e.getLine().substring(0, i).trim();
});
cmd.start().waitFor();
}
return name.v;
});
}
//#endregion
//region httpProxy
public static T httpProxyInvoke(String proxyAddr, BiFunc func) {
setHttpProxy(proxyAddr);
try {
return func.apply(proxyAddr);
} finally {
clearHttpProxy();
}
}
public static void setHttpProxy(String proxyAddr) {
setHttpProxy(proxyAddr, null, null, null);
}
public static void setHttpProxy(String proxyAddr, List nonProxyHosts, String userName, String password) {
InetSocketAddress ipe = parseEndpoint(proxyAddr);
Properties prop = System.getProperties();
prop.setProperty("http.proxyHost", ipe.getAddress().getHostAddress());
prop.setProperty("http.proxyPort", String.valueOf(ipe.getPort()));
prop.setProperty("https.proxyHost", ipe.getAddress().getHostAddress());
prop.setProperty("https.proxyPort", String.valueOf(ipe.getPort()));
if (!CollectionUtils.isEmpty(nonProxyHosts)) {
//"localhost|192.168.1.*"
prop.setProperty("http.nonProxyHosts", String.join("|", nonProxyHosts));
}
if (userName != null && password != null) {
Authenticator.setDefault(new UserAuthenticator(userName, password));
}
}
public static void clearHttpProxy() {
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
System.clearProperty("http.nonProxyHosts");
}
@RequiredArgsConstructor
static class UserAuthenticator extends Authenticator {
final String userName;
final String password;
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password.toCharArray());
}
}
//endregion
}