Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content negotiation module is ignoring Accept directives #1999

Open
adam-arold opened this issue Jul 20, 2020 · 2 comments
Open

Content negotiation module is ignoring Accept directives #1999

adam-arold opened this issue Jul 20, 2020 · 2 comments
Labels

Comments

@adam-arold
Copy link

I'm trying to limit the ContentTypes which can be returned form my Ktor endpoint (this is just an example):

accept(ContentType.Text.JavaScript) {
    get(operation.route) {
        call.respondText("foo" )
    }
}

but Ktor simply ignores ContentType.Text.Javascript even if I don't send that header form the browser.

@adam-arold adam-arold added the bug label Jul 20, 2020
@cy6erGn0m
Copy link
Contributor

Could you please provide a simplified sample? the accept function definitely shouldn't just ignore the missing header and shouldn't pass to the get handler. Is there any chance that it is actually handled by another handler or something is cached somewhere in the browser?

@adam-arold
Copy link
Author

This was discussed on the Kotlin Slack here.

So what happened is that since there was no error handler, Ktor simply swallowed the exception which was thrown. The problem is that the API is not well documented and it is not obvious what receive, receiveParameters, parameters are for.

This is an example which you can use to reproduce this:

import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.application.install
import io.ktor.features.ContentNegotiation
import io.ktor.http.ContentType
import io.ktor.request.receive
import io.ktor.response.respondText
import io.ktor.routing.accept
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.serialization.json
import io.ktor.server.engine.applicationEngineEnvironment
import io.ktor.server.engine.connector
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import kotlinx.serialization.Serializable
fun main(args: Array<String>) {
    val env = applicationEngineEnvironment {
        module {
            example()
        }
        connector {
            port = 8080
            host = "0.0.0.0"
        }
    }
    embeddedServer(Netty, env).apply {
        start(wait = true)
    }
}
@Serializable
data class PostURL(
        val date: String,
        val titleSlug: String,
        val redirectTo: String? = null
)
fun Application.example() {
    install(ContentNegotiation) {
        json()
    }
    routing {
        accept(ContentType.Any) {
            get("/foo/{date}/{titleSlug}") {
                val input = call.receive(PostURL::class)
                println("$input was received.")
                call.respondText("foo")
            }
        }
    }
}

There should be a way to deserialize a path to a data structure without having to use the @Location annotation since ktor might not be present in the codebase where the data structure is.

It should also be clarified with easy to understand examples in the Ktor documentation how these methods work together and what are their limitations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants