Search code examples
kotlinstatic-filesktor

Ktor not serving static images properly


I have a ktor server, and I'm trying to serve some static assets that are stored in resources folder assets.

static("/assets") {
    resources("assets")
}

For .css files it works when I fetch them with something like http://0.0.0.0:7200/assets/css/main.css, but when I try to fetch images with http://localhost:7200/assets/img/flags/uk.png, it returns a broken image, although it exists.

enter image description here

enter image description here

I've tried different image formats and paths. Also tried different ways of serving the resources, but none worked.

Edit (Beginning of image downloaded from browser): enter image description here

Edit (Beginning of original file, why are they slightly different?): enter image description here


Solution

  • Finally I found the issue. It had nothing to do with Ktor, but with Gradle. Let me explain. I have this configuration in my build.gradle.kts file:

    tasks.processResources {
        from(sourceSets["main"].resources.srcDirs)
        into("$buildDir/resources/main")
        duplicatesStrategy = DuplicatesStrategy.INCLUDE
    
            filter(
                ReplaceTokens::class, "tokens" to mapOf(
                    "BUILD_VERSION" to version,
                    "BUILD_DATE" to DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now()),
                    "BUILD_MACHINE" to InetAddress.getLocalHost().hostName
                )
            )
    }
    

    And for some reason, it was messing around the images. Solution, apply the processing only to the files I want, in this case, only application.conf. So I now have it like this, and it doesn't corrupt image files from resources:

    tasks.processResources {
        from(sourceSets["main"].resources.srcDirs)
        into("$buildDir/resources/main")
        duplicatesStrategy = DuplicatesStrategy.INCLUDE
    
        filesMatching("application.conf") {
            filter(
                ReplaceTokens::class, "tokens" to mapOf(
                    "BUILD_VERSION" to version,
                    "BUILD_DATE" to DateTimeFormatter.ISO_DATE_TIME.format(ZonedDateTime.now()),
                    "BUILD_MACHINE" to InetAddress.getLocalHost().hostName
                )
            )
        }
    }
    

    Thank you all for your willingness to help.