¿Cómo se crean "alias" en Apache Tomcat?
aliases context.xml (3)
Estoy trabajando en una aplicación web que permite a los usuarios subir archivos adjuntos. Estos archivos adjuntos se almacenan en una unidad diferente a la de la aplicación web. ¿Cómo puedo crear un alias (equivalente a los alias del servidor Apache HTTP) en esta unidad para que los usuarios puedan descargar estos archivos adjuntos?
Actualmente estoy creando un archivo de contexto y volcándolo en CATALINA_HOME / conf / Catalina / localhost, pero se elimina al azar de vez en cuando. El archivo de contexto se llama attachments.xml y los contenidos se muestran a continuación. También he leído sobre hosts virtuales, pero si entiendo correctamente, entonces un host virtual no es lo que estoy buscando. Estoy usando la versión 6.0.18 de Apache Tomcat.
attachments.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase = "e:/uploads/attachments"
reloadable = "true"
crossContext = "true">
</Context>
Hay múltiples opciones
- Utilice Apache como frontend, delegando a tomcat mediante mod_jk o mod_proxy
- Proporcione un servlet de descarga en su propia aplicación, sirviendo el archivo solicitado
- Cree el directorio que desea que tomcat entregue una aplicación web
cada uno tiene algunos inconvenientes y algunas ventajas. Yo prefiero la primera solución por varias razones:
- Mis principales razones se aplican a los sistemas unixoid, de los que obviamente no me hablo: solo root puede vincular puertos inferiores a 1024, por ejemplo, 80. Por lo tanto, tomcat debería ejecutarse como root (sé que hay mecanismos que permiten a los usuarios vincularse a bajo puertos, pero nunca he llegado a usarlos). Apache generalmente se inicia como root, pero descarta estos privilegios tan pronto como el puerto 80 está vinculado.
- Se dice que Apache es mucho mejor al servir recursos estáticos que Tomcat (nunca lo he medido, pero me cuesta creer lo contrario)
- Obviamente, sabes cómo crear alias en apache, sería trivial hacerlo.
Acerca del servlet de descarga:
De esta forma, tendrías un servlet al servicio de tus recursos estáticos, que podrías vincular a las URL "/ download / *" (por ejemplo, en la aplicación que también maneja las cargas de archivos). Obtendrás:
- Necesita configurar el directorio donde sus archivos están almacenados solo una vez
- Si lo necesita, puede implementar fácilmente comprobaciones de permisos (por ejemplo, se requiere iniciar sesión para descargar)
- Necesita implementar solo una aplicación completamente autónoma.
- El servlet de descarga es trivial: encuentre el archivo, configure su nombre y tipo de archivo en la secuencia de salida y transmítalo byte a byte, luego cierre la secuencia de salida (asegúrese de manejar los nombres de archivos atacantes como "/download/../../ ../../etc/passwd "o" /download/C:/WINDOWS/someimportantfile.xxx "), por ejemplo, utilizando el constructor java.io.File que obtiene el directorio base como un parámetro separado.
La tercera opción tiene algunos inconvenientes graves y te abre para los ataques si no los cuidas especialmente:
- Tomcat no sirve directorios, pero webapps. Por lo tanto, "E: / upload / attachments" necesitaría al menos un directorio llamado "WEB-INF", que contiene "web.xml". Tenga cuidado de no proporcionar acceso de escritura a este directorio y archivo desde la aplicación web de carga. Con esta disposición, puede dejar que tomcat sirva el directorio.
- Sin embargo: configure el web.xml contenido para que no sirva "* .jsp" como jsp, de lo contrario, tomcat no solo entregaría archivos jsp sino que los ejecutaría. Imagine que alguien carga "index.jsp" con
<% System.exit(0); %>
<% System.exit(0); %>
o más contenido malicioso.
Un pensamiento adicional: no necesita el crosscontext="true"
adicional crosscontext="true"
. Esto implicaría que la aplicación que usted implementa solo para servir sus archivos tiene acceso a otras aplicaciones de Internet, por ejemplo, puede administrarlas o acceder a sus datos privados. Usualmente no necesitas eso en absoluto, en el caso de tu pregunta definitivamente no quieres eso.
Pasé mucho más tiempo investigando esto y encontré una solución que resuelve la eliminación aleatoria de los archivos de contexto. Encontré este extracto en el sitio web de Apache en la sección de configuración del host:
Puede anidar uno o más elementos de contexto dentro de este elemento de host, cada uno de los cuales representa una aplicación web diferente asociada con este host virtual.
Los hosts virtuales se almacenan en el archivo server.xml ubicado en CATALINA_HOME / conf . Tomcat viene configurado con localhost como el host predeterminado. Entonces, si agregamos los contenidos de attachments.xml desde la primera publicación, obtenemos lo siguiente:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/attachments"
docBase="e:/uploads/attachments"
reloadable="true"
crossContext="true" />
</Host>
Esto es lo más cercano que se puede llegar a definir alias similares al servidor HTTP de Apache, creo.
Consulte la parte inicial de mi pregunta más reciente sobre cómo hacerlo editando el archivo context.xml ¿Cómo agrego alias a un contexto de servlet en java? . Según varias personas ahora, ya no es necesario (2012: Tomcat 6 o 7) utilizar Apache por razones de rendimiento sobre Tomcat para servir contenido estático.