mirror of
https://github.com/gotson/komga.git
synced 2025-12-22 00:13:30 +01:00
feat(api): http eTag caching for all API calls
this will reduce the network load
This commit is contained in:
parent
b30849698d
commit
fe22cb5ce6
5 changed files with 29 additions and 21 deletions
|
|
@ -55,9 +55,11 @@ class SecurityConfiguration(
|
|||
|
||||
// authorize frames for H2 console
|
||||
.and()
|
||||
.headers().frameOptions().sameOrigin()
|
||||
.headers {
|
||||
it.frameOptions().sameOrigin()
|
||||
it.cacheControl().disable() //headers are set in WebMvcConfiguration
|
||||
}
|
||||
|
||||
.and()
|
||||
.httpBasic()
|
||||
|
||||
.and()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ fun filePathToUrl(filePath: String): URL =
|
|||
Paths.get(filePath).toUri().toURL()
|
||||
|
||||
fun ResponseEntity.BodyBuilder.setCachePrivate() =
|
||||
this.cacheControl(CacheControl.maxAge(0, TimeUnit.SECONDS)
|
||||
.cachePrivate()
|
||||
.mustRevalidate()
|
||||
)
|
||||
this.cacheControl(cachePrivate)
|
||||
|
||||
val cachePrivate = CacheControl
|
||||
.maxAge(0, TimeUnit.SECONDS)
|
||||
.noTransform()
|
||||
.cachePrivate()
|
||||
.mustRevalidate()
|
||||
|
|
|
|||
|
|
@ -6,13 +6,15 @@ import org.springframework.stereotype.Component
|
|||
import org.springframework.web.bind.annotation.ControllerAdvice
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||
import org.springframework.web.servlet.NoHandlerFoundException
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||
import org.springframework.web.servlet.mvc.WebContentInterceptor
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
@Configuration
|
||||
class StaticResourceConfiguration : WebMvcConfigurer {
|
||||
class WebMvcConfiguration : WebMvcConfigurer {
|
||||
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
|
||||
if (!registry.hasMappingForPattern("/webjars/**")) {
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
|
|
@ -51,6 +53,17 @@ class StaticResourceConfiguration : WebMvcConfigurer {
|
|||
)
|
||||
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS).cachePublic())
|
||||
}
|
||||
|
||||
override fun addInterceptors(registry: InterceptorRegistry) {
|
||||
registry.addInterceptor(
|
||||
WebContentInterceptor().apply {
|
||||
addCacheMapping(
|
||||
cachePrivate,
|
||||
"/api/**", "/opds/**"
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
|
|
@ -191,16 +191,12 @@ class BookController(
|
|||
fun getBookThumbnail(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@PathVariable bookId: String
|
||||
): ResponseEntity<ByteArray> {
|
||||
): ByteArray {
|
||||
bookRepository.getLibraryId(bookId)?.let {
|
||||
if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.FORBIDDEN)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
|
||||
return bookLifecycle.getThumbnailBytes(bookId)?.let {
|
||||
ResponseEntity.ok()
|
||||
.setCachePrivate()
|
||||
.body(it)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
return bookLifecycle.getThumbnailBytes(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
|
||||
@Operation(description = "Download the book file.")
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.gotson.komga.infrastructure.jooq.UnpagedSorted
|
|||
import org.gotson.komga.infrastructure.security.KomgaPrincipal
|
||||
import org.gotson.komga.infrastructure.swagger.PageableAsQueryParam
|
||||
import org.gotson.komga.infrastructure.swagger.PageableWithoutSortAsQueryParam
|
||||
import org.gotson.komga.infrastructure.web.setCachePrivate
|
||||
import org.gotson.komga.interfaces.rest.dto.BookDto
|
||||
import org.gotson.komga.interfaces.rest.dto.CollectionDto
|
||||
import org.gotson.komga.interfaces.rest.dto.SeriesDto
|
||||
|
|
@ -38,7 +37,6 @@ import org.springframework.data.domain.Pageable
|
|||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.bind.annotation.DeleteMapping
|
||||
|
|
@ -196,16 +194,12 @@ class SeriesController(
|
|||
fun getSeriesThumbnail(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@PathVariable(name = "seriesId") seriesId: String
|
||||
): ResponseEntity<ByteArray> {
|
||||
): ByteArray {
|
||||
seriesRepository.getLibraryId(seriesId)?.let {
|
||||
if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.FORBIDDEN)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
|
||||
return seriesLifecycle.getThumbnailBytes(seriesId)?.let {
|
||||
ResponseEntity.ok()
|
||||
.setCachePrivate()
|
||||
.body(it)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
return seriesLifecycle.getThumbnailBytes(seriesId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
|
||||
@PageableAsQueryParam
|
||||
|
|
|
|||
Loading…
Reference in a new issue