cl
4 天以前 936dd65f69e1c9b17ed8abd4edf4c624cee68e23
rsf-http-audit/src/main/java/com/vincent/rsf/httpaudit/service/HttpAuditRuleServiceImpl.java
@@ -18,13 +18,14 @@
import java.util.regex.Pattern;
/**
 * 规则缓存;入站/出站或关系;record_all 时白名单下也全记
 * 规则缓存;入站/出站或关系;record_all 仅在该条规则命中时对本条日志生效(默认 -1 不截断)
 */
@Slf4j
public class HttpAuditRuleServiceImpl extends ServiceImpl<HttpAuditRuleMapper, HttpAuditRule> implements HttpAuditRuleService {
    private final HttpAuditProperties props;
    private final CopyOnWriteArrayList<HttpAuditRule> cache = new CopyOnWriteArrayList<>();
    private volatile long lastRefreshAt = 0L;
    public HttpAuditRuleServiceImpl(HttpAuditRuleMapper mapper, HttpAuditProperties props) {
        this.baseMapper = mapper;
@@ -37,8 +38,14 @@
    }
    @Override
    @Scheduled(fixedDelayString = "${http-audit.rule-cache-refresh-ms:60000}")
    @Scheduled(fixedDelay = 5000)
    public void refreshCache() {
        long now = System.currentTimeMillis();
        long interval = Math.max(5000L, props.getRuleCacheRefreshMs());
        if (now - lastRefreshAt < interval) {
            return;
        }
        lastRefreshAt = now;
        try {
            List<HttpAuditRule> list = list(new LambdaQueryWrapper<HttpAuditRule>()
                    .eq(HttpAuditRule::getDeleted, 0)
@@ -61,28 +68,21 @@
    @Override
    public HttpAuditDecision decideInbound(HttpServletRequest request, String requestBody) {
        if (!props.isWhitelistOnly()) {
            return HttpAuditDecision.yes(reqLimitFromRecordAllRow(), resLimitFromRecordAllRow());
            return HttpAuditDecision.yes(null, null);
        }
        if (cache.isEmpty()) {
            return HttpAuditDecision.SKIP;
        }
        HttpAuditRule allRow = firstRecordAllRule();
        if (allRow != null) {
            return HttpAuditDecision.yes(allRow.getRequestMaxChars(), allRow.getResponseMaxChars());
        }
        String path = HttpAuditSupport.safePath(request);
        String ip = HttpAuditSupport.clientIp(request);
        String body = requestBody == null ? "" : requestBody;
        for (HttpAuditRule r : cache) {
            if (isRecordAll(r)) {
                continue;
            }
            if (!appliesInbound(r)) {
                continue;
            }
            try {
                if (matchInbound(r, path, ip, body)) {
                    return HttpAuditDecision.yes(r.getRequestMaxChars(), r.getResponseMaxChars());
                    return decisionForMatchedRule(r);
                }
            } catch (Exception e) {
                log.debug("http-audit 规则 id={} 匹配异常:{}", r.getId(), e.getMessage());
@@ -94,26 +94,19 @@
    @Override
    public HttpAuditDecision decideOutbound(String fullUrl, String method, String requestBody) {
        if (!props.isWhitelistOnly()) {
            return HttpAuditDecision.yes(reqLimitFromRecordAllRow(), resLimitFromRecordAllRow());
            return HttpAuditDecision.yes(null, null);
        }
        if (cache.isEmpty()) {
            return HttpAuditDecision.SKIP;
        }
        HttpAuditRule allRow = firstRecordAllRule();
        if (allRow != null) {
            return HttpAuditDecision.yes(allRow.getRequestMaxChars(), allRow.getResponseMaxChars());
        }
        String body = requestBody == null ? "" : requestBody;
        for (HttpAuditRule r : cache) {
            if (isRecordAll(r)) {
                continue;
            }
            if (!appliesOutbound(r)) {
                continue;
            }
            try {
                if (matchOutbound(r, fullUrl, body)) {
                    return HttpAuditDecision.yes(r.getRequestMaxChars(), r.getResponseMaxChars());
                    return decisionForMatchedRule(r);
                }
            } catch (Exception e) {
                log.debug("http-audit 出站规则 id={} 匹配异常:{}", r.getId(), e.getMessage());
@@ -122,23 +115,13 @@
        return HttpAuditDecision.SKIP;
    }
    private Integer reqLimitFromRecordAllRow() {
        HttpAuditRule row = firstRecordAllRule();
        return row == null ? null : row.getRequestMaxChars();
    }
    private Integer resLimitFromRecordAllRow() {
        HttpAuditRule row = firstRecordAllRule();
        return row == null ? null : row.getResponseMaxChars();
    }
    private HttpAuditRule firstRecordAllRule() {
        for (HttpAuditRule r : cache) {
            if (isRecordAll(r)) {
                return r;
            }
    private static HttpAuditDecision decisionForMatchedRule(HttpAuditRule r) {
        if (isRecordAll(r)) {
            Integer req = r.getRequestMaxChars() != null ? r.getRequestMaxChars() : -1;
            Integer res = r.getResponseMaxChars() != null ? r.getResponseMaxChars() : -1;
            return HttpAuditDecision.yes(req, res);
        }
        return null;
        return HttpAuditDecision.yes(r.getRequestMaxChars(), r.getResponseMaxChars());
    }
    private static boolean isRecordAll(HttpAuditRule r) {
@@ -154,17 +137,11 @@
    }
    private static boolean appliesInbound(HttpAuditRule r) {
        if (isRecordAll(r)) {
            return false;
        }
        String d = dir(r);
        return HttpAuditRule.DIR_IN.equals(d) || HttpAuditRule.DIR_BOTH.equals(d);
    }
    private static boolean appliesOutbound(HttpAuditRule r) {
        if (isRecordAll(r)) {
            return false;
        }
        String d = dir(r);
        return HttpAuditRule.DIR_OUT.equals(d) || HttpAuditRule.DIR_BOTH.equals(d);
    }