-----------------------------------------------------------------------------
(username, path string, req *http.Request)
| 231 | // ----------------------------------------------------------------------------- |
| 232 | |
| 233 | func (e *rateLimiter) processRequest(username, path string, req *http.Request) (bool, string) { |
| 234 | limits, _ := cbauth.GetUserLimits(username, "local", "fts") |
| 235 | |
| 236 | e.m.Lock() |
| 237 | defer e.m.Unlock() |
| 238 | |
| 239 | if path == indexPath { |
| 240 | // Refresh the indexCache of the rateLimiter at this point, |
| 241 | // to track updates that have been received at other nodes. |
| 242 | // |
| 243 | // Also, pre-processing here for a DELETE INDEX request only |
| 244 | // (pre-processing for CREATE and UPDATE INDEX requests is handled |
| 245 | // within PrepareIndexDef callback for the IndexDef via limitIndexDef). |
| 246 | e.updateIndexCacheLOCKED(req) |
| 247 | } |
| 248 | |
| 249 | now := time.Now() |
| 250 | ingress := req.ContentLength |
| 251 | |
| 252 | entry, exists := e.requestCache[username] |
| 253 | if !exists { |
| 254 | entry = &requestStats{stamp: now} |
| 255 | e.requestCache[username] = entry |
| 256 | } else { |
| 257 | maxConcurrentRequests, _ := limits["num_concurrent_requests"] |
| 258 | if maxConcurrentRequests > 0 && |
| 259 | entry.live >= maxConcurrentRequests { |
| 260 | // reject, surpassed the concurrency limit |
| 261 | return false, fmt.Sprintf("num_concurrent_requests: %v, limit: %v", |
| 262 | entry.live, maxConcurrentRequests) |
| 263 | } |
| 264 | |
| 265 | if now.Sub(entry.stamp) < windowLength { |
| 266 | maxQueriesPerMin, _ := limits["num_queries_per_min"] |
| 267 | if path == queryPath && maxQueriesPerMin > 0 && |
| 268 | entry.countSinceStamp >= maxQueriesPerMin { |
| 269 | // reject, surpassed the queries per minute limit |
| 270 | return false, fmt.Sprintf("num_queries_per_min: %v, limit: %v", |
| 271 | entry.countSinceStamp, maxQueriesPerMin) |
| 272 | } |
| 273 | |
| 274 | maxIngressPerMin := int64(limits["ingress_mib_per_min"] * bytesPerMB) |
| 275 | if maxIngressPerMin > 0 && |
| 276 | entry.ingressBytesSinceStamp >= maxIngressPerMin { |
| 277 | // reject, surpassed the ingress per minute limit |
| 278 | return false, fmt.Sprintf("ingress_mib_per_min: %v, limit: %v", |
| 279 | entry.ingressBytesSinceStamp, maxIngressPerMin) |
| 280 | } |
| 281 | |
| 282 | maxEgressPerMin := int64(limits["egress_mib_per_min"] * bytesPerMB) |
| 283 | if maxEgressPerMin > 0 && |
| 284 | entry.egressBytesSinceStamp >= maxEgressPerMin { |
| 285 | // reject, surpassed the egress per minute limit |
| 286 | return false, fmt.Sprintf("egress_mib_per_min: %v, limit: %v", |
| 287 | entry.egressBytesSinceStamp, maxEgressPerMin) |
| 288 | } |
| 289 | } else { |
| 290 | entry.stamp = now |
no test coverage detected