【问题标题】:Developing a proxy servlet that can handle HTTPS connections开发可以处理 HTTPS 连接的代理 servlet
【发布时间】:2025-11-25 00:30:01
【问题描述】:

我开发了一个 Java servlet,它可以代理来自浏览器的 HTTP 请求。 我在代理 HTTPS 请求时遇到问题。
servlet 似乎没有从浏览器接收任何 HTTPS 请求。
在进一步调查后,我注意到 HTTP 请求似乎以简单的 GET 请求开始,而 HTTPS 请求以 CONNECT 请求开始,如下面的日志摘录所示:

"CONNECT ajax.googleapis.com:443 HTTP/1.1" 200

我的问题是,是否可以使用我的 servlet 处理此请求?

public class MyProxyServlet extends HttpServlet {
    @Override
    public void init(final ServletConfig config) throws ServletException {
        super.init(config);
    }

    @Override
    protected void doGet(final HttpServletRequest request,
            final HttpServletResponse response) throws ServletException,
            IOException {
    }

    @Override
    protected void doPost(final HttpServletRequest request,
            final HttpServletResponse response) throws ServletException,
            IOException {
    }
}

如果是,在哪里以及如何?

【问题讨论】:

  • 您想代理指向不同域的 HTTPS 请求?
  • @home 是的,被代理的请求是任意域
  • 我不是这个主题的专家,但我猜你需要实现一个“真正的”基于 TCP/IP 的代理。您不能只代理 HTTP 级别的 HTTPS 请求 - 它会绕过整个 SSL 信任链...

标签: java servlets https


【解决方案1】:

由于默认的HttpServlet 实现不处理CONNECT 动词,因此您必须在servlet 中覆盖javax.servlet.http.HttpServletService 方法并自己处理CONNECT 方法。最初的实现似乎用这个resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); 忽略了这一点。看看HttpServlet源码http://www.docjar.com/html/api/javax/servlet/http/HttpServlet.java.html

【讨论】:

    【解决方案2】:

    通常,HTTPS 握手和交换由带有浏览器的 servlet 容器处理。对于 servlet,它不需要知道模式是什么。您必须在服务器的配置中定义适当的连接器来侦听 HTTPS,并且无需在 Web 应用程序或 servlet 端进行任何额外操作。无论是通过 http:// 还是 https:// 访问,该请求都将相同地到达 servlet。只是需要将服务器配置为接受 https://

    【讨论】:

    • 您是否检查过您的服务器是否正在侦听 HTTPS 连接器?默认的 HTTPS 端口是 443,在 tomcat 或其他 servlet 容器中通常是 8443。我愿意学习 :)
    • 浏览器通常不使用 HTTPS 与代理服务器通信。他们使用 HTTP 进行交谈。如果浏览器通过代理服务器连接到互联网并且用户尝试导航到安全网站,则浏览器通过 HTTP 向代理服务器发出“连接”命令。看看上面的链接——你会看到 HTTP 实际上支持 CONNECT,但 javax.servlet.http.HttpServlet 类中似乎没有 doConnect 处理程序。我的结论是 servlet API 根本不支持这个命令。谢谢
    • 那你为什么不在你的servlet中覆盖javax.servlet.http.HttpServletService方法并自己处理CONNECT方法呢?最初的实现似乎用这个resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); 忽略了这一点。看一下HttpServlet代码http://www.docjar.com/html/api/javax/servlet/http/HttpServlet.java.html
    • 这是一个很好的建议 - 谢谢你会尝试的。您可能想添加您的评论作为答案,我会接受。