#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")
}