2008-12-08 51 views
10

Estoy trabajando en una aplicación web que permite a los usuarios cargar 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?¿Cómo se crean "Alias" en Apache Tomcat?

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> 

Respuesta

9

que pasó mucho más tiempo a investigar esto y encontrar una solución que resuelve la eliminación aleatoria de los archivos de contexto. He encontrado este fragmento en la página web de Apache en la sección de configuración de host:

Puede anidar una o más Contexto elementos dentro de este elemento anfitrión, cada uno representando una aplicación web diferente asociado con este host virtual.

Las máquinas virtuales se almacenan en el archivo server.xml situada en CATALINA_HOME \ conf. Tomcat viene configurado con localhost como el host predeterminado. Por lo tanto, si añadimos el contenido de attachments.xml desde el primer puesto, 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 cerca que se puede llegar a la definición de alias similares a servidor HTTP de Apache, creo.

+1

Hay algunos heredan peligro con esto. Ver mi respuesta para más información –

+0

Muchas gracias por esto. Estaba tratando de encontrar una solución para un 1+ días. Esto funcionó! –

6

hay múltiples opciones.

  1. Uso de Apache como frontend, delegando en Tomcat por mod_jk o mod_proxy
  2. Proporcionar un servlet descarga en su propia aplicación, sirviendo el archivo
  3. solicitado Hacer que el directorio que desea que Tomcat para entregar una aplicación web

cada uno tiene algunos inconvenientes y algunas ventajas. Yo prefiero la primera solución fuertemente por múltiples razones:

  • Mis principales razones son aplicables a los sistemas de unixoid, que está, obviamente, no estamos hablando de: Sólo root puede unir puertos inferiores a 1024, por ejemplo, 80. Por lo tanto, tomcat tendría que ejecutarse como root (sé que hay mecanismos que permiten a los usuarios vincularse a puertos bajos, 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 en el servicio de recursos estáticos que Tomcat (nunca lo he medido, pero me cuesta creer lo contrario)
  • Obviamente, usted sabe cómo crear alias en apache - sería trivial para hacerlo.

Sobre la descarga servlet:

De esta manera se tendría un servlet servir a sus recursos estáticos, que usted puede unirse a las direcciones URL "/ descarga/*" (por ejemplo, en la aplicación que también se ocupa de archivo archivos) que ganaría:

  • Es necesario configurar el directorio donde los archivos se almacenan sólo una vez
  • Si necesita usted puede implementar fácilmente comprobaciones de permisos de inicio de sesión (por ejemplo, requeridos para la descarga)
  • Necesita desplegar 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 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 que se abre para los ataques si no se toman especial cuidado de ellos:

  • Tomcat no sirve a los directorios, pero aplicaciones web. 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); %> o más contenido malicioso.

Una idea adicional: No necesita el extra crosscontext="true". Esto implicaría que la aplicación web que implementa solo para servir sus archivos tiene acceso a otras aplicaciones de Internet, p. es capaz de administrarlos o acceder a sus datos privados. Usualmente no necesitas eso en absoluto, en el caso de tu pregunta definitivamente no quieres eso.

2

Consulte la parte inicial de mi pregunta más reciente sobre cómo hacer esto editando el archivo context.xml How do I add aliases to a Servlet Context in 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.

+2

Para agregar a lo que señaló Paulus. Los alias ahora se pueden definir para Tomcat 7. El [documenation] (http://tomcat.apache.org/tomcat-7.0-doc/config/context.html) debería valer la pena si está ejecutando esta versión. Se pueden agrupar 'aliases ="/shared =/[path to]/shared,/app1a =/[path to]/app1a "' – Chadwick

Cuestiones relacionadas