Compare commits

..
8 Commits
10 changed files with 52 additions and 33 deletions
+18 -11
View File
@@ -12,7 +12,7 @@ jobs:
fail-fast: false
matrix:
# see: https://docs.github.com/zh/actions/using-jobs/choosing-the-runner-for-a-job
# os: ['ubuntu-20.04', 'macos-12']
# os: ['ubuntu-20.04', 'macos-12']
os: ['ubuntu-20.04']
name: build - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
@@ -45,34 +45,41 @@ jobs:
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Set vars
shell: bash
run: |
OS=$(echo '${{ runner.os }}' | awk '{print tolower($0)}')
[[ $OS == 'ubuntu' ]] && echo "OS=linux" >> $GITHUB_ENV || echo "OS=$OS" >> $GITHUB_ENV
[[ $OS == 'macos' ]] && echo "OS=darwin" >> $GITHUB_ENV || echo "OS=$OS" >> $GITHUB_ENV
echo "VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV
- name: Build with Maven (neutrino-proxy-server)
run: |
mvn clean install -pl neutrino-proxy-core -am -DskipTests --no-transfer-progress
cd neutrino-proxy-server
mvn clean native:compile -P native --file pom.xml --no-transfer-progress
chmod +x target/neutrino-proxy-server
cp target/neutrino-proxy-server ./../neutrino-proxy-server-${{ github.ref_name }}
cp target/classes/app-copy.yml ./../neutrino-proxy-server-${{ github.ref_name }}/app.yml
cp target/neutrino-proxy-server ./../neutrino-proxy-server-${{ env.VERSION }}
cp target/classes/app-copy.yml ./../neutrino-proxy-server-${{ env.VERSION }}/app.yml
- name: Archive zip (neutrino-proxy-server)
uses: thedoctor0/zip-release@master
with:
type: 'zip'
path: 'neutrino-proxy-server-${{ github.ref_name }}'
filename: neutrino-proxy-server-${{ matrix.os }}-${{ github.ref_name }}.zip
path: 'neutrino-proxy-server-${{ env.VERSION }}'
filename: neutrino-proxy-server-${{ env.OS }}-${{ env.VERSION }}.zip
- name: Build with Maven (neutrino-proxy-client)
run: |
cd neutrino-proxy-client
mvn clean package --file pom.xml --no-transfer-progress
mvn clean native:compile -P native --file pom.xml --no-transfer-progress
chmod +x target/neutrino-proxy-client
cp target/neutrino-proxy-client ./../neutrino-proxy-client-${{ github.ref_name }}
cp target/classes/app-copy.yml ./../neutrino-proxy-client-${{ github.ref_name }}/app.yml
cp target/neutrino-proxy-client ./../neutrino-proxy-client-${{ env.VERSION }}
cp target/classes/app-copy.yml ./../neutrino-proxy-client-${{ env.VERSION }}/app.yml
- name: Archive zip (neutrino-proxy-client)
uses: thedoctor0/zip-release@master
with:
type: 'zip'
path: 'neutrino-proxy-client-${{ github.ref_name }}'
filename: neutrino-proxy-client-${{ matrix.os }}-${{ github.ref_name }}.zip
path: 'neutrino-proxy-client-${{ env.VERSION }}'
filename: neutrino-proxy-client-${{ env.OS }}-${{ env.VERSION }}.zip
# GitHub 上创建 release
- name: Release
uses: softprops/action-gh-release@v1
@@ -81,7 +88,7 @@ jobs:
files: |
neutrino-proxy-server/target/neutrino-proxy-server.jar
neutrino-proxy-client/target/neutrino-proxy-client.jar
neutrino-proxy-server-${{ matrix.os }}-${{ github.ref_name }}.zip
neutrino-proxy-client-${{ matrix.os }}-${{ github.ref_name }}.zip
neutrino-proxy-server-${{ env.OS }}-${{ env.VERSION }}.zip
neutrino-proxy-client-${{ env.OS }}-${{ env.VERSION }}.zip
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
+11 -4
View File
@@ -44,6 +44,13 @@ jobs:
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Set vars
shell: bash
run: |
OS=$(echo '${{ runner.os }}' | awk '{print tolower($0)}')
[[ $OS == 'ubuntu' ]] && echo "OS=linux" >> $GITHUB_ENV || echo "OS=$OS" >> $GITHUB_ENV
[[ $OS == 'macos' ]] && echo "OS=darwin" >> $GITHUB_ENV || echo "OS=$OS" >> $GITHUB_ENV
echo "VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV
- name: Build with Maven (neutrino-proxy-server)
run: |
set MAVEN_OPTS="-Duser.language=UTF-8 -Dfile.encoding=UTF-8"
@@ -56,7 +63,7 @@ jobs:
with:
type: 'zip'
path: 'neutrino-proxy-server.exe'
filename: neutrino-proxy-server-${{ matrix.os }}-${{ github.ref_name }}.zip
filename: neutrino-proxy-server-${{ env.OS }}-${{ env.VERSION }}.zip
- name: Build with Maven (neutrino-proxy-client)
run: |
set MAVEN_OPTS="-Duser.language=UTF-8 -Dfile.encoding=UTF-8"
@@ -69,7 +76,7 @@ jobs:
with:
type: 'zip'
path: 'neutrino-proxy-client.exe'
filename: neutrino-proxy-client-${{ matrix.os }}-${{ github.ref_name }}.zip
filename: neutrino-proxy-client-${{ env.OS }}-${{ env.VERSION }}.zip
# GitHub 上创建 release
- name: Release
uses: softprops/action-gh-release@v1
@@ -78,7 +85,7 @@ jobs:
files: |
neutrino-proxy-server/target/neutrino-proxy-server.jar
neutrino-proxy-client/target/neutrino-proxy-client.jar
neutrino-proxy-server-${{ matrix.os }}-${{ github.ref_name }}.zip
neutrino-proxy-client-${{ matrix.os }}-${{ github.ref_name }}.zip
neutrino-proxy-server-${{ env.OS }}-${{ env.VERSION }}.zip
neutrino-proxy-client-${{ env.OS }}-${{ env.VERSION }}.zip
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
+2 -3
View File
@@ -75,7 +75,6 @@
## 2.0.1
- jdk版本升级为21
- native部署,后台新增提交到后端,数据库乱码问题
- 解决HTTP(S)映射时使用tcp端口访问正常,使用域名访问偶现一直loading的问题
- [ ] 支持被代理服务获取访问者真实ip
- [ ] 支持对用户、license限速
- 新增安全组模块,支持黑名单、白名单限制
- 支持对用户、license限速
@@ -8,6 +8,7 @@ import org.noear.solon.aot.RuntimeNativeRegistrar;
import org.noear.solon.aot.hint.MemberCategory;
import org.noear.solon.core.AppContext;
import java.nio.ByteBuffer;
import java.util.Set;
/**
@@ -22,6 +23,11 @@ public class NeutrinoCoreRuntimeNativeRegistrar implements RuntimeNativeRegistra
metadata.registerReflection(clazz, MemberCategory.INVOKE_DECLARED_METHODS);
}
Set<Class<?>> byteBufferClasses = ClassUtil.scanPackageBySuper("java", ByteBuffer.class);
for (Class<?> clazz : byteBufferClasses) {
metadata.registerReflection(clazz, MemberCategory.INVOKE_DECLARED_METHODS);
}
metadata.registerReflection(ProxyMessage.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
metadata.registerReflection(ProxyMessage.UdpBaseInfo.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
@@ -77,8 +77,8 @@ public class ProxyConfiguration implements LifecycleBean {
}
ch.pipeline().addFirst(new BytesMetricsHandler());
// ch.pipeline().addLast(new ChannelTrafficShapingHandler(1024 * 1024 * 20, 1024 * 1024 * 20, 100, 20000));
ch.pipeline().addLast("security", new TcpVisitorSecurityChannelHandler());
ch.pipeline().addLast(new VisitorFlowLimiterChannelHandler());
ch.pipeline().addLast(new TcpVisitorSecurityChannelHandler());
ch.pipeline().addLast("flowLimiter", new VisitorFlowLimiterChannelHandler());
ch.pipeline().addLast(new TcpVisitorChannelHandler());
}
});
@@ -116,8 +116,8 @@ public class ProxyConfiguration implements LifecycleBean {
if (null != proxyConfig.getServer().getUdp().getTransferLogEnable() && proxyConfig.getServer().getUdp().getTransferLogEnable()) {
ch.pipeline().addFirst(new LoggingHandler(UdpVisitorChannelHandler.class));
}
pipeline.addLast(udpServerWorkerGroup, "security", new UdpVisitorSecurityChannelHandler());
ch.pipeline().addLast(new VisitorFlowLimiterChannelHandler());
pipeline.addLast(udpServerWorkerGroup, new UdpVisitorSecurityChannelHandler());
ch.pipeline().addLast("flowLimiter", new VisitorFlowLimiterChannelHandler());
pipeline.addLast(udpServerWorkerGroup, new UdpVisitorChannelHandler());
}
});
@@ -48,8 +48,8 @@ public class HttpProxy implements EventListener<AppLoadEndEvent> {
ch.pipeline().addFirst(new LoggingHandler(HttpProxy.class));
}
ch.pipeline().addFirst(new BytesMetricsHandler());
ch.pipeline().addLast("security", new HttpVisitorSecurityChannelHandler(proxyConfig.getServer().getTcp().getDomainName()));
ch.pipeline().addLast(new VisitorFlowLimiterChannelHandler());
ch.pipeline().addLast(new HttpVisitorSecurityChannelHandler(proxyConfig.getServer().getTcp().getDomainName()));
ch.pipeline().addLast("flowLimiter",new VisitorFlowLimiterChannelHandler());
ch.pipeline().addLast(new HttpVisitorChannelHandler());
}
});
@@ -57,8 +57,8 @@ public class HttpsProxy implements EventListener<AppLoadEndEvent> {
}
ch.pipeline().addLast(createSslHandler());
ch.pipeline().addFirst(new BytesMetricsHandler());
ch.pipeline().addLast("security", new HttpVisitorSecurityChannelHandler(proxyConfig.getServer().getTcp().getDomainName()));
ch.pipeline().addLast(new VisitorFlowLimiterChannelHandler());
ch.pipeline().addLast(new HttpVisitorSecurityChannelHandler(proxyConfig.getServer().getTcp().getDomainName()));
ch.pipeline().addLast("flowLimiter",new VisitorFlowLimiterChannelHandler());
ch.pipeline().addLast(new HttpVisitorChannelHandler());
}
});
@@ -18,8 +18,6 @@ import org.noear.solon.Solon;
*/
@Slf4j
public class VisitorFlowLimiterChannelHandler extends ChannelInboundHandlerAdapter {
private final LicenseService licenseService = Solon.context().getBean(LicenseService.class);
private final PortMappingService portMappingService = Solon.context().getBean(PortMappingService.class);
@Override
@@ -38,7 +36,7 @@ public class VisitorFlowLimiterChannelHandler extends ChannelInboundHandlerAdapt
}
if (null != upLimitRate || null != downLimitRate) {
// 如果不全为空,则需要做限速
ctx.pipeline().addAfter("security", "trafficShaping", new ChannelTrafficShapingHandler(downLimitRate == null ? 0 : downLimitRate, upLimitRate == null ? 0 : upLimitRate, 100, 600000));
ctx.pipeline().addAfter("flowLimiter", "trafficShaping", new ChannelTrafficShapingHandler(downLimitRate == null ? 0 : downLimitRate, upLimitRate == null ? 0 : upLimitRate, 100, 600000));
}
// 每个连接第一次处理之后。无论是否限速,该连接后续都不在处理,避免频繁执行影响性能
@@ -138,7 +138,9 @@ public class PortMappingService implements LifecycleBean {
}
});
//sorted [userId asc] [licenseId asc] [createTime asc]
respList = respList.stream().sorted(Comparator.comparing(PortMappingListRes::getUserId).thenComparing(PortMappingListRes::getLicenseId).thenComparing(PortMappingListRes::getCreateTime)).collect(Collectors.toList());
respList = respList.stream()
.filter(e -> null != e.getUserId())
.sorted(Comparator.comparing(PortMappingListRes::getUserId).thenComparing(PortMappingListRes::getLicenseId).thenComparing(PortMappingListRes::getCreateTime)).collect(Collectors.toList());
return PageInfo.of(respList, page.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
@@ -15,7 +15,7 @@ public class StringUtil {
private static final Integer BYTES_MUL_GB = BYTES_MUL_MB * 1024;
private static final String[] BYTES_UNIT_STR = {"B", "K", "KB", "M", "MB", "G", "GB"};
private static final Integer[] BYTES_UNIT_MUL = {1, BYTES_MUL_KB, BYTES_MUL_KB, BYTES_MUL_MB, BYTES_MUL_MB, BYTES_MUL_GB, BYTES_MUL_GB};
private static final String BYTES_DESC_REGEX = "\\s*(\\d+)\\s*(B|K|KB|M|MB|G|GB)\\s*";
private static final String BYTES_DESC_REGEX = "\\s*(\\d+\\.*\\d*)\\s*(B|K|KB|M|MB|G|GB)\\s*";
private static final Pattern BYTES_DESC_PATTERN = Pattern.compile(BYTES_DESC_REGEX);
/**
@@ -46,14 +46,14 @@ public class StringUtil {
if (!found) {
return null;
}
Integer n = Integer.parseInt(matcher.group(1));
Double n = Double.parseDouble(matcher.group(1));
String unit = matcher.group(2);
Integer unitIndex = getBytesUnitIndex(unit);
if (null == unitIndex) {
return null;
}
return (long)n * BYTES_UNIT_MUL[unitIndex];
return (long)(n * BYTES_UNIT_MUL[unitIndex]);
} catch (Exception e) {
// ignore
}