10

我正在开发一个允许用户上传附件的 Web 应用程序。这些附件存储在与 Web 应用程序不同的驱动器上。如何为该驱动器创建一个别名(相当于 Apache HTTP 服务器的别名),以便用户可以下载这些附件?

目前我正在创建一个上下文文件并将其转储到 CATALINA_HOME/conf/Catalina/localhost 中,但它经常被随机删除。上下文文件名为 attachments.xml,内容如下所示。我还阅读了有关虚拟主机的信息,但如果我理解正确,那么虚拟主机不是我想要的。我正在使用 6.0.18 版的 Apache Tomcat。

附件.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase    = "e:\uploads\attachments"
     reloadable = "true"
     crossContext   = "true">
</Context>
4

3 回答 3

9

我花了很多时间研究这个问题,找到了解决上下文文件随机删除的解决方案。我在 Apache 的网站上的主机配置部分找到了这段摘录:

您可以在此 Host 元素中嵌套一个或多个 Context 元素,每个元素代表与此虚拟主机关联的不同 Web 应用程序。

虚拟主机存储在位于CATALINA_HOME\conf的server.xml文件中。Tomcat 配置了localhost作为默认主机。因此,如果我们从第一篇文章中添加附件.xml的内容,我们会得到以下内容:

<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>

我认为,这与定义类似于 Apache 的 HTTP 服务器的别名非常接近。

于 2008-12-09T13:36:04.940 回答
7

有多种选择。

  1. 使用 Apache 作为前端,通过 mod_jk 或 mod_proxy 委托给 tomcat
  2. 在您自己的应用程序中提供下载 servlet,为请求的文件提供服务
  3. 制作您希望 tomcat 交付 Web 应用程序的目录

每个都有一些缺点和一些优点。出于多种原因,我非常喜欢第一种解决方案:

  • 我的主要原因适用于 unixoid 系统,你显然不是在谈论:只有 root 可以绑定低于 1024 的端口,例如 80。因此,tomcat 需要以 root 身份运行(我知道有机制允许用户绑定到低端口,但我从来没有使用过它们)。Apache 通常以 root 身份启动,但一旦绑定端口 80,就会放弃这些权限。
  • 据说 Apache 在提供静态资源方面比 tomcat 好很多(我从来没有测量过,但很难相信相反)
  • 您显然知道如何在 apache 中创建别名 - 这样做很简单。

关于下载 servlet:

这样,您将拥有一个为您的静态资源提供服务的 servlet,您可以将其绑定到 URL“/download/*”(例如,在还处理文件上传的应用程序中)您将获得:

  • 您只需要配置一次文件存储的目录
  • 如果您需要,您可以轻松实施权限检查(例如下载需要登录)
  • 您只需部署一个完全独立的应用程序。
  • 下载 servlet 很简单 - 找到文件,在输出流中设置它的名称和文件类型并逐字节流式传输,然后关闭输出流(确保处理攻击文件名,如“/download/../../ ../../etc/passwd" 或 "/download/C:/WINDOWS/someimportantfile.xxx"),例如通过使用获取基目录作为单独参数的 java.io.File 构造函数。

第三种选择有一些严重的缺点,如果你不特别注意它们,就会让你受到攻击:

  • Tomcat 不提供目录,而是提供 webapps。因此“E:/upload/attachments”至少需要一个名为“WEB-INF”的目录,其中包含“web.xml”。注意不要从上传的 Web 应用程序中提供对该目录和文件的写访问权限。有了这个规定,您可以让 tomcat 为目录提供服务。
  • 但是:将包含的 web.xml 配置为不将“*.jsp”作为 jsp 提供,否则 tomcat 不仅会传递 jsp 文件,还会执行它们。<% System.exit(0); %>想象一下有人上传带有或更多恶意内容的“index.jsp” 。

一个额外的想法:你不需要额外的crosscontext="true". 这意味着您部署的只是为您的文件提供服务的 web 应用程序可以访问其他 web 应用程序,例如能够管理它们或访问它们的私有数据。通常你根本不需要那个,在你的问题的情况下你肯定不想要那个。

于 2008-12-14T10:35:15.727 回答
2

See the initial part of my newer question for ways to do this by editing the context.xml file How do I add aliases to a Servlet Context in java?. According to several people now, it is no longer necessary (2012: Tomcat 6 or 7) to use Apache for performance reasons over Tomcat for serving static content.

于 2012-10-03T19:26:18.583 回答