rsocket / rsocket-kotlin

RSocket Kotlin multi-platform implementation
http://rsocket.io
Apache License 2.0
552 stars 37 forks source link

Forward request information to Acceptor#accept (to get the client ip) #231

Open mihai1voicescu opened 2 years ago

mihai1voicescu commented 2 years ago

Forward the request information of Ktor to the Acceptor#accept method so we can see the request headers, IP, and other request details.

Motivation

Determining the IP of the client is impossible now. You can make some hacks to determine it with some degree of certainty but it's not enough. Having access to the ApplicationRequest allows us to access the origin IP and the headers (in case we are behind load balancers).

Desired solution

Forward the ApplicationRequest of Ktor to the Acceptor#accept method.

Considered alternatives

  1. Have a special kind of Acceptor that we can use with Ktor HTTP and WebSockets.

  2. Forward the IP (but this is hard because of load balancers and proxies, usually needs to be done by a higher level with knowledge about the node architecture (eg: number of trusted proxies for x-forwarded-for)).

  3. Pass a "requestContext" map to the acceptor where we can store values regarding the request. Add a callback to Route.RSocket where we get the application context and we can build it.

whyoleg commented 2 years ago

Hi, thanks for report! This is something what could be provided (rsocket-java has access to SocketAddress from connection for example). But this way it will not work for rsocket-kotlin as I don't want to introduce some kind of multiplatform address functionality in rsocket-kotlin. But, I've done some experiments on how it could be done in rsocket-kotlin. Just to give more info: we need to keep in mind, that soon we will have support for Resume, in which case we need to have not a single context value per acceptor, but it should be something like StateFlow<Context>. As you said, if server is behind load balancer, in this case after resume we could have even different server, or f.e. we need to somehow ensure, that we point to the same server to make resume work. Also I want to keep in mind, that some time in the future we will have client LoadBalance API in rsocket-kotlin (as there is such in rsocket-java) and we need to support different transports (tcp/ws/quic) in single LoadBalancer instance while having different contexts per transport.

I will keep in touch here about progress and this most likely will be done in next release with new transport API implementation. No release date yet, because of lack of resources...

Related: #187