src/main/kotlin/de/uapcore/lightpit/AbstractServlet.kt

changeset 335
1eed60b779da
parent 298
1275eb652008
equal deleted inserted replaced
334:2696337baa3d 335:1eed60b779da
31 import jakarta.servlet.http.Cookie 31 import jakarta.servlet.http.Cookie
32 import jakarta.servlet.http.HttpServlet 32 import jakarta.servlet.http.HttpServlet
33 import jakarta.servlet.http.HttpServletRequest 33 import jakarta.servlet.http.HttpServletRequest
34 import jakarta.servlet.http.HttpServletResponse 34 import jakarta.servlet.http.HttpServletResponse
35 import java.sql.SQLException 35 import java.sql.SQLException
36 import java.time.ZoneId
36 import java.util.* 37 import java.util.*
37 38
38 abstract class AbstractServlet : HttpServlet() { 39 abstract class AbstractServlet : HttpServlet() {
39 40
40 companion object { 41 companion object {
42 const val COOKIE_MAX_AGE = 2592000 // 30 days
41 const val LANGUAGE_COOKIE_NAME = "lpit_language" 43 const val LANGUAGE_COOKIE_NAME = "lpit_language"
44 const val TIMEZONE_COOKIE_NAME = "lpit_timezone"
42 } 45 }
43 46
44 protected val logger = MyLogger() 47 protected val logger = MyLogger()
45 48
46 /** 49 /**
134 ) 137 )
135 } else { 138 } else {
136 val sessionLocale = session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) as Locale 139 val sessionLocale = session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) as Locale
137 resp.locale = sessionLocale 140 resp.locale = sessionLocale
138 logger.trace("Continuing session {0} with language {1}", session.id, sessionLocale) 141 logger.trace("Continuing session {0} with language {1}", session.id, sessionLocale)
142 }
143
144 // determine the timezone
145 if (session.getAttribute(Constants.SESSION_ATTR_TIMEZONE) == null) {
146 // timezone selection stored in cookie
147 val cookieTimezone = cookieTimezone(http)
148
149 // if no cookie, fall back to server's timezone (the browser does not transmit one)
150 val timezone = cookieTimezone ?: ZoneId.systemDefault()
151
152 selectTimezone(http, timezone)
153 logger.debug("Timezone for session {0} set to {1}", session.id, timezone)
139 } 154 }
140 155
141 // if this is an error path, bypass the normal flow 156 // if this is an error path, bypass the normal flow
142 if (fullPath.startsWith("/error/")) { 157 if (fullPath.startsWith("/error/")) {
143 http.styleSheets = listOf("error") 158 http.styleSheets = listOf("error")
196 211
197 private fun cookieLanguage(http: HttpRequest): Locale? = 212 private fun cookieLanguage(http: HttpRequest): Locale? =
198 http.request.cookies?.firstOrNull { c -> c.name == LANGUAGE_COOKIE_NAME } 213 http.request.cookies?.firstOrNull { c -> c.name == LANGUAGE_COOKIE_NAME }
199 ?.runCatching {Locale.forLanguageTag(this.value)}?.getOrNull() 214 ?.runCatching {Locale.forLanguageTag(this.value)}?.getOrNull()
200 215
216 protected fun sessionLanguage(http: HttpRequest) = http.session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) as Locale
217
218 private fun cookieTimezone(http: HttpRequest): ZoneId? =
219 http.request.cookies?.firstOrNull { c -> c.name == TIMEZONE_COOKIE_NAME }
220 ?.runCatching { ZoneId.of(this.value)}?.getOrNull()
221
222 protected fun sessionTimezone(http: HttpRequest) = http.session.getAttribute(Constants.SESSION_ATTR_TIMEZONE) as String
223
224 protected fun selectTimezone(http: HttpRequest, zoneId: ZoneId) {
225 http.session.setAttribute(Constants.SESSION_ATTR_TIMEZONE, zoneId.id)
226 val cookie = Cookie(TIMEZONE_COOKIE_NAME, zoneId.id)
227 cookie.isHttpOnly = true
228 cookie.path = http.request.contextPath
229 cookie.maxAge = COOKIE_MAX_AGE
230 http.response.addCookie(cookie)
231 }
232
201 protected fun selectLanguage(http: HttpRequest, locale: Locale) { 233 protected fun selectLanguage(http: HttpRequest, locale: Locale) {
202 http.response.locale = locale 234 http.response.locale = locale
203 http.session.setAttribute(Constants.SESSION_ATTR_LANGUAGE, locale) 235 http.session.setAttribute(Constants.SESSION_ATTR_LANGUAGE, locale)
204 // delete cookie if language selection matches request locale, otherwise set cookie 236 // delete cookie if language selection matches request locale, otherwise set cookie
205 val cookie = Cookie(LANGUAGE_COOKIE_NAME, "") 237 val cookie = Cookie(LANGUAGE_COOKIE_NAME, "")
207 cookie.path = http.request.contextPath 239 cookie.path = http.request.contextPath
208 if (http.request.locale.language == locale.language) { 240 if (http.request.locale.language == locale.language) {
209 cookie.maxAge = 0 241 cookie.maxAge = 0
210 } else { 242 } else {
211 cookie.value = locale.language 243 cookie.value = locale.language
212 cookie.maxAge = 2592000 // 30 days 244 cookie.maxAge = COOKIE_MAX_AGE
213 } 245 }
214 http.response.addCookie(cookie) 246 http.response.addCookie(cookie)
215 } 247 }
216 } 248 }

mercurial