5555import org .littleshoot .proxy .HttpProxyServerBootstrap ;
5656import org .littleshoot .proxy .impl .DefaultHttpProxyServer ;
5757import org .littleshoot .proxy .impl .ProxyUtils ;
58+ import org .littleshoot .proxy .impl .ThreadPoolConfiguration ;
5859import org .openqa .selenium .Proxy ;
5960import org .slf4j .Logger ;
6061import org .slf4j .LoggerFactory ;
@@ -198,6 +199,11 @@ public class BrowserMobProxyServer implements BrowserMobProxy, LegacyProxyServer
198199 */
199200 private volatile InetSocketAddress upstreamProxyAddress ;
200201
202+ /**
203+ * The chained proxy manager that manages upstream proxies.
204+ */
205+ private volatile ChainedProxyManager chainedProxyManager ;
206+
201207 /**
202208 * The address and socket on which the proxy will listen for client requests.
203209 */
@@ -232,6 +238,11 @@ public class BrowserMobProxyServer implements BrowserMobProxy, LegacyProxyServer
232238
233239 private final ActivityMonitor activityMonitor = new ActivityMonitor ();
234240
241+ /**
242+ * The acceptor and worker thread configuration for the Netty thread pools.
243+ */
244+ private volatile ThreadPoolConfiguration threadPoolConfiguration ;
245+
235246 /**
236247 * Adapter to enable clients to switch to a LittleProxy implementation of BrowserMobProxy but maintain compatibility with
237248 * the 2.0.0 interface.
@@ -341,20 +352,29 @@ public int getMaximumResponseBufferSizeInBytes() {
341352 bootstrap .withThrottling (readBandwidthLimitBps , writeBandwidthLimitBps );
342353 }
343354
344- if (upstreamProxyAddress != null ) {
355+ if (chainedProxyManager != null ) {
356+ bootstrap .withChainProxyManager (chainedProxyManager );
357+ } else if (upstreamProxyAddress != null ) {
345358 bootstrap .withChainProxyManager (new ChainedProxyManager () {
346359 @ Override
347360 public void lookupChainedProxies (HttpRequest httpRequest , Queue <ChainedProxy > chainedProxies ) {
348- chainedProxies .add (new ChainedProxyAdapter () {
349- @ Override
350- public InetSocketAddress getChainedProxyAddress () {
351- return upstreamProxyAddress ;
352- }
353- });
361+ final InetSocketAddress upstreamProxy = upstreamProxyAddress ;
362+ if (upstreamProxy != null ) {
363+ chainedProxies .add (new ChainedProxyAdapter () {
364+ @ Override
365+ public InetSocketAddress getChainedProxyAddress () {
366+ return upstreamProxy ;
367+ }
368+ });
369+ }
354370 }
355371 });
356372 }
357373
374+ if (threadPoolConfiguration != null ) {
375+ bootstrap .withThreadPoolConfiguration (threadPoolConfiguration );
376+ }
377+
358378 proxyServer = bootstrap .start ();
359379 }
360380
@@ -1128,6 +1148,8 @@ public boolean waitForQuiescence(long quietPeriod, long timeout, TimeUnit timeUn
11281148 /**
11291149 * Instructs this proxy to route traffic through an upstream proxy. Proxy chaining is not compatible with man-in-the-middle
11301150 * SSL, so HAR capture will be disabled for HTTPS traffic when using an upstream proxy.
1151+ * <p/>
1152+ * <b>Note:</b> Using {@link #setChainedProxyManager(ChainedProxyManager)} will supersede any value set by this method.
11311153 *
11321154 * @param chainedProxyAddress address of the upstream proxy
11331155 */
@@ -1141,6 +1163,34 @@ public InetSocketAddress getChainedProxy() {
11411163 return upstreamProxyAddress ;
11421164 }
11431165
1166+ /**
1167+ * Allows access to the LittleProxy {@link ChainedProxyManager} for fine-grained control of the chained proxies. To enable a single
1168+ * chained proxy, {@link BrowserMobProxy#setChainedProxy(InetSocketAddress)} is generally more convenient.
1169+ *
1170+ * @param chainedProxyManager chained proxy manager to enable
1171+ */
1172+ public void setChainedProxyManager (ChainedProxyManager chainedProxyManager ) {
1173+ if (isStarted ()) {
1174+ throw new IllegalStateException ("Cannot configure chained proxy manager after proxy has started." );
1175+ }
1176+
1177+ this .chainedProxyManager = chainedProxyManager ;
1178+ }
1179+
1180+ /**
1181+ * Configures the Netty thread pool used by the LittleProxy back-end. See {@link ThreadPoolConfiguration} for details.
1182+ *
1183+ * @param threadPoolConfiguration thread pool configuration to use
1184+ *
1185+ */
1186+ public void setThreadPoolConfiguration (ThreadPoolConfiguration threadPoolConfiguration ) {
1187+ if (isStarted ()) {
1188+ throw new IllegalStateException ("Cannot configure thread pool after proxy has started." );
1189+ }
1190+
1191+ this .threadPoolConfiguration = threadPoolConfiguration ;
1192+ }
1193+
11441194 @ Override
11451195 public void addFirstHttpFilterFactory (HttpFiltersSource filterFactory ) {
11461196 filterFactories .add (0 , filterFactory );
0 commit comments