|
23 | 23 | import java.util.Set; |
24 | 24 | import java.util.TimeZone; |
25 | 25 | import java.util.concurrent.CompletableFuture; |
| 26 | +import java.util.concurrent.atomic.AtomicLong; |
26 | 27 | import javax.net.ssl.SSLEngine; |
27 | 28 | import javax.net.ssl.SSLException; |
28 | 29 |
|
|
36 | 37 | import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; |
37 | 38 | import org.eclipse.jetty.client.ContentResponse; |
38 | 39 | import org.eclipse.jetty.client.HttpClient; |
| 40 | +import org.eclipse.jetty.client.transport.HttpClientConnectionFactory; |
| 41 | +import org.eclipse.jetty.client.transport.HttpClientTransportDynamic; |
39 | 42 | import org.eclipse.jetty.compression.server.CompressionConfig; |
40 | 43 | import org.eclipse.jetty.compression.server.CompressionHandler; |
41 | 44 | import org.eclipse.jetty.ee11.servlet.DefaultServlet; |
|
54 | 57 | import org.eclipse.jetty.http.MultiPartConfig; |
55 | 58 | import org.eclipse.jetty.http.MultiPartFormData; |
56 | 59 | import org.eclipse.jetty.http.pathmap.PathSpec; |
| 60 | +import org.eclipse.jetty.http2.client.HTTP2Client; |
| 61 | +import org.eclipse.jetty.http2.client.transport.ClientConnectionFactoryOverHTTP2; |
57 | 62 | import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory; |
58 | 63 | import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; |
59 | 64 | import org.eclipse.jetty.http3.server.HTTP3ServerConnectionFactory; |
60 | 65 | import org.eclipse.jetty.http3.server.HTTP3ServerQuicConfiguration; |
| 66 | +import org.eclipse.jetty.io.ClientConnectionFactory; |
| 67 | +import org.eclipse.jetty.io.ClientConnector; |
61 | 68 | import org.eclipse.jetty.io.Content; |
62 | 69 | import org.eclipse.jetty.io.ssl.SslHandshakeListener; |
| 70 | +import org.eclipse.jetty.proxy.ProxyHandler; |
63 | 71 | import org.eclipse.jetty.quic.quiche.server.QuicheServerConnector; |
64 | 72 | import org.eclipse.jetty.quic.quiche.server.QuicheServerQuicConfiguration; |
65 | 73 | import org.eclipse.jetty.rewrite.handler.CompactPathRule; |
@@ -2052,4 +2060,106 @@ public boolean handle(Request request, Response response, Callback callback) |
2052 | 2060 | server.start(); |
2053 | 2061 | // end::dosHandler[] |
2054 | 2062 | } |
| 2063 | + |
| 2064 | + public void proxyNewHttpClient() throws Exception |
| 2065 | + { |
| 2066 | + // tag::proxyNewHttpClient[] |
| 2067 | + Server server = new Server(); |
| 2068 | + ServerConnector connector = new ServerConnector(server); |
| 2069 | + server.addConnector(connector); |
| 2070 | + |
| 2071 | + // Customize the forward proxy's HttpClient transports. |
| 2072 | + ProxyHandler.Forward forwardProxy = new ProxyHandler.Forward() |
| 2073 | + { |
| 2074 | + @Override |
| 2075 | + protected HttpClient newHttpClient() |
| 2076 | + { |
| 2077 | + ClientConnector clientConnector = new ClientConnector(); |
| 2078 | + ClientConnectionFactory.Info http11 = HttpClientConnectionFactory.HTTP11; |
| 2079 | + ClientConnectionFactory.Info http2 = new ClientConnectionFactoryOverHTTP2.HTTP2(new HTTP2Client(clientConnector)); |
| 2080 | + return new HttpClient(new HttpClientTransportDynamic(clientConnector, http11, http2)); |
| 2081 | + } |
| 2082 | + }; |
| 2083 | + |
| 2084 | + server.setHandler(forwardProxy); |
| 2085 | + server.start(); |
| 2086 | + // end::proxyNewHttpClient[] |
| 2087 | + } |
| 2088 | + |
| 2089 | + public void proxyForwardForbidden() throws Exception |
| 2090 | + { |
| 2091 | + // tag::proxyForwardForbidden[] |
| 2092 | + Server server = new Server(); |
| 2093 | + ServerConnector connector = new ServerConnector(server); |
| 2094 | + server.addConnector(connector); |
| 2095 | + |
| 2096 | + // Customize the forward proxy's HttpClient transports. |
| 2097 | + ProxyHandler.Forward forwardProxy = new ProxyHandler.Forward() |
| 2098 | + { |
| 2099 | + @Override |
| 2100 | + public boolean handle(Request clientToProxyRequest, Response proxyToClientResponse, Callback proxyToClientCallback) |
| 2101 | + { |
| 2102 | + String domain = Request.getServerName(clientToProxyRequest); |
| 2103 | + |
| 2104 | + // Allow requests to non-bad domains. |
| 2105 | + if (!domain.contains(".bad.com")) |
| 2106 | + return super.handle(clientToProxyRequest, proxyToClientResponse, proxyToClientCallback); |
| 2107 | + |
| 2108 | + // Deny requests to bad domains. |
| 2109 | + Response.writeError(clientToProxyRequest, proxyToClientResponse, proxyToClientCallback, HttpStatus.FORBIDDEN_403); |
| 2110 | + return true; |
| 2111 | + } |
| 2112 | + }; |
| 2113 | + |
| 2114 | + server.setHandler(forwardProxy); |
| 2115 | + server.start(); |
| 2116 | + // end::proxyForwardForbidden[] |
| 2117 | + } |
| 2118 | + |
| 2119 | + public void proxyReverse() throws Exception |
| 2120 | + { |
| 2121 | + // tag::proxyReverse[] |
| 2122 | + Server server = new Server(); |
| 2123 | + ServerConnector connector = new ServerConnector(server); |
| 2124 | + server.addConnector(connector); |
| 2125 | + |
| 2126 | + // Rewrite the client URI to the backend server. |
| 2127 | + ProxyHandler.Reverse reverseProxy = new ProxyHandler.Reverse( |
| 2128 | + clientToProxyRequest -> HttpURI.build("http://backend1/proxy/" + clientToProxyRequest.getHttpURI().getPathQuery()) |
| 2129 | + ); |
| 2130 | + |
| 2131 | + server.setHandler(reverseProxy); |
| 2132 | + server.start(); |
| 2133 | + // end::proxyReverse[] |
| 2134 | + } |
| 2135 | + |
| 2136 | + public void proxyReverseLoadBalancer() throws Exception |
| 2137 | + { |
| 2138 | + // tag::proxyReverseLoadBalancer[] |
| 2139 | + Server server = new Server(); |
| 2140 | + ServerConnector connector = new ServerConnector(server); |
| 2141 | + server.addConnector(connector); |
| 2142 | + |
| 2143 | + // Rewrite the client URI to the backend server. |
| 2144 | + AtomicLong counter = new AtomicLong(); |
| 2145 | + ProxyHandler.Reverse reverseProxy = new ProxyHandler.Reverse( |
| 2146 | + clientToProxyRequest -> |
| 2147 | + { |
| 2148 | + // Even goes to backend1, odd goes to backend2. |
| 2149 | + long index = counter.getAndIncrement(); |
| 2150 | + int turn = (index & 1) == 0 ? 1 : 2; |
| 2151 | + String backendHost = "backend" + turn; |
| 2152 | + |
| 2153 | + // Rewrite the URI to the chosen backend. |
| 2154 | + return HttpURI.build() |
| 2155 | + .scheme("http") |
| 2156 | + .host(backendHost) |
| 2157 | + .path("/proxy/" + clientToProxyRequest.getHttpURI().getPathQuery()); |
| 2158 | + } |
| 2159 | + ); |
| 2160 | + |
| 2161 | + server.setHandler(reverseProxy); |
| 2162 | + server.start(); |
| 2163 | + // end::proxyReverseLoadBalancer[] |
| 2164 | + } |
2055 | 2165 | } |
0 commit comments