B4J Library [Web] Pakai Watch

Pakai Watch — Rate Limiter Filter for Pakai Server​

Version 0.60

A sliding-window rate limiter for Pakai Server v6 / B4J server apps. Drop it in and protect your endpoints from abuse.

GitHub: https://github.com/pyhoon/pakai-watch

Features

  • Sliding window — per-client timestamp tracking (configurable per-endpoint)
  • Per-endpoint limits — different (maxRequests, windowMs) for different URL prefixes
  • Per-key overrides — boost limits for specific trusted API keys
  • Bearer token auth — identifies clients via Authorization header, falls back to GUEST-{IP}
  • Cloudflare aware — reads CF-Connecting-IP header automatically
  • IP whitelist — loaded from whitelist.txt, supports wildcards (192.168.*)
  • Security logging — blocked requests logged to security_violations.log
  • Daily summaries — midnight rollover generates daily_report_YYYY-MM-DD.txt
  • Retry-After header — 429 responses include seconds until window reset
  • Thread-safe — uses java.util.concurrent.locks.ReentrantLock srvr.CreateThreadSafeMap
  • No timer thread — lazy maintenance runs inline every N requests

Quick Start

  1. Copy PakaiWatch.b4xlib to your additional libraries folder and add the library in your project.
  2. Add a filter class by selecting Add New Module -> Class Module -> Rate Limiter.
  3. Name the class "RateLimiter".
  4. Register the filter:
    B4X:
    App.srvr.AddFilter("/*", "RateLimiter", False)
    *note: this library also include a Code Snippet to add this line.
  5. (Optional) Set per-endpoint limits by adding this function to your main module:
    B4X:
    Public Sub GetRateLimitConfig As Map
        Dim Cfg As Map
        Cfg.Initialize
    
        ' 5 req per 10s for API
        Cfg.Put("/api/", Array As Int(5, 10000))
    
        ' 3 req per 30s for auth
        Cfg.Put("/auth/", Array As Int(3, 30000))
    
        ' Per-key overrides (highest priority)
        Dim KeyLimits As Map
        KeyLimits.Initialize
        KeyLimits.Put("trusted-partner-key", Array As Int(100, 60000))
        Cfg.Put("__key_overrides__", KeyLimits)
    
        Return Cfg
    End Sub
Priority Chain

For each request, the applied limit is determined by (highest first):
  1. Key override (matches the Bearer token value)
  2. URI pattern (prefix match against the request path)
  3. Default (10 req / 10 s)

Whitelist

A whitelist.txt is created automatically in File.DirApp. One entry per line — exact IP, IP wildcard, or API key:

B4X:
127.0.0.1
192.168.*
my-trusted-api-key

Lines starting with # are ignored.

Files

File nameDescription
whitelist.txtIP/API key whitelist
security_violations.logTimestamped blocked request log
daily_report_YYYY-MM-DD.txtBlock count summary at midnight

---

Feedback, issues, and feature requests welcome!

Post written by DeepSeek v4 Flash Free

Simple Test:
  1. The easiest way is to clone the repo which contains a Pakai server project with example configuration.
  2. Just run it as it is.
  3. Make sure 127.0.0.1 is not whitelisted in whitelist.txt
  4. Login with wrong password for admin.
  5. You should see status code 429 and message Too Many Request for POST /login but 200 for GET /login in Chrome Developer Tool.
  6. You can also try with the build-in Web API documentation (HelpHandler) - required login.
 

Attachments

  • PakaiWatch.b4xlib
    3.9 KB · Views: 13
Last edited:

aeric

Expert
Licensed User
Longtime User
Version 0.60
Using srvr.CreateThreadSafeMap to replace ReentrantLock
 
Top