import Foundation
import Kitura
import SwiftRedis
import KituraLimiter
let redis = Redis() // remember to make sure a redis instance is running
redis.connect(host: "localhost", port: 6379) { (redisError: NSError?) in
if let error = redisError {
print("Could not connect to Redis: \(error)")
} else {
print("Redis connected")
// Create a new router
let router = Router()
// By default, Limiter allows 150 requests/hour for each IP address
router.all(middleware: Limiter(redis: redis))
// Handle HTTP GET requests to /
router.get("/") { request, response, next in
response.send("Hello, World!")
next()
}
// Add an HTTP server and connect it to the router
Kitura.addHTTPServer(onPort: 8090, with: router)
// Start the Kitura runloop (this call never returns)
Kitura.run()
}
}func apiToken(request: RouterRequest) -> String {
// use api token from middleware, cookies, etc.
return request.userInfo["apiToken"]
}
func isAdmin(request: RouterRequest) -> Bool {
return request.userInfo["isAdmin"]
}
func onRedisError(request: RouterRequest, response: RouterResponse, next: @escaping NextFunc) throws {
response.status(HTTPStatusCode.internalServerError).send("This service is awful!")
try response.end()
}
func onRateLimited(request: RouterRequest, response: RouterResponse, next: @escaping NextFunc) throws {
response.status(HTTPStatusCode.tooManyRequests).send("I need you to calm down")
try response.end()
}
router.all(middleware:
Limiter(
redis: redis,
by: apiToken, // limit by api token instead of default ip address
total: 2, // 2 req/second
expire: 1000, // 1000 ms
whitelist: isAdmin, // admin users shouldn't be limited
ignoreErrors: true, // is rate limiting really *that* important?
onRedisError: onRedisError, // this is ignored because ignoreErrors is true
skipHeaders: true, // I don't care if my clients know when they can make more requests!
onRateLimited: onRateLimited
)
)