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", "revanced-manager",
] ]
api-version = 1 api-version = 1
host = "*.revanced.app"

View File

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

View File

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

View File

@ -1,28 +1,20 @@
package app.revanced.api.configuration package app.revanced.api.configuration
import io.ktor.http.* import app.revanced.api.configuration.repository.ConfigurationRepository
import io.ktor.http.content.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.plugins.* import io.ktor.server.plugins.*
import io.ktor.server.plugins.cachingheaders.*
import io.ktor.server.plugins.cors.routing.* import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.ratelimit.* import io.ktor.server.plugins.ratelimit.*
import org.koin.ktor.ext.get
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.minutes
fun Application.configureHTTP( fun Application.configureHTTP() {
allowedHost: String, val configurationRepository = get<ConfigurationRepository>()
) {
install(CORS) { install(CORS) {
allowMethod(HttpMethod.Options) allowHost(host = configurationRepository.host)
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())) }
} }
install(RateLimit) { install(RateLimit) {
register(RateLimitName("weak")) { register(RateLimitName("weak")) {
rateLimiter(limit = 30, refillPeriod = 2.minutes) 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.oldApiRoute
import app.revanced.api.configuration.routes.patchesRoute import app.revanced.api.configuration.routes.patchesRoute
import app.revanced.api.configuration.routes.rootRoute 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.application.*
import io.ktor.server.plugins.cachingheaders.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
import org.koin.ktor.ext.get import org.koin.ktor.ext.get
import kotlin.time.Duration.Companion.minutes
internal fun Application.configureRouting() = routing { internal fun Application.configureRouting() = routing {
val configuration = get<ConfigurationRepository>() val configuration = get<ConfigurationRepository>()
install(CachingHeaders) {
options { _, _ ->
CachingOptions(
CacheControl.MaxAge(maxAgeSeconds = 5.minutes.inWholeSeconds.toInt()),
)
}
}
route("/v${configuration.apiVersion}") { route("/v${configuration.apiVersion}") {
rootRoute() rootRoute()
patchesRoute() patchesRoute()

View File

@ -14,4 +14,5 @@ internal class ConfigurationRepository(
val contributorsRepositoryNames: Set<String>, val contributorsRepositoryNames: Set<String>,
@SerialName("api-version") @SerialName("api-version")
val apiVersion: Int = 1, 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.APIAnnouncement
import app.revanced.api.configuration.schema.APIAnnouncementArchivedAt import app.revanced.api.configuration.schema.APIAnnouncementArchivedAt
import app.revanced.api.configuration.services.AnnouncementService 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.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
import io.ktor.server.plugins.cachingheaders.*
import io.ktor.server.plugins.ratelimit.* import io.ktor.server.plugins.ratelimit.*
import io.ktor.server.request.* import io.ktor.server.request.*
import io.ktor.server.response.* import io.ktor.server.response.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
import io.ktor.server.util.* import io.ktor.server.util.*
import kotlin.time.Duration.Companion.minutes
import org.koin.ktor.ext.get as koinGet import org.koin.ktor.ext.get as koinGet
internal fun Route.announcementsRoute() = route("announcements") { internal fun Route.announcementsRoute() = route("announcements") {
val announcementService = koinGet<AnnouncementService>() val announcementService = koinGet<AnnouncementService>()
install(CachingHeaders) {
options { _, _ ->
CachingOptions(
CacheControl.MaxAge(maxAgeSeconds = 1.minutes.inWholeSeconds.toInt()),
)
}
}
rateLimit(RateLimitName("weak")) { rateLimit(RateLimitName("weak")) {
route("{channel}/latest") { route("{channel}/latest") {
get("id") { get("id") {
@ -39,6 +51,7 @@ internal fun Route.announcementsRoute() = route("announcements") {
call.respond(announcementService.all(channel)) call.respond(announcementService.all(channel))
} }
} }
rateLimit(RateLimitName("strong")) { rateLimit(RateLimitName("strong")) {
route("latest") { route("latest") {
get("id") { 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.ApiService
import app.revanced.api.configuration.services.AuthService import app.revanced.api.configuration.services.AuthService
import io.ktor.http.* import io.ktor.http.*
import io.ktor.http.content.CachingOptions
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
import io.ktor.server.http.content.* 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.plugins.ratelimit.*
import io.ktor.server.response.* import io.ktor.server.response.*
import io.ktor.server.routing.* 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() { internal fun Route.rootRoute() {
val apiService = get<ApiService>() val apiService = koinGet<ApiService>()
val authService = get<AuthService>() val authService = koinGet<AuthService>()
rateLimit(RateLimitName("strong")) { rateLimit(RateLimitName("strong")) {
authenticate("basic") { authenticate("basic") {
@ -23,16 +27,38 @@ internal fun Route.rootRoute() {
} }
} }
get("contributors") { route("contributors") {
call.respond(apiService.contributors()) install(CachingHeaders) {
options { _, _ ->
CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 1.days.inWholeSeconds.toInt()))
}
} }
get("team") { get {
call.respond(apiService.contributors())
}
}
route("team") {
install(CachingHeaders) {
options { _, _ ->
CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 1.days.inWholeSeconds.toInt()))
}
}
get {
call.respond(apiService.team()) call.respond(apiService.team())
} }
} }
}
route("ping") { route("ping") {
install(CachingHeaders) {
options { _, _ ->
CachingOptions(CacheControl.NoCache(null))
}
}
handle { handle {
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }