Как вы создаете "Псевдонимы" в Apache Tomcat?

Я работаю над веб-приложением, которое позволяет пользователям загружать вложения. Эти вложения хранятся на другом диске, чем в веб-приложении. Как я могу создать псевдоним (эквивалентный псевдонимам сервера Apache HTTP) на этом диске, чтобы пользователи могли загружать эти вложения?

В настоящее время я создаю файл контекста и сбрасываю его в CATALINA_HOME/conf/Catalina/localhost, но он получает случайное удаление так часто. Файл контекста называется attachments.xml, и содержимое показано ниже. Я также читал о виртуальных хостах, но если я правильно понимаю, то виртуальный хост не то, что я ищу. Я использую версию 6.0.18 Apache Tomcat.

attachments.xml:

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

Ответ 1

Я потратил гораздо больше времени на изучение этого и нашел решение, которое решает случайное удаление файлов контекста. Я нашел эту выдержку на веб-сайте Apache в разделе конфигурации хоста:

Вы можете вложить один или несколько контекстов элементы внутри этого элемента Host, каждый из которых представляет собой другую сеть приложение, связанное с этим виртуальный хост.

Виртуальные хосты хранятся в файле server.xml, расположенном в каталоге CATALINA_HOME\conf. Tomcat поставляется с локальным хостом в качестве хоста по умолчанию. Итак, если мы добавим содержимое 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>

Это как можно ближе к определению псевдонимов, подобных HTTP-серверу Apache, я думаю.

Ответ 2

Существует несколько вариантов.

  • Использовать Apache как интерфейс, делегируя tomcat mod_jk или mod_proxy
  • Предоставить загрузочный сервлет в своем приложении, обслуживающий запрошенный файл
  • Сделайте каталог, который вы хотите, чтобы tomcat доставлял веб-приложение.

у каждого есть некоторые недостатки и некоторые преимущества. Я предпочитаю первое решение по нескольким причинам:

  • Мои основные причины относятся к системам unixoid, о которых вы, очевидно, не говорите: только root может связывать порты ниже 1024, например. 80. Для этого tomcat должен запускаться как root (я знаю, что есть механики, позволяющие пользователям связываться с низкими портами, но я никогда не использовал их). Обычно Apache запускается с правами root, но эти привилегии отбрасываются, как только порт 80 привязан.
  • Говорят, что Apache намного лучше обслуживает статические ресурсы, чем tomcat (я его никогда не измерял, но трудно поверить в это)
  • Вы, очевидно, знаете, как создавать псевдонимы в apache - было бы тривиально сделать это.

О сервлет загрузки:

Таким образом, у вас будет сервлет, обслуживающий ваши статические ресурсы, которые вы можете привязать к URL-адресам "/download/*" (например, в приложении, которое также обрабатывает загрузку файлов). Вы получите:

  • Вам нужно настроить каталог, в котором ваши файлы хранятся только один раз
  • Если вам нужно, вы можете легко выполнить проверки разрешений (например, для входа в систему)
  • Вам нужно развернуть только одно полностью автономное приложение.
  • Загрузочный сервлет тривиально - найдите файл, задайте его имя и тип файла в потоке вывода и передайте его байтом по байту, затем закройте выходной поток (обязательно обработайте имена файлов атаки типа "/download/../../../../etc/passwd" или "/download/C:/WINDOWS/someimportantfile.xxx" ), например используя конструктор java.io.File, который получает базовый каталог как отдельный параметр.

Третий вариант имеет некоторые серьезные недостатки и открывает вам атаки, если вы не заботитесь о них особо:

  • Tomcat не обслуживает каталоги, а webapps. Для этого "E:/upload/attachments" потребуется хотя бы директория с именем "WEB-INF", содержащая "web.xml". Позаботьтесь о том, чтобы не предоставлять доступ к записи в этот каталог и файл из загружающего веб-приложения. С помощью этого условия вы можете позволить tomcat обслуживать каталог.
  • Однако: сконфигурируйте содержащийся файл web.xml, чтобы он не служил "*.jsp" как jsp, иначе tomcat не просто доставлял jsp файлы, а выполнял их. Представьте, что кто-то загрузил "index.jsp" с <% System.exit(0); %> или более злонамеренным контентом.

Еще одна мысль: вам не нужен дополнительный crosscontext="true". Это подразумевает, что веб-приложение, которое вы развертываете только для обслуживания ваших файлов, имеет доступ к другим веб-приложениям, например. может управлять ими или получать доступ к своим личным данным. Обычно вам это совсем не нужно, в случае вашего вопроса вы определенно этого не хотите.

Ответ 3

См. начальную часть моего нового вопроса о способах сделать это, отредактировав файл context.xml Как добавить псевдонимы в контекст сервлета в java?. По мнению нескольких людей, больше нет необходимости (2012: Tomcat 6 или 7) использовать Apache по причинам производительности по сравнению с Tomcat для обслуживания статического контента.