Обновление: похоже, это связано с ошибкой Apache: https://bz.apache.org/bugzilla/show_bug.cgi?id=60330
У меня есть приложение Java, которое запускает Jetty 8 как встроенный HTTP-сервер. Это серверная служба, работающая на порту 20000. Код моей реальной службы не имеет отношения. Я создал пример проекта на GitHub, чтобы продемонстрировать проблему: https://github.com/janvanmansum/apache-jetty9-502-error
Основной код показан ниже для справки. Это зависит от пары библиотек:
javax.servlet:javax.servlet-api:3.1.0
commons-io:commons-io:2.5
org.eclipse.jetty:jetty-server:9.4.6.v20170531 or 8.2.0.v20160908
org.eclipse.jetty:jetty-servlet:9.4.6.v20170531 or 8.2.0.v20160908
BackendServer.java
package nl.knaw.dans.test;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
public class BackendServer {
public static void main(String[] args) throws Exception {
Server server = new Server(20000);
ServletContextHandler handler = new ServletContextHandler();
handler.addServlet(AcceptAllServlet.class, "/acceptAll");
handler.addServlet(ReadAllServlet.class, "/readAll");
server.setHandler(handler);
server.start();
server.join();
}
}
AcceptAllServlet
package nl.knaw.dans.test;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AcceptAllServlet extends HttpServlet {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("AcceptAll Servlet OK!");
resp.setStatus(200);
}
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setStatus(201);
}
}
ReadAllServlet
package nl.knaw.dans.test;
import org.apache.commons.io.IOUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
public class ReadAllServlet extends HttpServlet {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("ReadAll Servlet OK!");
resp.setStatus(200);
}
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
FileOutputStream fos = new FileOutputStream("target/outfile");
try {
IOUtils.copy(req.getInputStream(), fos);
}
finally {
fos.close();
}
resp.setStatus(201);
}
}
Сервис доступен для внешнего мира через HTTP-сервер Apache, который служит прокси-сервером, используя следующую конфигурацию:
<VirtualHost *:80>
ProxyTimeout 600
<Location / >
ProxyPass http://localhost:20000/
ProxyPassReverse http://localhost:20000/
</Location>
</VirtualHost>
POST
-ing файлы в серверную службу через Apache отлично работает с Jetty 8 с файлами любого размера. Однако в Jetty 9 я получаю 502 Bad Gateway
ошибка при отправке в AcceptAllServlet и размер файла превышает 256 КБ. Я предполагаю, что это как-то связано с тем, что Apache не завершил запись данных в серверную службу. Однако, если внутренний сервер хочет ответить 401 Unauthorized
Я бы не хотел, чтобы он сначала прочитал все данные, которые он все равно отклонит.
Есть идеи, почему это, по-видимому, изменилось? Я неправильно сконфигурировал Apache или неправильно использую Jetty? Или это ошибка?
Спасибо за любую помощь!