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

org.http4k.routing.experimental.StaticRoutingHttpHandler.kt Maven / Gradle / Ivy

There is a newer version: 5.41.0.0
Show newest version
package org.http4k.routing.experimental

import org.http4k.core.Filter
import org.http4k.core.HttpHandler
import org.http4k.core.Method.GET
import org.http4k.core.NoOp
import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status.Companion.METHOD_NOT_ALLOWED
import org.http4k.core.Status.Companion.NOT_FOUND
import org.http4k.core.Uri.Companion.of
import org.http4k.core.then
import org.http4k.routing.Router
import org.http4k.routing.RouterDescription
import org.http4k.routing.RouterMatch
import org.http4k.routing.RouterMatch.MatchedWithoutHandler
import org.http4k.routing.RouterMatch.MatchingHandler
import org.http4k.routing.RouterMatch.MethodNotMatched
import org.http4k.routing.RouterMatch.Unmatched
import org.http4k.routing.RoutingHttpHandler
import org.http4k.routing.friendlyToString

fun static(resourceLoader: Router): RoutingHttpHandler = StaticRoutingHttpHandler("", resourceLoader)

internal data class StaticRoutingHttpHandler(
    private val pathSegments: String,
    private val resourceLoader: Router,
    private val filter: Filter = Filter.NoOp
) : RoutingHttpHandler {

    override val description = RouterDescription(pathSegments)

    override fun withFilter(new: Filter): RoutingHttpHandler = copy(filter = new.then(filter))

    override fun withBasePath(new: String): RoutingHttpHandler = copy(pathSegments = new + pathSegments)

    private val handlerNoFilter = ResourceLoadingHandler(pathSegments, resourceLoader)
    private val handlerWithFilter = filter.then(handlerNoFilter)

    override fun match(request: Request): RouterMatch = handlerNoFilter(request).let {
        if (it.status != NOT_FOUND)
            MatchingHandler(filter.then { _: Request -> it }, description)
        else
            Unmatched(description)
    }

    override fun toString() = description.friendlyToString()

    override fun invoke(request: Request): Response = handlerWithFilter(request)
}

internal class ResourceLoadingHandler(
    private val pathSegments: String,
    private val resourceLoader: Router
) : HttpHandler {

    override fun invoke(request: Request): Response =
        if (request.method == GET && request.uri.path.startsWith(pathSegments))
            when (val matchResult = resourceLoader.match(request.uri(of(convertPath(request.uri.path))))) {
                is MatchingHandler -> matchResult(request)
                is MethodNotMatched -> Response(METHOD_NOT_ALLOWED)
                is Unmatched -> Response(NOT_FOUND)
                is MatchedWithoutHandler -> Response(NOT_FOUND)
            }
        else
            Response(NOT_FOUND)

    private fun convertPath(path: String) =
        if (pathSegments == "/" || pathSegments == "") path else path.replace(pathSegments, "")
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy