Jetty ProxyServlet with SSL support

11,239

Solution 1

You can use a "ConnectHandler"

http://grepcode.com/file/repo1.maven.org/maven2/org.eclipse.jetty/example-jetty-embedded/8.1.1.v20120215/org/eclipse/jetty/embedded/ProxyServer.java

public class ProxyServer {

    public static void main(String[] args) throws Exception {

        Server server = new Server();
        SelectChannelConnector connector = new SelectChannelConnector();
        connector.setPort(8888);
        server.addConnector(connector);

        HandlerCollection handlers = new HandlerCollection();
        server.setHandler(handlers);

        // Setup proxy servlet
        ServletContextHandler context = new ServletContextHandler(handlers, "/", ServletContextHandler.SESSIONS);
        ServletHolder proxyServlet = new ServletHolder(ProxyServlet.class);
        proxyServlet.setInitParameter("whiteList", "google.com, www.eclipse.org, localhost");
        proxyServlet.setInitParameter("blackList", "google.com/calendar/*, www.eclipse.org/committers/");
        context.addServlet(proxyServlet, "/*");

        // Setup proxy handler to handle CONNECT methods
        ConnectHandler proxy = new ConnectHandler();
        proxy.setWhite(new String[]{"mail.google.com"});
        proxy.addWhite("www.google.com");
        handlers.addHandler(proxy);

        server.start();

    }

}

Solution 2

ZmK's answer is simply a copy of the example from Jetty repositories and does not even work.

Jetty by default does not have an HTTPS Proxy. The AsyncProxyServlet and ProxyServlet classes only do HTTP proxy. In order for you to do an HTTPS proxy, do the following:

  1. Create a class which extends from AsyncProxyServlet class.
  2. Override createHttpClient() method. The key here is that the HttpClient instance which you will create will need an SslContextFactory(). Just set SslContextFactory with appropriate settings on HttpClient object and you will be good to go.

Here is the code example in detail: https://github.com/k2k2e6/jettyHttpsProxy

Solution 3

I'm using the latest release of Jetty currently (9.4.1) and I was able to get HTTPS proxy working by simply adding this to my Proxy Servlet:

@Override
protected HttpClient newHttpClient() {        
    return new HttpClient(new SslContextFactory());
}

Credit to k2k2e6's example which I started with before realizing I could just override this simple method instead of the entire createHttpClient() method.

Share:
11,239
Jochen
Author by

Jochen

Founder of: https://testingbot.com - Cross Browser Testing with Selenium https://headlesstesting.com - Puppeteer and Playwright Cloud Testing

Updated on June 20, 2022

Comments

  • Jochen
    Jochen about 2 years

    I am using Jetty's ProxyServlet as a HTTP proxy.

    After I start the server and add the socks proxy in firefox I can access websites through the proxy without any problems.

    The problem is that when I try to access a HTTPs website through the proxy. Firefox displays a "Server not found" error and during debugging I don't see anything happening in my Java code.

    Am I missing something here to add SSL support to Jetty?

    Here's part of the code:

        Server httpProxy = new Server(8087);
    
        ServletHandler servletHandler = new ServletHandler();
        servletHandler.addServletWithMapping(new ServletHolder(new TunnelProxyServlet()), "/*");
    
        httpProxy.setHandler(servletHandler);
        try {
            httpProxy.start();
        } catch (Exception ex) {
            Logger.getLogger(HttpProxy.class.getName()).log(Level.SEVERE, null, ex);
        }
    
        public class TunnelProxyServlet extends ProxyServlet {
          @Override
          public void init(ServletConfig config) throws ServletException {
            super.init(config);
            System.out.println("init done !");
          }
    
          @Override
          public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
            System.out.println("got a request !");
            super.service(req, res);
          } 
       }
    
  • John
    John about 7 years
    Passing new SslContextFactory() directly info the HttpClient constructor will not work without proper xml config files. By using setTrustAll(true) or new SslContextFactory(true) will work without any extra config. BUT, it's a major security flaw since it will blindly trust all certificates.
  • NumeroUno
    NumeroUno over 5 years
    You can add the truststore path in SSLContextFactory also
  • mj.ghd
    mj.ghd over 5 years
    I'm facing a similar problem, and I'm disappointed with the answer given by the developers at jetty, not sure if you solved it?