11package app
22
33import io.javalin.Javalin
4+ import io.javalin.compression.CompressionStrategy
45import io.javalin.http.BadRequestResponse
56import io.javalin.http.NotFoundResponse
7+ import io.javalin.http.queryParamAsClass
68import io.javalin.http.staticfiles.Location
7- import io.javalin.http.util.NaiveRateLimit
9+ import io.javalin.plugin.bundled.JavalinVuePlugin
10+ import io.javalin.plugin.bundled.RateLimitPlugin
811import io.javalin.vue.VueComponent
9- import io.javalin.http.queryParamAsClass
1012import org.eclipse.jetty.server.HttpConnectionFactory
1113import org.eclipse.jetty.server.Server
1214import org.eclipse.jetty.server.ServerConnector
@@ -17,48 +19,55 @@ import java.util.concurrent.TimeUnit
1719fun main () {
1820
1921 val log = LoggerFactory .getLogger(" app.MainKt" )
20- val app = Javalin .create {
21- it.plugins.enableSslRedirects()
22- it.staticFiles.add(" /public" , Location .CLASSPATH )
23- it.compression.brotliAndGzip()
24- it.jetty.server {
25- Server (QueuedThreadPool (200 , 8 , 120000 )).apply {
26- connectors = arrayOf(ServerConnector (server).apply {
27- port = Config .getPort() ? : 7070
28- idleTimeout = 120_000
29- connectionFactories.filterIsInstance<HttpConnectionFactory >().forEach {
30- it.httpConfiguration.sendServerVersion = false
31- }
32- })
33- }
22+ Javalin .start { config ->
23+ config.bundledPlugins.enableSslRedirects()
24+ config.staticFiles.add(" /public" , Location .CLASSPATH )
25+ config.http.compressionStrategy = CompressionStrategy .GZIP
26+ config.unsafe.jettyInternal.server = Server (QueuedThreadPool (200 , 8 , 120000 )).apply {
27+ connectors = arrayOf(ServerConnector (server).apply {
28+ port = Config .getPort() ? : 7070
29+ idleTimeout = 120_000
30+ connectionFactories.filterIsInstance<HttpConnectionFactory >().forEach {
31+ it.httpConfiguration.sendServerVersion = false
32+ }
33+ })
3434 }
35- it.vue.optimizeDependencies = false
36- }.apply {
37- before(" /api/*" ) { NaiveRateLimit .requestPerTimeUnit(it, 20 , TimeUnit .MINUTES ) }
38- get(" /api/can-load" ) { ctx ->
39- val user = ctx.queryParamAsClass<String >(" user" ).get()
40- if (! UserService .userExists(user)) throw NotFoundResponse ()
41- ctx.status(if (UserService .canLoadUser(user)) 200 else 400 )
35+ config.registerPlugin(RateLimitPlugin ({}))
36+ config.registerPlugin(JavalinVuePlugin { vue ->
37+ vue.optimizeDependencies = false
38+ })
39+
40+ // Routes
41+ config.routes.before(" /api/*" ) { it.with (RateLimitPlugin ::class ).requestPerTimeUnit(20 , TimeUnit .MINUTES ) }
42+ config.routes.get(" /api/can-load" ) { ctx ->
43+ val user = ctx.queryParamAsClass<String >(" user" ).required().get()
44+ // Use quick check that doesn't consume GitHub API requests
45+ // This runs before the spinner is shown
46+ ctx.status(if (UserService .canLoadUserQuick(user)) 200 else 400 )
4247 }
43- get(" /api/user/{user}" ) { ctx ->
48+ config.routes. get(" /api/user/{user}" ) { ctx ->
4449 val user = ctx.pathParam(" user" )
4550 if (! UserService .userExists(user)) throw NotFoundResponse ()
4651 UserService .getUserIfCanLoad(user)?.let { ctx.json(it) } ? : throw BadRequestResponse (" Can't load user" )
4752 }
48- get(" /search" , VueComponent (" search-view" ))
49- get(" /user/{user}" , VueComponent (" user-view" ))
50- ws(" /rate-limit-status" ) { ws ->
53+ config.routes. get(" /search" , VueComponent (" search-view" ))
54+ config.routes. get(" /user/{user}" , VueComponent (" user-view" ))
55+ config.routes. ws(" /rate-limit-status" ) { ws ->
5156 ws.onConnect { GhService .registerClient(it) }
5257 ws.onClose { GhService .unregisterClient(it) }
5358 ws.onError { GhService .unregisterClient(it) }
5459 }
55- after { it.cookie(" gtm-id" , Config .getGtmId() ? : " " ) } // what is this?
56- }.exception(Exception ::class .java) { e, ctx ->
57- log.warn(" Uncaught exception" , e)
58- ctx.status(500 )
59- }.error(404 , " html" ) {
60- it.redirect(" /search" )
61- }.start()
60+ config.routes.after { it.cookie(" gtm-id" , Config .getGtmId() ? : " " ) } // what is this?
61+
62+ // Exception and error handlers
63+ config.routes.exception(Exception ::class .java) { e, ctx ->
64+ log.warn(" Uncaught exception" , e)
65+ ctx.status(500 )
66+ }
67+ config.routes.error(404 , " html" ) {
68+ it.redirect(" /search" )
69+ }
70+ }
6271
6372 UserService .syncWatchers()
6473
0 commit comments