• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.jsoup.integration.servlets;
2 
3 import org.eclipse.jetty.client.api.Response;
4 import org.eclipse.jetty.proxy.AsyncProxyServlet;
5 import org.eclipse.jetty.proxy.ConnectHandler;
6 import org.eclipse.jetty.server.Handler;
7 import org.eclipse.jetty.servlet.FilterHolder;
8 import org.eclipse.jetty.servlet.FilterMapping;
9 import org.eclipse.jetty.servlet.ServletHandler;
10 import org.eclipse.jetty.servlet.ServletHolder;
11 import org.jsoup.integration.TestServer;
12 
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 
16 import static org.jsoup.integration.servlets.AuthFilter.ProxyRealm;
17 
18 public class ProxyServlet extends AsyncProxyServlet {
19     public static TestServer.ProxySettings ProxySettings = TestServer.proxySettings();
20     public static String Via = "1.1 jsoup test proxy";
21 
22     static {
23         System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
24         // removes Basic, which is otherwise excluded from auth for CONNECT tunnels
25     }
26 
createHandler(boolean alwaysAuth)27     public static Handler createHandler(boolean alwaysAuth) {
28         // ConnectHandler wraps this ProxyServlet and handles CONNECT, which sets up a tunnel for HTTPS requests and is
29         // opaque to the proxy. The ProxyServlet handles simple HTTP requests.
30         AuthFilter authFilter = new AuthFilter(alwaysAuth, true);
31         ConnectHandler connectHandler = new ConnectProxy(authFilter);
32         ServletHandler proxyHandler = new ServletHandler();
33         proxyHandler.addFilterWithMapping(new FilterHolder(authFilter), "/*", FilterMapping.ALL); // auth for HTTP proxy
34         ServletHolder proxyServletHolder = new ServletHolder(ProxyServlet.class); // Holder wraps as it requires maxThreads initialization
35         proxyServletHolder.setAsyncSupported(true);
36         proxyServletHolder.setInitParameter("maxThreads", "8");
37         proxyHandler.addServletWithMapping(proxyServletHolder, "/*");
38         connectHandler.setHandler(proxyHandler);
39 
40         return connectHandler;
41     }
42 
43     @Override
onServerResponseHeaders(HttpServletRequest clientRequest, HttpServletResponse proxyResponse, Response serverResponse)44     protected void onServerResponseHeaders(HttpServletRequest clientRequest, HttpServletResponse proxyResponse, Response serverResponse) {
45         super.onServerResponseHeaders(clientRequest, proxyResponse, serverResponse);
46         proxyResponse.addHeader("Via", Via);
47     }
48 
49     /** Supports CONNECT tunnels */
50     static class ConnectProxy extends ConnectHandler {
51         final AuthFilter authFilter;
52 
ConnectProxy(AuthFilter authFilter)53         public ConnectProxy(AuthFilter authFilter) {
54             this.authFilter = authFilter;
55         }
56 
57         @Override
handleAuthentication(HttpServletRequest req, HttpServletResponse res, String address)58         protected boolean handleAuthentication(HttpServletRequest req, HttpServletResponse res, String address) {
59             boolean accessGranted = authFilter.checkAuth(req);
60             //System.err.println("CONNECT AUTH: " + accessGranted);
61 
62             // need to add the desired auth header if not granted. Returning false here will also send 407 header
63             if (!accessGranted) {
64                 res.setHeader("Proxy-Authenticate", "Basic realm=\"" + ProxyRealm + "\"");
65             }
66             return accessGranted;
67         }
68     }
69 }
70