STTNet 0.7.0

Demo:连接与请求限流

可构建、可运行、可验证,并与仓库 examples 目录中的源码保持一致。

1. 示例内容

完整源码中的关键调用均有中文注释,页面同时给出运行命令、验证方法和可调整参数。

2. 构建与运行

cmake --build build --target sttnet_security_limiter --parallel
./build/examples/sttnet_security_limiter

3. 运行结果

./build/examples/sttnet_security_limiter
预期:前两次登录请求为 ALLOW,之后为 CLOSE,并显示黑名单状态。

4. 完整源码

#include <sttnet.h>

#include <iostream>

static const char *decisionName(stt::security::DefenseDecision decision)
{
    using namespace stt::security;
    switch(decision)
    {
        case ALLOW: return "ALLOW";
        case DROP:  return "DROP";
        case CLOSE: return "CLOSE";
    }
    return "UNKNOWN";
}

int main()
{
    using namespace stt::security;

    // 同一 IP 最多允许两个并发连接,并把
    // 60 秒无活动的连接视为空闲。
    ConnectionLimiter limiter(2, 60);
    limiter.setConnectStrategy(RateLimitType::TokenBucket);
    limiter.setRequestStrategy(RateLimitType::SlidingWindow);
    limiter.setPathStrategy(RateLimitType::Cooldown);

    // /login 使用更严格的附加规则:十秒最多两次请求。
    limiter.setPathLimit("/login", 2, 10);

    const std::string ip = "192.0.2.10";
    const int fd = 1001; // 演示用标识,不需要真实 socket。

    const DefenseDecision connect = limiter.allowConnect(ip, fd, 10, 1);
    std::cout << "connect: " << decisionName(connect) << '\n';
    if(connect != ALLOW)
        return 1;

    for(int i = 1; i <= 4; ++i)
    {
        const DefenseDecision request =
            limiter.allowRequest(ip, fd, "/login", 100, 1);
        std::cout << "login request " << i << ": "
                  << decisionName(request) << '\n';
    }

    limiter.banIP(ip, 30, "演示封禁", "demo ban");
    std::cout << "banned: " << std::boolalpha << limiter.isBanned(ip) << '\n';
    limiter.unbanIP(ip);

    // 连接关闭时移除每个成功登记的 fd。
    limiter.clearIP(ip, fd);
    return 0;
}