diff --git a/Sources/Vapor/Application.swift b/Sources/Vapor/Application.swift index bec54974b4..b00327eeb4 100644 --- a/Sources/Vapor/Application.swift +++ b/Sources/Vapor/Application.swift @@ -7,7 +7,6 @@ public final class Application { public let eventLoopGroupProvider: EventLoopGroupProvider public let eventLoopGroup: EventLoopGroup public var storage: Storage - public var userInfo: [AnyHashable: Any] public private(set) var didShutdown: Bool public var logger: Logger private var isBooted: Bool @@ -71,7 +70,6 @@ public final class Application { self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount) } self.locks = .init() - self.userInfo = [:] self.didShutdown = false self.logger = .init(label: "codes.vapor.application") self.storage = .init(logger: self.logger) @@ -140,7 +138,6 @@ public final class Application { self.logger.trace("Clearing Application storage") self.storage.shutdown() self.storage.clear() - self.userInfo = [:] switch self.eventLoopGroupProvider { case .shared: diff --git a/Sources/Vapor/Authentication/AuthenticationCache.swift b/Sources/Vapor/Authentication/AuthenticationCache.swift index d64c318857..eb6c01845b 100755 --- a/Sources/Vapor/Authentication/AuthenticationCache.swift +++ b/Sources/Vapor/Authentication/AuthenticationCache.swift @@ -84,20 +84,17 @@ extension Request { } } + private struct AuthenticationCacheKey: StorageKey { + typealias Value = AuthenticationCache + } + internal var _authenticationCache: AuthenticationCache { - get { - if let existing = self.userInfo[_authenticationCacheKey] as? AuthenticationCache { - return existing - } else { - let new = AuthenticationCache() - self.userInfo[_authenticationCacheKey] = new - return new - } - } - set { - self.userInfo[_authenticationCacheKey] = newValue + if let existing = self.storage[AuthenticationCacheKey.self] { + return existing + } else { + let new = AuthenticationCache() + self.storage[AuthenticationCacheKey.self] = new + return new } } } - -private let _authenticationCacheKey = "authc" diff --git a/Sources/Vapor/Deprecated.swift b/Sources/Vapor/Deprecated.swift index 6ee7c67edd..61b6d5b256 100644 --- a/Sources/Vapor/Deprecated.swift +++ b/Sources/Vapor/Deprecated.swift @@ -1 +1,31 @@ -// nothing here yet... +extension Application { + private struct UserInfoKey: StorageKey { + typealias Value = [AnyHashable: Any] + } + + @available(*, deprecated, message: "Use storage instead.") + public var userInfo: [AnyHashable: Any] { + get { + self.storage[UserInfoKey.self] ?? [:] + } + set { + self.storage[UserInfoKey.self] = newValue + } + } +} + +extension Request { + private struct UserInfoKey: StorageKey { + typealias Value = [AnyHashable: Any] + } + + @available(*, deprecated, message: "Use storage instead.") + public var userInfo: [AnyHashable: Any] { + get { + self.storage[UserInfoKey.self] ?? [:] + } + set { + self.storage[UserInfoKey.self] = newValue + } + } +} diff --git a/Sources/Vapor/Request/Request.swift b/Sources/Vapor/Request/Request.swift index 916e48fb4e..7824338917 100644 --- a/Sources/Vapor/Request/Request.swift +++ b/Sources/Vapor/Request/Request.swift @@ -128,8 +128,8 @@ public final class Request: CustomStringConvertible { public let eventLoop: EventLoop public var parameters: Parameters - - public var userInfo: [AnyHashable: Any] + + public var storage: Storage public convenience init( application: Application, @@ -181,7 +181,7 @@ public final class Request: CustomStringConvertible { self.remoteAddress = remoteAddress self.eventLoop = eventLoop self.parameters = .init() - self.userInfo = [:] + self.storage = .init() self.isKeepAlive = true self.logger = logger self.logger[metadataKey: "request-id"] = .string(UUID().uuidString) diff --git a/Sources/Vapor/Response/Response.swift b/Sources/Vapor/Response/Response.swift index 727b308931..e07d26e9e4 100644 --- a/Sources/Vapor/Response/Response.swift +++ b/Sources/Vapor/Response/Response.swift @@ -37,6 +37,8 @@ public final class Response: CustomStringConvertible { } internal var upgrader: Upgrader? + + public var storage: Storage /// Get and set `HTTPCookies` for this `HTTPResponse` /// This accesses the `"Set-Cookie"` header. @@ -131,6 +133,7 @@ public final class Response: CustomStringConvertible { self.version = version self.headers = headers self.body = body + self.storage = .init() } } diff --git a/Sources/Vapor/Sessions/Request+Session.swift b/Sources/Vapor/Sessions/Request+Session.swift index b2b37f40ae..28968b83ff 100644 --- a/Sources/Vapor/Sessions/Request+Session.swift +++ b/Sources/Vapor/Sessions/Request+Session.swift @@ -34,21 +34,18 @@ extension Request { public func destroySession() { self._sessionCache.session = nil } + + private struct SessionCacheKey: StorageKey { + typealias Value = SessionCache + } internal var _sessionCache: SessionCache { - get { - if let existing = self.userInfo[_sessionCacheKey] as? SessionCache { - return existing - } else { - let new = SessionCache() - self.userInfo[_sessionCacheKey] = new - return new - } - } - set { - self.userInfo[_sessionCacheKey] = newValue + if let existing = self.storage[SessionCacheKey.self] { + return existing + } else { + let new = SessionCache() + self.storage[SessionCacheKey.self] = new + return new } } } - -private let _sessionCacheKey = "session" diff --git a/Sources/Vapor/Sessions/SessionsMiddleware.swift b/Sources/Vapor/Sessions/SessionsMiddleware.swift index 1ce1ed9913..b1f25fb16e 100644 --- a/Sources/Vapor/Sessions/SessionsMiddleware.swift +++ b/Sources/Vapor/Sessions/SessionsMiddleware.swift @@ -34,32 +34,30 @@ public final class SessionsMiddleware: Middleware { /// See `Middleware.respond` public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture { - // Create a session cache - let cache = SessionCache() - request._sessionCache = cache - cache.middlewareFlag = true + // Signal middleware has been added. + request._sessionCache.middlewareFlag = true // Check for an existing session if let cookieValue = request.cookies[self.configuration.cookieName] { // A cookie value exists, get the session for it. let id = SessionID(string: cookieValue.string) return self.session.readSession(id, for: request).flatMap { data in - cache.session = .init(id: id, data: data ?? .init()) + request._sessionCache.session = .init(id: id, data: data ?? .init()) return next.respond(to: request).flatMap { res in - return self.addCookies(to: res, for: request, cache: cache) + return self.addCookies(to: res, for: request) } } } else { // No cookie value exists, simply respond. return next.respond(to: request).flatMap { response in - return self.addCookies(to: response, for: request, cache: cache) + return self.addCookies(to: response, for: request) } } } /// Adds session cookie to response or clears if session was deleted. - private func addCookies(to response: Response, for request: Request, cache: SessionCache) -> EventLoopFuture { - if let session = cache.session { + private func addCookies(to response: Response, for request: Request) -> EventLoopFuture { + if let session = request._sessionCache.session { // A session exists or has been created. we must // set a cookie value on the response let createOrUpdate: EventLoopFuture