que - ruby on rails tutorial español
Obtener el nombre de host o IP en Ruby on Rails (12)
Estoy en el proceso de mantener una aplicación Ruby on Rails y estoy buscando una forma fácil de encontrar el nombre de host o la dirección IP del cuadro en el que estoy (ya que es una VM y las nuevas instancias pueden tener diferentes nombres de host o direcciones IP) . ¿Hay alguna manera rápida y fácil de hacer esto en Ruby on Rails?
Editar: La respuesta a continuación es correcta, pero la aclaración que proporcionó Craig es útil (ver también el enlace en la respuesta):
El código [a continuación] NO establece una conexión ni envía ningún paquete (a 64.233.187.99 que es google). Como UDP es un protocolo sin estado, connect () simplemente hace una llamada al sistema que determina cómo enrutar los paquetes en función de la dirección y qué interfaz (y, por lo tanto, dirección IP) debe vincular. addr () devuelve una matriz que contiene la familia (AF_INET), el puerto local y la dirección local (que es lo que queremos) del socket.
Desde coderrr.wordpress.com :
require ''socket''
def local_ip
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
UDPSocket.open do |s|
s.connect ''64.233.187.99'', 1
s.addr.last
end
ensure
Socket.do_not_reverse_lookup = orig
end
# irb:0> local_ip
# => "192.168.0.127"
El más simple es host_with_port
en controller.rb
host_port= request.host_with_port
Es probable que tenga múltiples direcciones IP en cada máquina (127.0.0.1, 192.168.0.1, etc.). Si está utilizando * NIX como su sistema operativo, le sugiero usar el hostname
, y luego ejecutar una búsqueda de DNS en eso. Debería poder usar / etc / hosts para definir el nombre de host local para resolver la dirección IP de esa máquina. Hay una funcionalidad similar en Windows, pero no la he usado desde que Windows 95 fue la punta de lanza.
La otra opción sería acceder a un servicio de búsqueda como WhatIsMyIp.com . Estos chicos le devolverán la dirección IP del mundo real. Esto también es algo que puede configurar fácilmente con una secuencia de comandos Perl en un servidor local, si lo prefiere. Creo que 3 líneas más o menos de código para generar la IP remota desde% ENV deberían cubrirlo.
Esta dirección IP utilizada aquí es de Google, pero puede usar cualquier IP accesible.
require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
La respuesta aceptada funciona, pero debe crear un socket para cada solicitud y no funciona si el servidor está en una red local y / o no está conectado a Internet. A continuación, creo que siempre funcionará, ya que está analizando el encabezado de la solicitud.
request.env["SERVER_ADDR"]
Ponga la parte resaltada en los puntos atrás:
`dig #{request.host} +short`.strip # dig gives a newline at the end
O simplemente request.host
si no te importa si es una IP o no.
Prueba esto:
host = `hostname`.strip # Get the hostname from the shell and removing trailing /n
puts host # Output the hostname
Similar a la respuesta usando hostname
, usando el comando externo uname
en UNIX / LINUX:
hostname = `uname -n`.chomp.sub(//..*/,'''') # stripping off "/n" and the network name if present
para las direcciones IP en uso (su máquina podría tener múltiples interfaces de red), podría usar algo como esto:
# on a Mac:
ip_addresses = `ifconfig | grep ''inet '' | grep -v 127.0.0.1 | cut -d'' '' -f 2`.split
=> [''10.2.21.122'',''10.8.122.12'']
# on Linux:
ip_addresses = `ifconfig -a | grep ''inet '' | grep -v 127.0.0.1 | cut -d'':'' -f 2 | cut -d'' '' -f 1`.split
=> [''10.2.21.122'',''10.8.122.12'']
Un servidor generalmente tiene más de una interfaz, al menos una privada y una pública.
Dado que todas las respuestas aquí se relacionan con este escenario simple, una forma más limpia es pedirle a Socket la actual ip_address_list()
como en:
require ''socket''
def my_first_private_ipv4
Socket.ip_address_list.detect{|intf| intf.ipv4_private?}
end
def my_first_public_ipv4
Socket.ip_address_list.detect{|intf| intf.ipv4? and !intf.ipv4_loopback? and !intf.ipv4_multicast? and !intf.ipv4_private?}
end
Ambos devuelven un objeto Addrinfo, por lo que si necesita una cadena, puede usar el método ip_address()
, como en:
ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?
Puede encontrar fácilmente la solución más adecuada para su caso cambiando los métodos Addrinfo utilizados para filtrar la dirección de interfaz requerida.
Request.remote_ip : Request.remote_ip
IP remota()
Determine la dirección IP de origen. REMOTE_ADDR es el estándar pero fallará si el usuario está detrás de un proxy. HTTP_CLIENT_IP y / o HTTP_X_FORWARDED_FOR se establecen por proxies, así que verifica si REMOTE_ADDR es un proxy. HTTP_X_FORWARDED_FOR puede ser una lista delimitada por comas en el caso de múltiples proxies encadenados; la última dirección que no es de confianza es la IP de origen.
Actualización: Ups, lo siento, leí mal la documentación.
Nombre de host
Una forma sencilla de obtener el nombre de host en Ruby es:
require ''socket''
hostname = Socket.gethostname
El inconveniente es que esto depende de que el host sepa su propio nombre porque utiliza el nombre gethostname
o uname
system call, por lo que no funcionará para el problema original.
Funcionalmente, esto es idéntico a la respuesta del hostname
, sin invocar un programa externo. El nombre de host puede o no estar completamente calificado, dependiendo de la configuración de la máquina.
Dirección IP
Desde ruby 1.9, también puede usar la biblioteca de Socket para obtener una lista de direcciones locales. ip_address_list
devuelve una matriz de objetos AddrInfo . La forma de elegir dependerá de lo que quiera hacer y de la cantidad de interfaces que tenga, pero he aquí un ejemplo que simplemente selecciona la primera dirección IP IPV4 sin bucle como una cadena:
require ''socket''
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
io = IO.popen(''hostname'')
hostname = io.readlines
io = IO.popen(''ifconfig'')
ifconfig = io.readlines
ip = ifconfig[11].scan(// /d{1,3}/./d{1,3}/./d{1,3}/./d{1,3}/ /)
Las dos respuestas con require ''socket''
ven bien. Los que tienen request.blah_blah_blah asumen que estás usando Rails.
IO debería estar disponible todo el tiempo. El único problema con esta secuencia de comandos sería que si ifconfig
se ifconfig
en un feudo diferente en sus sistemas, entonces obtendría resultados diferentes para la IP. La búsqueda del nombre de host debe ser sólida como Sears.