All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.javalin.http.SinglePageHandler.kt Maven / Gradle / Ivy

The newest version!
/*
 * Javalin - https://javalin.io
 * Copyright 2017 David Åse
 * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
 */

package io.javalin.http

import io.javalin.core.util.Header
import io.javalin.core.util.Util
import io.javalin.http.staticfiles.Location
import io.javalin.http.util.ContextUtil.isLocalhost
import java.net.URL

/**
 * This is just a glorified 404 handler.
 * Ex: app.addSinglePageRoot("/my-path", "index.html")
 * If no routes or static files are found on "/my-path/" (or any subpath), index.html will be returned
 *
 * It also supports custom handlers (as opposed to a file path like above).
 * Ex: app.addSinglePageHandler("/my-path", myHandler)
 * If no routes or static files or single page file paths are found on "/my-path/" (or any subpath), myHandler will handle the request.
 */
class SinglePageHandler {

    data class Page(val url: URL, val cachedHtml: String) {
        fun getHtml(reRead: Boolean) = if (reRead) url.readText() else cachedHtml
    }

    private val pathPageMap = mutableMapOf()
    private val pathHandlerMap = mutableMapOf()

    fun add(hostedPath: String, filePath: String, location: Location) {
        val url = when (location) {
            Location.CLASSPATH -> Util.getResourceUrl(filePath.removePrefix("/")) ?: throw IllegalArgumentException("File at '$filePath' not found. Path should be relative to resource folder.")
            Location.EXTERNAL -> Util.getFileUrl(filePath) ?: throw IllegalArgumentException("External file at '$filePath' not found.")
        }
        pathPageMap[hostedPath] = Page(url, url.readText())
    }

    fun add(hostedPath: String, handler: Handler) {
        pathHandlerMap[hostedPath] = handler
    }

    fun handle(ctx: Context): Boolean {
        val accept = ctx.header(Header.ACCEPT) ?: ""
        if (ContentType.HTML !in accept && "*/*" !in accept && accept != "") return false
        pathPageMap.findByPath(ctx.path())?.let { page ->
            ctx.html(page.getHtml(reRead = ctx.isLocalhost()))
            return true
        }
        pathHandlerMap.findByPath(ctx.path())?.let { handler ->
            handler.handle(ctx)
            return true
        }
        return false
    }

}

private fun  Map.findByPath(requestPath: String) = this.keys.find { requestPath.startsWith(it) }?.let { this[it]!! }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy