如何创建“别名” 在 Apache Tomcat 中?

发布于 2024-07-09 19:04:49 字数 528 浏览 5 评论 0原文

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

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

attachments.xml:

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

I am working on a web application that allows users to upload attachments. These attachments are stored on a different drive than that of the web application. How can I create an alias (equivalent to Apache HTTP server's aliases) to this drive so that users can download these attachments?

Currently I am creating a context file and dumping it in CATALINA_HOME/conf/Catalina/localhost, but it gets randomly deleted every so often. The context file is named attachments.xml and the contents are shown below. I have also read about virtual hosts, but if I understand correctly, then a virtual host is not what I am looking for. I am using version 6.0.18 of Apache Tomcat.

attachments.xml:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

溺深海 2024-07-16 19:04:49

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

可以嵌套一个或多个Context
该 Host 元素内的元素,
每个代表不同的网络
与此相关的应用程序
虚拟主机。

虚拟主机存储在位于 CATALINA_HOME\confserver.xml 文件中。 Tomcat 配置为 localhost 作为默认主机。 因此,如果我们添加第一篇文章中 attachments.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 服务器的别名非常接近。

I spent a lot more time researching this and found a solution that solves the random deletion of the context files. I found this excerpt on Apache's website under the host configuration section:

You can nest one or more Context
elements inside this Host element,
each representing a different web
application associated with this
virtual host.

The virtual hosts are stored in the server.xml file located at CATALINA_HOME\conf. Tomcat comes configured with localhost as the default host. So, if we add the contents of attachments.xml from the first post, we get the following:

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

This is as close as one can get to defining aliases similar to Apache's HTTP server, I think.

血之狂魔 2024-07-16 19:04:49

有多种选择。

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

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

There are multiple options.

  1. Use Apache as frontend, delegating to tomcat by mod_jk or mod_proxy
  2. Provide a download servlet in your own application, serving the requested file
  3. Make the directory that you want tomcat to deliver a web application

each has some drawbacks and some advantages. I strongly prefer the first solution for multiple reasons:

  • My main reasons apply to unixoid systems, which you are obviously not talking about: Only root can bind ports lower than 1024, e.g. 80. Therefor tomcat would need to run as root (I know that there are mechanics to allow users to bind to low ports, but I've never gotten to use them). Apache is usually started as root but drops these privileges as soon as port 80 is bound.
  • Apache is said to be a lot better in serving static resources than tomcat (I've never measured it, but find it hard to believe the contrary)
  • You obviously know how to create aliases in apache - it would be trivial to do so.

About the download servlet:

This way you'd have a servlet serving your static resources, which you might bind to the urls "/download/*" (e.g. in the application that also handles file uploads) You'd gain:

  • You need to configure the directory where your files are stored only once
  • If you need you might easily implement permission checks (e.g. login required for downloading)
  • You need to deploy only one completely selfcontained application.
  • The download servlet is trivial - find the file, set it's name and filetype in the output stream and stream it byte by byte, then close the output stream (be sure to handle attacking file names like "/download/../../../../etc/passwd" or "/download/C:/WINDOWS/someimportantfile.xxx"), e.g. by using the java.io.File constructor that gets the base directory as a separate parameter.

The third option has some severe drawbacks and opens you for attacks if you don't take special care of them:

  • Tomcat does not serve directories, but webapps. Therefor "E:/upload/attachments" would need at least a directory named "WEB-INF", containing "web.xml". Take care to not provide write access to this directory and file from the uploading web application. With this provision you might let tomcat serve the directory.
  • However: Configure the contained web.xml to not serve "*.jsp" as a jsp, otherwise tomcat would not just deliver jsp files but execute them. Imagine someone uploading "index.jsp" with <% System.exit(0); %> or more malicious content.

One additional thought: You don't need the extra crosscontext="true". This would imply that the webapplication that you deploy just to serve your files has access to other webapplications, e.g. is able to manage them or access their private data. Usually you don't need that at all, in the case of your question you definitely don't want that.

流年里的时光 2024-07-16 19:04:49

请参阅我的新问题的初始部分,了解通过编辑 context.xml 文件来执行此操作的方法
如何向 Servlet 添加别名java 中的上下文?
据一些人称,出于性能原因,不再需要(2012 年:Tomcat 6 或 7)使用 Apache 而不是 Tomcat 来提供静态内容。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文