                     if let _ = redisError {
                         if ignoreErrors {
                             return next()
+                        } else {
+                            return try! onRedisError(request, response, next)
                         }
                     } else {
+
+                        if !skipHeaders {
+                            let lim = json["total"].int!
+                            let rs = ceil((Double(json["reset"].int!) / 1000))
+                            let rem = max(json["remaining"].int!, 0)
+
+                            response.headers.append("X-RateLimit-Limit", value: "\(lim)")
+                            response.headers.append("X-RateLimit-Reset", value: "\(rs)")
+                            response.headers.append("X-RateLimit-Remaining", value: "\(rem)")
+                        }
+
                         if json["remaining"].int! >= 0 {
                             return next()
+                        } else {
+
+                            if !skipHeaders {
+                                let after = (json["reset"].int! - now()) / 1000
+                                response.headers.append("Retry-After", value: "\(after)")
+                            }
+
+                            return try! onRateLimited(request, response, next)
                         }
                     }
-
-                    return try! onRateLimited(request, response, next)
                 }
             }
         }

    return request.remoteAddress
}

public class Limiter: RouterMiddleware {
    let by: By
    let onRateLimited: RouterHandler
    let expire: Int


typealias By = (_ request: RouterRequest) -> String
typealias NextFunc = () -> Void
typealias WhiteList = (_ request: RouterRequest) -> Bool

private func now() -> Int { // ms since epoch
    return Int(Date().timeIntervalSince1970 * 1000)
