Demo:连接与请求限流
可构建、可运行、可验证,并与仓库 examples 目录中的源码保持一致。
1. 示例内容
完整源码中的关键调用均有中文注释,页面同时给出运行命令、验证方法和可调整参数。
2. 构建与运行
cmake --build build --target sttnet_security_limiter --parallel
./build/examples/sttnet_security_limiter3. 运行结果
./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;
}