MCPcopy Create free account
hub / github.com/MITK/MITK / CheckRateLimit

Method CheckRateLimit

Modules/RESTAPI/src/mitkRestServer.cpp:662–753  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

660}
661
662bool RestServer::CheckRateLimit(const httplib::Request& req, httplib::Response& res)
663{
664 const auto& config = *m_RunningConfig;
665
666 if (!config.rateLimitEnabled)
667 {
668 return true;
669 }
670
671 // Exempt health/info endpoints from rate limiting
672 if (IsRateLimitExemptPath(req.path))
673 {
674 return true;
675 }
676
677 const auto now = std::chrono::steady_clock::now();
678 const auto windowDuration = std::chrono::seconds(60);
679 const auto windowStart = now - windowDuration;
680
681 bool rateLimitExceeded = false;
682 int retryAfterSeconds = 0;
683
684 {
685 std::lock_guard<std::mutex> lock(m_Mutex);
686
687 // NOTE: rate limiting keys on req.remote_addr (TCP source address). Behind a NAT
688 // or reverse proxy all clients share one bucket. X-Forwarded-For is intentionally
689 // not used as it can be spoofed by the client.
690 auto& timestamps = m_RateLimitMap[req.remote_addr];
691
692 // Remove entries older than the window
693 while (!timestamps.empty() && timestamps.front() < windowStart)
694 {
695 timestamps.pop_front();
696 }
697
698 if (static_cast<int>(timestamps.size()) >= config.rateLimitPerMinute)
699 {
700 // Calculate retry-after as seconds until the oldest entry expires
701 const auto oldestExpiry = timestamps.front() + windowDuration;
702 const auto retryAfter =
703 std::chrono::duration_cast<std::chrono::seconds>(oldestExpiry - now).count();
704 retryAfterSeconds = std::max(1, static_cast<int>(retryAfter));
705 rateLimitExceeded = true;
706 }
707 else
708 {
709 // Record this request's timestamp
710 timestamps.push_back(now);
711
712 // Periodically clean up stale IP entries. NOTE: cleanup runs only every
713 // kRateLimitCleanupInterval checks, so m_RateLimitMap can grow proportionally
714 // to the number of unique source IPs seen between sweeps.
715 ++m_RateLimitCheckCount;
716 if (m_RateLimitCheckCount % kRateLimitCleanupInterval == 0)
717 {
718 for (auto it = m_RateLimitMap.begin(); it != m_RateLimitMap.end(); )
719 {

Callers 1

RegisterRoutesMethod · 0.95

Calls 9

RecordRequestMethod · 0.95
IsRateLimitExemptPathFunction · 0.85
frontMethod · 0.80
countMethod · 0.80
emptyMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
eraseMethod · 0.45

Tested by

no test coverage detected