Tengo un servidor nginx que funciona a través de https con Sinatra. Cuando intento descargar un archivo jnlp en una configuración que funciona bien en Mongrel y http (sin s), el servidor nginx no entrega el archivo con un error 504. La verificación posterior de los registros indica que este error se debe a que se desbordó el número de identificadores de archivos disponibles, es decir, "24: demasiados archivos abiertos". Correr
sudo lsof -p <nginx worker pid>
me da una lista enorme de archivos, todos luciendo así:
nginx 1771 nobody 11u IPv4 10867997 0t0 TCP localhost:44704->localhost:https (ESTABLISHED)
nginx 1771 nobody 12u IPv4 10868113 0t0 TCP localhost:https->localhost:44704 (ESTABLISHED)
nginx 1771 nobody 13u IPv4 10868114 0t0 TCP localhost:44705->localhost:https (ESTABLISHED)
nginx 1771 nobody 14u IPv4 10868191 0t0 TCP localhost:https->localhost:44705 (ESTABLISHED)
nginx 1771 nobody 15u IPv4 10868192 0t0 TCP localhost:44706->localhost:https (ESTABLISHED)
nginx 1771 nobody 16u IPv4 10868255 0t0 TCP localhost:https->localhost:44706 (ESTABLISHED)
nginx 1771 nobody 17u IPv4 10868256 0t0 TCP localhost:44707->localhost:https (ESTABLISHED)
nginx 1771 nobody 18u IPv4 10868330 0t0 TCP localhost:https->localhost:44707 (ESTABLISHED)
nginx 1771 nobody 19u IPv4 10868331 0t0 TCP localhost:44708->localhost:https (ESTABLISHED)
nginx 1771 nobody 20u IPv4 10868434 0t0 TCP localhost:https->localhost:44708 (ESTABLISHED)
Aumentar la cantidad de archivos que se pueden abrir no es de ayuda, porque entonces nginx simplemente supera ese límite. Y no es de extrañar, parece que está en una especie de bucle para extraer todos los archivos disponibles.
¿Alguna idea de lo que está pasando y cómo solucionarlo?
EDITAR:nginx 0.7.63, ubuntu linux, sinatra 1.0
EDITAR 2:Aquí está el código ofensivo. Es Sinatra sirviendo a jnlp, que finalmente descubrí:
get '/uploader' do
#read in the launch.jnlp file
theJNLP = ""
File.open("/launch.jnlp", "r+") do |file|
while theTemp = file.gets
theJNLP = theJNLP + theTemp
end
end
content_type :jnlp
theJNLP
end
Si sirvo esto con Sinatra vía Mongrel y http, todo funciona bien. Si sirvo esto con Sinatra y nginx a través de https, aparece el error anterior. Todas las demás partes del sitio web parecen ser equivalentes.
EDITAR:Desde entonces, actualicé a Passenger 2.2.14, Ruby 1.9.1, nginx 0.8.40, openssl 1.0.0a y no hubo cambios.
EDITAR:El culpable parece ser redirecciones infinitas debido al uso de SSL. No sé cómo solucionar este problema, aparte de alojar el archivo jnlp en el directorio raíz del servidor (lo cual prefiero no hacer, ya que me limita a una aplicación basada en jnlp a la vez).
Las líneas relevantes de nginx.conf:
# HTTPS server
#
server {
listen 443;
server_name MyServer.org
root /My/Root/Dir;
passenger_enabled on;
expires 1d;
proxy_set_header X-FORWARDED_PROTO https;
proxy_set_header X_FORWARDED_PROTO https;#the almighty google is not clear on which to use
location /upload {
proxy_pass https://127.0.0.1:443;
}
}
Lo curioso de esto es que, primero, estaba colocando el jnlp en un directorio llamado 'uploader', no 'upload', pero aún así pareció desencadenar el problema, ya que esa directiva proxy_pass apareció en los registros. En segundo lugar, nuevamente, mover el jnlp a la raíz evitó el problema, porque no había nada de este proxy debido a ssl.
Entonces, ¿cómo puedo evitar el bucle infinito proxy_pass en nginx?
Respuesta1
nginx está escuchando en el puerto 443. Cuando recibe una solicitud /uploader
, utiliza el proxy para... el puerto 443. Eso es nginx. ¿Parece que deberías conectarte a tu aplicación Sinatra, que está escuchando en algún otro puerto? No conozco bien nginx, pero no parece correcto.