https://kotlinlang.org logo
Title
a

August Lilleaas

08/22/2022, 10:43 AM
hi, folks! I have a question about
is
checks and delegation from a class to an object. Ktor has an extension function on
ApplicationRequest
that uses
when(this)
to check if the request
is
a
ServletApplicationRequest
. The problem is that the actual request object that I call the extension function on, is a
RoutingApplicationRequest
, which is a class that delegates to the original request object. Which in turn causes
is ServletApplicationRequest
to be false, as
is
only seems to check class inheritance hierarchies, and not delegation. Is there a way to work around this? Or is it an issue/bug that Ktor needs to handle differently to work as expected? FYI, here’s the full extension function:
public val ApplicationRequest.javaSecurityPrincipal: Principal?
    get() = when (this) {
        is ServletApplicationRequest -> servletRequest.userPrincipal
        else -> null
    }
and here’s the class that the instance of the request object is a member of:
public class RoutingApplicationRequest(
    override val call: RoutingApplicationCall,
    override val pipeline: ApplicationReceivePipeline,
    request: ApplicationRequest
) : ApplicationRequest by request
e

Emil Kantis

08/22/2022, 11:34 AM
A
ServletApplicationRequest
is a
ApplicationRequest
, but the inverse isn't necessarily true.
If your original request in
RoutingApplicationRequest
is always a
ServletApplicationRequest
you should model it as such and I think it should work then.
a

August Lilleaas

08/22/2022, 11:41 AM
seems like this is an issue that needs to be fixed by ktor - there’s no way to access the original servlet request the way Ktor wraps it and delegates to it. I filed an issue 🙂 https://youtrack.jetbrains.com/issue/KTOR-4784
e

Emil Kantis

08/22/2022, 11:49 AM
You could probably solve it with a slight workaround:
public val RoutingApplicationRequest.routedJavaSecurityPrincipal: Principal?
    get() = when (this.request) {
        is ServletApplicationRequest -> (this.request as ServletApplicationRequest).javaSecurityPrincipal
        else -> null
    }