feat: Setup cors and cache

This commit is contained in:
oSumAtrIX 2024-06-08 03:41:48 +02:00
parent 81cc5968d4
commit 205bcde77a
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
8 changed files with 69 additions and 23 deletions

View File

@ -12,3 +12,4 @@ contributors-repositories = [
"revanced-manager",
]
api-version = 1
host = "*.revanced.app"

View File

@ -12,3 +12,4 @@ contributors-repositories = [
"revanced-manager",
]
api-version = 1
host = "*.revanced.app"

View File

@ -39,7 +39,7 @@ internal object StartAPICommand : Runnable {
override fun run() {
embeddedServer(Jetty, port, host) {
configureDependencies(configFile)
configureHTTP(allowedHost = host)
configureHTTP()
configureSerialization()
configureSecurity()
configureRouting()

View File

@ -1,28 +1,20 @@
package app.revanced.api.configuration
import io.ktor.http.*
import io.ktor.http.content.*
import app.revanced.api.configuration.repository.ConfigurationRepository
import io.ktor.server.application.*
import io.ktor.server.plugins.*
import io.ktor.server.plugins.cachingheaders.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.ratelimit.*
import org.koin.ktor.ext.get
import kotlin.time.Duration.Companion.minutes
fun Application.configureHTTP(
allowedHost: String,
) {
fun Application.configureHTTP() {
val configurationRepository = get<ConfigurationRepository>()
install(CORS) {
allowMethod(HttpMethod.Options)
allowMethod(HttpMethod.Put)
allowMethod(HttpMethod.Delete)
allowMethod(HttpMethod.Patch)
allowHeader(HttpHeaders.Authorization)
allowHost(allowedHost)
}
install(CachingHeaders) {
options { _, _ -> CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 5.minutes.inWholeSeconds.toInt())) }
allowHost(host = configurationRepository.host)
}
install(RateLimit) {
register(RateLimitName("weak")) {
rateLimiter(limit = 30, refillPeriod = 2.minutes)

View File

@ -5,13 +5,25 @@ import app.revanced.api.configuration.routes.announcementsRoute
import app.revanced.api.configuration.routes.oldApiRoute
import app.revanced.api.configuration.routes.patchesRoute
import app.revanced.api.configuration.routes.rootRoute
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.plugins.cachingheaders.*
import io.ktor.server.routing.*
import org.koin.ktor.ext.get
import kotlin.time.Duration.Companion.minutes
internal fun Application.configureRouting() = routing {
val configuration = get<ConfigurationRepository>()
install(CachingHeaders) {
options { _, _ ->
CachingOptions(
CacheControl.MaxAge(maxAgeSeconds = 5.minutes.inWholeSeconds.toInt()),
)
}
}
route("/v${configuration.apiVersion}") {
rootRoute()
patchesRoute()

View File

@ -14,4 +14,5 @@ internal class ConfigurationRepository(
val contributorsRepositoryNames: Set<String>,
@SerialName("api-version")
val apiVersion: Int = 1,
val host: String,
)

View File

@ -4,18 +4,30 @@ import app.revanced.api.configuration.respondOrNotFound
import app.revanced.api.configuration.schema.APIAnnouncement
import app.revanced.api.configuration.schema.APIAnnouncementArchivedAt
import app.revanced.api.configuration.services.AnnouncementService
import io.ktor.http.*
import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.plugins.cachingheaders.*
import io.ktor.server.plugins.ratelimit.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.util.*
import kotlin.time.Duration.Companion.minutes
import org.koin.ktor.ext.get as koinGet
internal fun Route.announcementsRoute() = route("announcements") {
val announcementService = koinGet<AnnouncementService>()
install(CachingHeaders) {
options { _, _ ->
CachingOptions(
CacheControl.MaxAge(maxAgeSeconds = 1.minutes.inWholeSeconds.toInt()),
)
}
}
rateLimit(RateLimitName("weak")) {
route("{channel}/latest") {
get("id") {
@ -39,6 +51,7 @@ internal fun Route.announcementsRoute() = route("announcements") {
call.respond(announcementService.all(channel))
}
}
rateLimit(RateLimitName("strong")) {
route("latest") {
get("id") {

View File

@ -4,17 +4,21 @@ import app.revanced.api.configuration.respondOrNotFound
import app.revanced.api.configuration.services.ApiService
import app.revanced.api.configuration.services.AuthService
import io.ktor.http.*
import io.ktor.http.content.CachingOptions
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.http.content.*
import io.ktor.server.plugins.cachingheaders.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.ratelimit.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.koin.ktor.ext.get
import kotlin.time.Duration.Companion.days
import org.koin.ktor.ext.get as koinGet
internal fun Route.rootRoute() {
val apiService = get<ApiService>()
val authService = get<AuthService>()
val apiService = koinGet<ApiService>()
val authService = koinGet<AuthService>()
rateLimit(RateLimitName("strong")) {
authenticate("basic") {
@ -23,16 +27,38 @@ internal fun Route.rootRoute() {
}
}
get("contributors") {
call.respond(apiService.contributors())
route("contributors") {
install(CachingHeaders) {
options { _, _ ->
CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 1.days.inWholeSeconds.toInt()))
}
}
get {
call.respond(apiService.contributors())
}
}
get("team") {
call.respond(apiService.team())
route("team") {
install(CachingHeaders) {
options { _, _ ->
CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 1.days.inWholeSeconds.toInt()))
}
}
get {
call.respond(apiService.team())
}
}
}
route("ping") {
install(CachingHeaders) {
options { _, _ ->
CachingOptions(CacheControl.NoCache(null))
}
}
handle {
call.respond(HttpStatusCode.NoContent)
}