All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.lightbody.bmp.proxy.ProxyServer Maven / Gradle / Ivy

The newest version!
package net.lightbody.bmp.proxy;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.core.har.HarEntry;
import net.lightbody.bmp.core.har.HarLog;
import net.lightbody.bmp.core.har.HarNameVersion;
import net.lightbody.bmp.core.har.HarPage;
import net.lightbody.bmp.core.util.ThreadUtils;
import net.lightbody.bmp.exception.JettyException;
import net.lightbody.bmp.exception.NameResolutionException;
import net.lightbody.bmp.filters.RequestFilter;
import net.lightbody.bmp.filters.ResponseFilter;
import net.lightbody.bmp.mitm.TrustSource;
import net.lightbody.bmp.proxy.auth.AuthType;
import net.lightbody.bmp.proxy.dns.AdvancedHostResolver;
import net.lightbody.bmp.proxy.http.BrowserMobHttpClient;
import net.lightbody.bmp.proxy.http.RequestInterceptor;
import net.lightbody.bmp.proxy.http.ResponseInterceptor;
import net.lightbody.bmp.proxy.jetty.http.HttpContext;
import net.lightbody.bmp.proxy.jetty.http.HttpListener;
import net.lightbody.bmp.proxy.jetty.http.SocketListener;
import net.lightbody.bmp.proxy.jetty.jetty.Server;
import net.lightbody.bmp.proxy.jetty.util.InetAddrPort;
import net.lightbody.bmp.util.BrowserMobProxyUtil;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponseInterceptor;
import org.java_bandwidthlimiter.BandwidthLimiter;
import org.java_bandwidthlimiter.StreamManager;
import org.littleshoot.proxy.HttpFiltersSource;
import org.littleshoot.proxy.MitmManager;
import org.openqa.selenium.Proxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

/**
 * The legacy, Jetty 5-based implementation of BrowserMobProxy. This class implements the {@link net.lightbody.bmp.proxy.LegacyProxyServer}
 * interface that defines the BMP 2.0 contact, as well as the 2.1+ {@link BrowserMobProxy} interface. Important: if
 * you are implementing new code, use the {@link BrowserMobProxy} interface. The
 * {@link net.lightbody.bmp.proxy.LegacyProxyServer} interface is deprecated and will be removed in a future release.
 * 

Unsupported operations

* The following {@link BrowserMobProxy} operations are not supported and will be ignored: *
    *
  • {@link BrowserMobProxy#getServerBindAddress()} and {@link #start(int, java.net.InetAddress, java.net.InetAddress)} - server bind addresses are not supported
  • *
  • {@link BrowserMobProxy#stopAutoAuthorization(String)}
  • *
* * @deprecated Use the {@link BrowserMobProxy} interface to preserve compatibility with future BrowserMob Proxy versions. */ @Deprecated public class ProxyServer implements LegacyProxyServer, BrowserMobProxy { private static final HarNameVersion CREATOR = new HarNameVersion("BrowserMob Proxy", BrowserMobProxyUtil.getVersionString() + "-legacy"); private static final Logger LOG = LoggerFactory.getLogger(ProxyServer.class); /** * System property to allow fallback to the native Java hostname lookup mechanism when dnsjava (xbill) cannot resolve the hostname. Native fallback * is enabled by default and will be disabled only if the value of this property is explicitly set to false. */ public static final String ALLOW_NATIVE_DNS_FALLBACK = "bmp.allowNativeDnsFallback"; /* * The Jetty HttpServer use in BrowserMobProxyHandler */ private Server server; /* * Proxy port. Defaults to 0 (JVM-assigned). */ private int port = 0; private InetAddress localHost; private BrowserMobHttpClient client; private StreamManager streamManager; private HarPage currentPage; private BrowserMobProxyHandler handler; private AtomicInteger pageCount = new AtomicInteger(1); private AtomicInteger requestCounter = new AtomicInteger(0); private boolean started; private InetSocketAddress chainedProxyAddress; public ProxyServer() { } public ProxyServer(int port) { this.port = port; } @Override public void start() { //create a stream manager that will be capped to 100 Megabits //remember that by default it is disabled! streamManager = new StreamManager( 100 * BandwidthLimiter.OneMbps ); server = new Server(); HttpListener listener = new SocketListener(new InetAddrPort(getLocalHost(), getPort())); server.addListener(listener); HttpContext context = new HttpContext(); context.setContextPath("/"); server.addContext(context); handler = new BrowserMobProxyHandler(); handler.setJettyServer(server); handler.setShutdownLock(new Object()); client = new BrowserMobHttpClient(streamManager, requestCounter); // if native DNS fallback is explicitly disabled, replace the default resolver with a dnsjava-only resolver if ("false".equalsIgnoreCase(System.getProperty(ALLOW_NATIVE_DNS_FALLBACK))) { client.setResolver(ClientUtil.createDnsJavaResolver()); } client.prepareForBrowser(); handler.setHttpClient(client); context.addHandler(handler); try { server.start(); } catch (Exception e) { // wrapping unhelpful Jetty Exception into a RuntimeException throw new JettyException("Exception occurred when starting the server", e); } setPort(listener.getPort()); started = true; } @Override public void start(int port) { this.port = port; start(); } @Override public void start(int port, InetAddress bindAddress) { setLocalHost(bindAddress); start(port); } @Override public void start(int port, InetAddress clientBindAddress, InetAddress serverBindAddress) { LOG.warn("The legacy ProxyServer implementation does not support a server bind address"); } @Override public boolean isStarted() { return started; } @Override public org.openqa.selenium.Proxy seleniumProxy() throws NameResolutionException { Proxy proxy = new Proxy(); proxy.setProxyType(Proxy.ProxyType.MANUAL); InetAddress connectableLocalHost; try { connectableLocalHost = getConnectableLocalHost(); } catch (UnknownHostException e) { // InetAddress cannot resolve a local host. since seleniumProxy() is designed to be called within a Selenium test, // this is most likely a fatal error that does not need to be a checked exception. throw new NameResolutionException("Error getting local host when creating seleniumProxy", e); } String proxyStr = String.format("%s:%d", connectableLocalHost.getCanonicalHostName(), getPort()); proxy.setHttpProxy(proxyStr); proxy.setSslProxy(proxyStr); return proxy; } @Override public void cleanup() { if (handler != null) { handler.cleanup(); } } @Override public void stop() { cleanup(); if (client != null) { client.shutdown(); } try { if (server != null) { server.stop(); } } catch (InterruptedException e) { // the try/catch block in server.stop() is manufacturing a phantom InterruptedException, so this should not occur throw new JettyException("Exception occurred when stopping the server", e); } } @Override public void abort() { stop(); } @Override public InetAddress getClientBindAddress() { return getLocalHost(); } public int getPort() { return port; } @Override public InetAddress getServerBindAddress() { LOG.warn("LegacyProxyServer does not support a server bind address"); return null; } public void setPort(int port) { this.port = port; } /** * Get the the InetAddress that the Proxy server binds to when it starts. * * If not otherwise set via {@link #setLocalHost(InetAddress)}, defaults to * 0.0.0.0 (i.e. bind to any interface). * * Note - just because we bound to the address, doesn't mean that it can be * reached. E.g. trying to connect to 0.0.0.0 is going to fail. Use * {@link #getConnectableLocalHost()} if you're looking for a host that can be * connected to. */ @Override public InetAddress getLocalHost() { if (localHost == null) { try { localHost = InetAddress.getByName("0.0.0.0"); } catch (UnknownHostException e) { // InetAddress.getByName javadocs state: "If a literal IP address is supplied, only the validity of the address format is checked." // Since the format of 0.0.0.0 is valid, getByName should never throw UnknownHostException throw new RuntimeException("InetAddress.getByName failed to look up 0.0.0.0", e); } } return localHost; } /** * Return a plausible {@link InetAddress} that other processes can use to * contact the proxy. * * In essence, this is the same as {@link #getLocalHost()}, but avoids * returning 0.0.0.0. as no-one can connect to that. If no other host has * been set via {@link #setLocalHost(InetAddress)}, will return * {@link InetAddress#getLocalHost()} * * No attempt is made to check the address for reachability before it is * returned. */ @Override public InetAddress getConnectableLocalHost() throws UnknownHostException { if (getLocalHost().equals(InetAddress.getByName("0.0.0.0"))) { return InetAddress.getLocalHost(); } else { return getLocalHost(); } } @Override public void setLocalHost(InetAddress localHost) { if (localHost.isAnyLocalAddress() || localHost.isLoopbackAddress()) { this.localHost = localHost; } else { // address is not a local/loopback address, but might still be bound to a local network interface NetworkInterface localInterface; try { localInterface = NetworkInterface.getByInetAddress(localHost); } catch (SocketException e) { throw new IllegalArgumentException("localHost address must be address of a local adapter (attempted to use: " + localHost + ")", e); } if (localInterface != null) { this.localHost = localHost; } else { throw new IllegalArgumentException("localHost address must be address of a local adapter (attempted to use: " + localHost + ")"); } } } @Override public Har getHar() { // Wait up to 5 seconds for all active requests to cease before returning the HAR. // This helps with race conditions but won't cause deadlocks should a request hang // or error out in an unexpected way (which of course would be a bug!) boolean success = ThreadUtils.pollForCondition(new ThreadUtils.WaitCondition() { @Override public boolean checkCondition() { return requestCounter.get() == 0; } }, 5, TimeUnit.SECONDS); if (!success) { LOG.warn("Waited 5 seconds for requests to cease before returning HAR; giving up!"); } return client.getHar(); } @Override public Har newHar() { return newHar(null); } public Har newHar(String initialPageRef) { return newHar(initialPageRef, null); } @Override public Har newHar(String initialPageRef, String initialPageTitle) { pageCount.set(0); // this will be automatically incremented by newPage() below Har oldHar = getHar(); Har har = new Har(new HarLog(CREATOR)); client.setHar(har); newPage(initialPageRef, initialPageTitle); return oldHar; } @Override public void setHarCaptureTypes(Set captureTypes) { setCaptureBinaryContent(captureTypes.contains(CaptureType.REQUEST_BINARY_CONTENT) || captureTypes.contains(CaptureType.RESPONSE_BINARY_CONTENT)); setCaptureContent(captureTypes.contains(CaptureType.REQUEST_CONTENT) || captureTypes.contains(CaptureType.RESPONSE_CONTENT)); setCaptureHeaders(captureTypes.contains(CaptureType.REQUEST_HEADERS) || captureTypes.contains(CaptureType.RESPONSE_HEADERS)); } @Override public void setHarCaptureTypes(CaptureType... captureTypes) { if (captureTypes == null) { setHarCaptureTypes(EnumSet.noneOf(CaptureType.class)); } else { setHarCaptureTypes(EnumSet.copyOf(Arrays.asList(captureTypes))); } } @Override public EnumSet getHarCaptureTypes() { // cookie capture types are always enabled in the legacy ProxyServer EnumSet captureTypes = CaptureType.getCookieCaptureTypes(); if (client.isCaptureBinaryContent()) { captureTypes.addAll(CaptureType.getBinaryContentCaptureTypes()); } if (client.isCaptureContent()) { captureTypes.addAll(CaptureType.getNonBinaryContentCaptureTypes()); } if (client.isCaptureHeaders()) { captureTypes.addAll(CaptureType.getHeaderCaptureTypes()); } return captureTypes; } @Override public void enableHarCaptureTypes(Set captureTypes) { if (captureTypes.contains(CaptureType.REQUEST_BINARY_CONTENT) || captureTypes.contains(CaptureType.RESPONSE_BINARY_CONTENT)) { setCaptureBinaryContent(true); } if (captureTypes.contains(CaptureType.REQUEST_CONTENT) || captureTypes.contains(CaptureType.RESPONSE_CONTENT)) { setCaptureContent(true); } if (captureTypes.contains(CaptureType.REQUEST_HEADERS) || captureTypes.contains(CaptureType.RESPONSE_HEADERS)) { setCaptureHeaders(true); } } @Override public void enableHarCaptureTypes(CaptureType... captureTypes) { if (captureTypes == null) { enableHarCaptureTypes(EnumSet.noneOf(CaptureType.class)); } else { enableHarCaptureTypes(EnumSet.copyOf(Arrays.asList(captureTypes))); } } @Override public void disableHarCaptureTypes(Set captureTypes) { if (captureTypes.contains(CaptureType.REQUEST_BINARY_CONTENT) || captureTypes.contains(CaptureType.RESPONSE_BINARY_CONTENT)) { setCaptureBinaryContent(false); } if (captureTypes.contains(CaptureType.REQUEST_CONTENT) || captureTypes.contains(CaptureType.RESPONSE_CONTENT)) { setCaptureContent(false); } if (captureTypes.contains(CaptureType.REQUEST_HEADERS) || captureTypes.contains(CaptureType.RESPONSE_HEADERS)) { setCaptureHeaders(false); } } @Override public void disableHarCaptureTypes(CaptureType... captureTypes) { if (captureTypes == null) { disableHarCaptureTypes(EnumSet.noneOf(CaptureType.class)); } else { disableHarCaptureTypes(EnumSet.copyOf(Arrays.asList(captureTypes))); } } @Override public Har newPage() { return newPage(null); } public Har newPage(String pageRef) { return newPage(pageRef, null); } @Override public Har newPage(String pageRef, String pageTitle) { if (pageRef == null) { pageRef = "Page " + pageCount.get(); } if (pageTitle == null) { pageTitle = pageRef; } client.setHarPageRef(pageRef); currentPage = new HarPage(pageRef, pageTitle); client.getHar().getLog().addPage(currentPage); pageCount.incrementAndGet(); return client.getHar(); } @Override public Har endHar() { endPage(); return getHar(); } @Override public void setReadBandwidthLimit(long bytesPerSecond) { getStreamManager().setDownstreamKbps(bytesPerSecond / 1024L); } @Override public long getReadBandwidthLimit() { return getStreamManager().getMaxDownstreamKB() * 1024L; } @Override public void setWriteBandwidthLimit(long bytesPerSecond) { getStreamManager().setUpstreamKbps(bytesPerSecond / 1024L); } @Override public long getWriteBandwidthLimit() { return getStreamManager().getMaxUpstreamKB() * 1024L; } @Override public void setLatency(long latency, TimeUnit timeUnit) { getStreamManager().setLatency(TimeUnit.MILLISECONDS.convert(latency, timeUnit)); } @Override public void setConnectTimeout(int connectionTimeout, TimeUnit timeUnit) { setConnectionTimeout((int) TimeUnit.MILLISECONDS.convert(connectionTimeout, timeUnit)); } @Override public void setIdleConnectionTimeout(int idleConnectionTimeout, TimeUnit timeUnit) { setSocketOperationTimeout((int) TimeUnit.MILLISECONDS.convert(idleConnectionTimeout, timeUnit)); } @Override public void setRequestTimeout(int requestTimeout, TimeUnit timeUnit) { setRequestTimeout((int) TimeUnit.MILLISECONDS.convert(requestTimeout, timeUnit)); } @Override public void autoAuthorization(String domain, String username, String password, AuthType authType) { if (authType == AuthType.BASIC) { autoBasicAuthorization(domain, username, password); } else { throw new UnsupportedOperationException("Legacy ProxyServer implementation does not support non-BASIC authorization"); } } @Override public void stopAutoAuthorization(String domain) { LOG.warn("Legacy ProxyServer implementation does not support stopping auto authorization"); } @Override public void chainedProxyAuthorization(String username, String password, AuthType authType) { LOG.warn("Legacy ProxyServer implementation does not support chained proxy authorization"); } public void endPage() { if (currentPage == null) { return; } currentPage.getPageTimings().setOnLoad(new Date().getTime() - currentPage.getStartedDateTime().getTime()); client.setHarPageRef(null); currentPage = null; } @Override public void setRetryCount(int count) { client.setRetryCount(count); } @Override public void addHeaders(Map headers) { for (Map.Entry entry : headers.entrySet()) { addHeader(entry.getKey(), entry.getValue()); } } public void remapHost(String source, String target) { if (client.getResolver() instanceof AdvancedHostResolver) { AdvancedHostResolver advancedHostResolver = (AdvancedHostResolver) client.getResolver(); advancedHostResolver.remapHost(source, target); } else { LOG.warn("Attempting to remap host, but host resolver is not an AdvancedHostRemapper. Host resolver is: {}", client.getResolver()); } } @Override @Deprecated public void addRequestInterceptor(HttpRequestInterceptor i) { client.addRequestInterceptor(i); } @Override public void addRequestInterceptor(RequestInterceptor interceptor) { client.addRequestInterceptor(interceptor); } @Override @Deprecated public void addResponseInterceptor(HttpResponseInterceptor i) { client.addResponseInterceptor(i); } @Override public void addResponseInterceptor(ResponseInterceptor interceptor) { client.addResponseInterceptor(interceptor); } @Override public StreamManager getStreamManager() { return streamManager; } //use getStreamManager().setDownstreamKbps instead @Override @Deprecated public void setDownstreamKbps(long downstreamKbps) { streamManager.setDownstreamKbps(downstreamKbps); streamManager.enable(); } //use getStreamManager().setUpstreamKbps instead @Override @Deprecated public void setUpstreamKbps(long upstreamKbps) { streamManager.setUpstreamKbps(upstreamKbps); streamManager.enable(); } //use getStreamManager().setLatency instead @Override @Deprecated public void setLatency(long latency) { streamManager.setLatency(latency); streamManager.enable(); } @Override public void setRequestTimeout(int requestTimeout) { client.setRequestTimeout(requestTimeout); } @Override public void setSocketOperationTimeout(int readTimeout) { client.setSocketOperationTimeout(readTimeout); } @Override public void setConnectionTimeout(int connectionTimeout) { client.setConnectionTimeout(connectionTimeout); } @Override public void autoBasicAuthorization(String domain, String username, String password) { client.autoBasicAuthorization(domain, username, password); } @Override public void rewriteUrl(String match, String replace) { client.rewriteUrl(match, replace); } @Override public void rewriteUrls(Map rewriteRules) { for (Map.Entry entry : rewriteRules.entrySet()) { rewriteUrl(entry.getKey(), entry.getValue()); } } @Override public Map getRewriteRules() { ImmutableMap.Builder builder = ImmutableMap.builder(); for (RewriteRule rewriteRule : client.getRewriteRules()) { builder.put(rewriteRule.getPattern().pattern(), rewriteRule.getReplace()); } return builder.build(); } @Override public void removeRewriteRule(String urlPattern) { client.removeRewriteRule(urlPattern); } public void clearRewriteRules() { client.clearRewriteRules(); } @Override public void blacklistRequests(String pattern, int responseCode) { client.blacklistRequests(pattern, responseCode, null); } @Override public void blacklistRequests(String pattern, int responseCode, String method) { client.blacklistRequests(pattern, responseCode, method); } @Override public void setBlacklist(Collection blacklist) { for (BlacklistEntry entry : blacklist) { if (entry.getHttpMethodPattern() == null) { blacklistRequests(entry.getUrlPattern().pattern(), entry.getStatusCode()); } else { blacklistRequests(entry.getUrlPattern().pattern(), entry.getStatusCode(), entry.getHttpMethodPattern().pattern()); } } } @Override public Collection getBlacklist() { return getBlacklistedUrls(); } /** * @deprecated use getBlacklistedUrls() */ @Override @Deprecated public List getBlacklistedRequests() { return client.getBlacklistedRequests(); } @Override public Collection getBlacklistedUrls() { return client.getBlacklistedUrls(); } @Override public boolean isWhitelistEnabled() { return client.isWhitelistEnabled(); } /** * @deprecated use getWhitelistUrls() */ @Override @Deprecated public List getWhitelistRequests() { return client.getWhitelistRequests(); } @Override public Collection getWhitelistUrls() { ImmutableList.Builder builder = ImmutableList.builder(); for (Pattern pattern : getWhitelistRequests()) { builder.add(pattern.pattern()); } return builder.build(); } @Override public int getWhitelistStatusCode() { return getWhitelistResponseCode(); } public int getWhitelistResponseCode() { return client.getWhitelistResponseCode(); } @Override public void clearBlacklist() { client.clearBlacklist(); } @Override public void whitelistRequests(Collection urlPatterns, int statusCode) { whitelistRequests(urlPatterns.toArray(new String[urlPatterns.size()]), statusCode); } @Override public void addWhitelistPattern(String urlPattern) { List whitelistUrls = new ArrayList<>(getWhitelistUrls()); whitelistUrls.add(urlPattern); whitelistRequests(whitelistUrls, getWhitelistStatusCode()); } /** * Whitelists the specified requests. *

* Note: This method overwrites any existing whitelist. * * @param patterns regular expression patterns matching URLs to whitelist * @param responseCode response code to return for non-whitelisted URLs */ @Override public void whitelistRequests(String[] patterns, int responseCode) { client.whitelistRequests(patterns, responseCode); } /** * Enables an empty whitelist, which will return the specified responseCode for all requests. * * @param responseCode HTTP response code to return for all requests */ @Override public void enableEmptyWhitelist(int responseCode) { client.whitelistRequests(new String[0], responseCode); } @Override public void disableWhitelist() { clearWhitelist(); } public void clearWhitelist() { client.clearWhitelist(); } @Override public void addHeader(String name, String value) { client.addHeader(name, value); } @Override public void removeHeader(String name) { ImmutableMap.Builder builder = ImmutableMap.builder(); for (Map.Entry entry : getAllHeaders().entrySet()) { if (!entry.getKey().equals(name)) { builder.put(entry.getKey(), entry.getValue()); } } client.setAdditionalHeaders(builder.build()); } @Override public void removeAllHeaders() { client.setAdditionalHeaders(Collections.emptyMap()); } @Override public Map getAllHeaders() { return client.getAdditionalHeaders(); } @Override public void setHostNameResolver(AdvancedHostResolver resolver) { client.setResolver(resolver); } @Override public AdvancedHostResolver getHostNameResolver() { return client.getResolver(); } @Override public boolean waitForQuiescence(long quietPeriod, long timeout, TimeUnit timeUnit) { try { waitForNetworkTrafficToStop(TimeUnit.MILLISECONDS.convert(quietPeriod, timeUnit), TimeUnit.MILLISECONDS.convert(timeout, timeUnit)); return true; } catch (TimeoutException e) { return false; } } @Override public void setChainedProxy(InetSocketAddress chainedProxyAddress) { this.chainedProxyAddress = chainedProxyAddress; client.setHttpProxy(chainedProxyAddress.getHostString() + ":" + chainedProxyAddress.getPort()); } @Override public InetSocketAddress getChainedProxy() { return this.chainedProxyAddress; } public void setCaptureHeaders(boolean captureHeaders) { client.setCaptureHeaders(captureHeaders); } @Override public void setCaptureContent(boolean captureContent) { client.setCaptureContent(captureContent); } @Override public void setCaptureBinaryContent(boolean captureBinaryContent) { client.setCaptureBinaryContent(captureBinaryContent); } @Override public void clearDNSCache() { if (client.getResolver() instanceof AdvancedHostResolver) { AdvancedHostResolver advancedHostResolver = (AdvancedHostResolver) client.getResolver(); advancedHostResolver.clearDNSCache(); } else { LOG.warn("Attempting to clear DNS cache, but host resolver is not an AdvancedHostRemapper. Host resolver is: {}", client.getResolver()); } } @Override public void setDNSCacheTimeout(int timeout) { if (client.getResolver() instanceof AdvancedHostResolver) { AdvancedHostResolver advancedHostResolver = (AdvancedHostResolver) client.getResolver(); advancedHostResolver.setNegativeDNSCacheTimeout(timeout, TimeUnit.MILLISECONDS); advancedHostResolver.setPositiveDNSCacheTimeout(timeout, TimeUnit.MILLISECONDS); } else { LOG.warn("Attempting to set DNS cache timeout, but host resolver is not an AdvancedHostRemapper. Host resolver is: {}", client.getResolver()); } } @Override public void waitForNetworkTrafficToStop(final long quietPeriodInMs, long timeoutInMs) { boolean result = ThreadUtils.pollForCondition(new ThreadUtils.WaitCondition() { @Override public boolean checkCondition() { Date lastCompleted = null; Har har = client.getHar(); if (har == null || har.getLog() == null) { return true; } for (HarEntry entry : har.getLog().getEntries()) { // if there is an active request, just stop looking if (entry.getResponse().getStatus() < 0) { return false; } Date end = new Date(entry.getStartedDateTime().getTime() + entry.getTime()); if (lastCompleted == null) { lastCompleted = end; } else if (end.after(lastCompleted)) { lastCompleted = end; } } return lastCompleted != null && System.currentTimeMillis() - lastCompleted.getTime() >= quietPeriodInMs; } }, timeoutInMs, TimeUnit.MILLISECONDS); if (!result) { throw new TimeoutException("Timed out after " + timeoutInMs + " ms while waiting for network traffic to stop"); } } @Override public void setOptions(Map options) { if (options.containsKey("httpProxy")) { client.setHttpProxy(options.get("httpProxy")); } } @Override public void addFirstHttpFilterFactory(HttpFiltersSource filterFactory) { LOG.warn("The legacy ProxyServer implementation does not support HTTP filter factories. Use addRequestInterceptor/addResponseInterceptor instead."); } @Override public void addLastHttpFilterFactory(HttpFiltersSource filterFactory) { LOG.warn("The legacy ProxyServer implementation does not support HTTP filter factories. Use addRequestInterceptor/addResponseInterceptor instead."); } @Override public void addResponseFilter(ResponseFilter filter) { LOG.warn("The legacy ProxyServer implementation does not support addRequestFilter and addResponseFilter. Use addRequestInterceptor/addResponseInterceptor instead."); } @Override public void addRequestFilter(RequestFilter filter) { LOG.warn("The legacy ProxyServer implementation does not support addRequestFilter and addResponseFilter. Use addRequestInterceptor/addResponseInterceptor instead."); } @Override public void setMitmDisabled(boolean mitmDisabled) { LOG.warn("The legacy ProxyServer implementation does not support disabling MITM."); } @Override public void setMitmManager(MitmManager mitmManager) { LOG.warn("The legacy ProxyServer implementation does not support custom MITM managers."); } @Override public void setTrustAllServers(boolean trustAllServers) { LOG.warn("The legacy ProxyServer implementation does not support the trustAllServers option."); } @Override public void setTrustSource(TrustSource trustSource) { LOG.warn("The legacy ProxyServer implementation does not support the setTrustSource option."); } public void cleanSslCertificates() { handler.cleanSslWithCyberVilliansCA(); } /** * Exception thrown when waitForNetworkTrafficToStop does not successfully wait for network traffic to stop. */ public static class TimeoutException extends RuntimeException { private static final long serialVersionUID = -7179322468198775663L; public TimeoutException(String message) { super(message); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy