UrlCallback.kt
- package com.hexagonkt.http.server.callbacks
- import com.hexagonkt.core.ResourceNotFoundException
- import com.hexagonkt.core.logging.Logger
- import com.hexagonkt.core.media.mediaTypeOfOrNull
- import com.hexagonkt.core.require
- import com.hexagonkt.core.urlOf
- import com.hexagonkt.http.model.ContentType
- import com.hexagonkt.http.handlers.HttpContext
- import java.net.URL
- class UrlCallback(private val url: URL) : (HttpContext) -> HttpContext {
- constructor(url: String) : this(urlOf(url))
- private companion object {
- val logger: Logger = Logger(UrlCallback::class)
- }
- override fun invoke(context: HttpContext): HttpContext {
- val requestPath = when (context.pathParameters.size) {
- 0 -> ""
- 1 -> context.pathParameters.require("0")
- else -> error("URL loading require a single path parameter or none")
- }
- check(!requestPath.contains("..")) { "Requested path cannot contain '..': $requestPath" }
- logger.debug { "Resolving resource: $requestPath" }
- return try {
- if (requestPath.endsWith("/"))
- throw ResourceNotFoundException("$requestPath not found (folder)")
- val url = when {
- requestPath.isEmpty() -> url.toString()
- url.toString() == "classpath:/" -> "classpath:$requestPath"
- else -> "$url/$requestPath"
- }
- val resource = urlOf(url)
- val bytes = resource.readBytes()
- val mediaType = mediaTypeOfOrNull(resource)
- context.ok(bytes, contentType = mediaType?.let { ContentType(it) })
- }
- catch (e: ResourceNotFoundException) {
- context.notFound(e.message ?: "")
- }
- }
- }