Marc Plano-Lesay
08/31/2022, 11:28 AMrouting {
static("/") {
staticRootFolder = dataDir
files(".")
default("index.html")
}
}
Ktor serves the top-level index.html
, but when requesting a subdirectory, Ktor returns a 404 (but requesting explicitly index.html
in this subdirectory works fine). I also tried default(File(dataDir, "index.html"))
, assuming it would at least serve the top-level index.html
, which isn't the case.
Is there any way to serve those index files in subdirectories?Marc Plano-Lesay
08/31/2022, 12:31 PMprivate fun Routing.addStaticSubdirectory(directory: File, parent: File) {
val routePath = if (directory == parent) {
"/"
} else {
directory.absolutePath.removePrefix(parent.absolutePath)
}
static(routePath) {
directory.listFiles()?.filter { it.isDirectory }?.forEach {
this@addStaticSubdirectory.addStaticSubdirectory(it, directory)
}
files(directory)
default(File(directory, "index.html"))
}
}
But I get the same behaviour - the default only applies to the top-level directory, not subdirectories. I'm done for the night but my next try will be to remove files()
and try adding every file to see how that goes...Aleksei Tirman [JB]
08/31/2022, 12:34 PMfun main() {
embeddedServer(Netty, port = 3333) {
routing {
static("/export") {
files("export", "index.html")
default("index.html")
}
}
}.start(wait = true)
}
fun Route.files(folder: String, fallbackFilePath: String) {
val dir = File(folder)
val combinedDir = staticRootFolder?.resolve(dir) ?: dir
get("{static_path...}") {
val relativePath = call.parameters.getAll("static_path")?.joinToString(File.separator) ?: return@get
val file = combinedDir.combineSafe(relativePath)
val localFile = if (file.isDirectory) File(fallbackFilePath) else file
call.respond(LocalFileContent(localFile, ContentType.defaultForFile(localFile)))
}
}
Marc Plano-Lesay
08/31/2022, 1:13 PMget
block gets displayed for files but not directories)Marc Plano-Lesay
08/31/2022, 1:15 PM{static_path...}
syntax at all)Marc Plano-Lesay
08/31/2022, 1:21 PMindex.html
file in that folder, otherwise serve whatever was requested. I'm just not sure why those routes aren't apparently matching folders when requested...Aleksei Tirman [JB]
08/31/2022, 1:42 PMfun Route.files(folder: String, fallbackFileName: String) {
val dir = File(folder)
val combinedDir = staticRootFolder?.resolve(dir) ?: dir
get("{static_path...}") {
val relativePath = call.parameters.getAll("static_path")?.joinToString(File.separator) ?: return@get
val file = combinedDir.combineSafe(relativePath)
val fallbackFile = file.combineSafe(fallbackFileName)
val localFile = when {
file.isFile -> file
file.isDirectory && fallbackFile.isFile -> fallbackFile
else -> return@get
}
call.respond(LocalFileContent(localFile, ContentType.defaultForFile(localFile)))
}
}
I though you want to serve the same file when a subdirectory is requested but it turns out you want to serve a file with specified name from each subdirectory.Marc Plano-Lesay
08/31/2022, 9:35 PM/foo/
, but /
is caught) isn't caught by the get
block - which results in a 404 regardless of the content of that blockAleksei Tirman [JB]
09/01/2022, 10:15 AMMarc Plano-Lesay
09/01/2022, 11:14 AMMarc Plano-Lesay
09/01/2022, 11:15 AMindex.html
, but it does work for subfoldersMarc Plano-Lesay
09/01/2022, 11:16 AMrouting
block is this:
static {
files(dataDir.absolutePath, "index.html")
default("index.html")
}
Marc Plano-Lesay
09/01/2022, 11:19 AM/index.html
explicitly works fine)Marc Plano-Lesay
09/01/2022, 11:24 AMdefault(File(dataDir, "index.html"))
. Thanks a lot!Marc Plano-Lesay
09/01/2022, 11:25 AMget("{static_path...}")
syntax called/where can I find documentation about that?Marc Plano-Lesay
09/01/2022, 11:26 AM