Как получить IP-адрес из объекта вызова

#kotlin #ktor

#kotlin #ktor

Вопрос:

Я использую Ktor для серверной службы, и я хотел бы регистрировать входящие запросы. У меня установлена функция, и все отлично, но как я могу получить удаленный IP-адрес?

 call.request.origin.remoteHost
  

Я использую эту строку, но получаю имя хоста, а не IP. Для получения IP-адреса я использую стандартный метод getByName из класса InetAddress.
Есть ли лучший способ?

Ответ №1:

Вы не можете сделать это с помощью Ktor, поскольку в задачу Ktor не входит разрешение IP-адресов из доменов.

Однако вы можете использовать Java InetAddress :

 val url = "http://google.com"; 
val ip =  Inet4Address.getByName(url);
  

Ответ №2:

Зависит от того, насколько точной вы хотите, чтобы эта информация была.

Если вы прочитаете код Ktor, вы увидите, что remoteHost фактически задается из заголовка HTTP X-Forwarded-Host .

Из документации API:

 * NEVER use it for user authentication as it can be easily falsified (user  can simply set some HTTP headers
* such as X-Forwarded-Host so you should NEVER rely on it in any security checks.
* If you are going to use it to create a back-connection please do it with care as an offender can easily
* use it to force you to connect to some host that is not intended to be connected to so that may cause
* serious consequences.
  

Лучшим способом может быть получение IP-адреса из самого движка приложения. К сожалению, ApplicationCall сам объект является частным, поэтому вам придется прибегнуть к рефлексии, что не является оптимальным:

 class RoutingApplicationCall(private val call: ApplicationCall,

  

Тем не менее, это возможно:

 
// Getting the private field through reflection
val f = context::class.memberProperties.find { it.name == "call" }

f?.let {
    // Making it accessible
    it.isAccessible = true
    val w = it.getter.call(context) as NettyApplicationCall

    // Getting the remote address 
    val ip: SocketAddress? = w.request.context.pipeline().channel().remoteAddress()
    println("IP: $ip")
}