org.browsermob.proxy.ProxyServer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of browsermob-proxy Show documentation
Show all versions of browsermob-proxy Show documentation
A programmatic HTTP/S designed for performance and functional testing
The newest version!
package org.browsermob.proxy;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponseInterceptor;
import org.browsermob.core.har.*;
import org.browsermob.core.util.ThreadUtils;
import org.browsermob.proxy.http.BrowserMobHttpClient;
import org.browsermob.proxy.http.RequestInterceptor;
import org.browsermob.proxy.http.ResponseInterceptor;
import org.browsermob.proxy.jetty.http.HttpContext;
import org.browsermob.proxy.jetty.http.HttpListener;
import org.browsermob.proxy.jetty.http.SocketListener;
import org.browsermob.proxy.jetty.jetty.Server;
import org.browsermob.proxy.jetty.util.InetAddrPort;
import org.browsermob.proxy.util.Log;
import org.java_bandwidthlimiter.BandwidthLimiter;
import org.java_bandwidthlimiter.StreamManager;
import org.openqa.selenium.Proxy;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ProxyServer {
private static final HarNameVersion CREATOR = new HarNameVersion("BrowserMob Proxy", "2.0");
private static final Log LOG = new Log();
private Server server;
private int port = -1;
private BrowserMobHttpClient client;
private StreamManager streamManager;
private HarPage currentPage;
private BrowserMobProxyHandler handler;
private int pageCount = 1;
private AtomicInteger requestCounter = new AtomicInteger(0);
public ProxyServer() {
}
public ProxyServer(int port) {
this.port = port;
}
public void start() throws Exception {
if (port == -1) {
throw new IllegalStateException("Must set port before starting");
}
//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(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);
client.prepareForBrowser();
handler.setHttpClient(client);
context.addHandler(handler);
server.start();
setPort(listener.getPort());
}
public org.openqa.selenium.Proxy seleniumProxy() throws UnknownHostException {
Proxy proxy = new Proxy();
proxy.setProxyType(Proxy.ProxyType.MANUAL);
String proxyStr = String.format("%s:%d", InetAddress.getLocalHost().getCanonicalHostName(), getPort());
proxy.setHttpProxy(proxyStr);
proxy.setSslProxy(proxyStr);
return proxy;
}
public void cleanup() {
handler.cleanup();
}
public void stop() throws Exception {
cleanup();
client.shutdown();
server.stop();
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
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.waitFor(new ThreadUtils.WaitCondition() {
@Override
public boolean checkCondition(long elapsedTimeInMs) {
return requestCounter.get() == 0;
}
}, TimeUnit.SECONDS, 5);
if (!success) {
LOG.warn("Waited 5 seconds for requests to cease before returning HAR; giving up!");
}
return client.getHar();
}
public Har newHar(String initialPageRef) {
pageCount = 1;
Har oldHar = getHar();
Har har = new Har(new HarLog(CREATOR));
client.setHar(har);
newPage(initialPageRef);
return oldHar;
}
public void newPage(String pageRef) {
if (pageRef == null) {
pageRef = "Page " + pageCount;
}
client.setHarPageRef(pageRef);
currentPage = new HarPage(pageRef);
client.getHar().getLog().addPage(currentPage);
pageCount++;
}
public void endPage() {
if (currentPage == null) {
return;
}
currentPage.getPageTimings().setOnLoad(new Date().getTime() - currentPage.getStartedDateTime().getTime());
client.setHarPageRef(null);
currentPage = null;
}
public void setRetryCount(int count) {
client.setRetryCount(count);
}
public void remapHost(String source, String target) {
client.remapHost(source, target);
}
@Deprecated
public void addRequestInterceptor(HttpRequestInterceptor i) {
client.addRequestInterceptor(i);
}
public void addRequestInterceptor(RequestInterceptor interceptor) {
client.addRequestInterceptor(interceptor);
}
@Deprecated
public void addResponseInterceptor(HttpResponseInterceptor i) {
client.addResponseInterceptor(i);
}
public void addResponseInterceptor(ResponseInterceptor interceptor) {
client.addResponseInterceptor(interceptor);
}
public StreamManager getStreamManager() {
return streamManager;
}
//use getStreamManager().setDownstreamKbps instead
@Deprecated
public void setDownstreamKbps(long downstreamKbps) {
streamManager.setDownstreamKbps(downstreamKbps);
streamManager.enable();
}
//use getStreamManager().setUpstreamKbps instead
@Deprecated
public void setUpstreamKbps(long upstreamKbps) {
streamManager.setUpstreamKbps(upstreamKbps);
streamManager.enable();
}
//use getStreamManager().setLatency instead
@Deprecated
public void setLatency(long latency) {
streamManager.setLatency(latency);
streamManager.enable();
}
public void setRequestTimeout(int requestTimeout) {
client.setRequestTimeout(requestTimeout);
}
public void setSocketOperationTimeout(int readTimeout) {
client.setSocketOperationTimeout(readTimeout);
}
public void setConnectionTimeout(int connectionTimeout) {
client.setConnectionTimeout(connectionTimeout);
}
public void autoBasicAuthorization(String domain, String username, String password) {
client.autoBasicAuthorization(domain, username, password);
}
public void rewriteUrl(String match, String replace) {
client.rewriteUrl(match, replace);
}
public void blacklistRequests(String pattern, int responseCode) {
client.blacklistRequests(pattern, responseCode);
}
public void whitelistRequests(String[] patterns, int responseCode) {
client.whitelistRequests(patterns, responseCode);
}
public void addHeader(String name, String value) {
client.addHeader(name, value);
}
public void setCaptureHeaders(boolean captureHeaders) {
client.setCaptureHeaders(captureHeaders);
}
public void setCaptureContent(boolean captureContent) {
client.setCaptureContent(captureContent);
}
public void clearDNSCache() {
client.clearDNSCache();
}
public void setDNSCacheTimeout(int timeout) {
client.setDNSCacheTimeout(timeout);
}
public void waitForNetworkTrafficToStop(final long quietPeriodInMs, long timeoutInMs) {
long start = System.currentTimeMillis();
boolean result = ThreadUtils.waitFor(new ThreadUtils.WaitCondition() {
@Override
public boolean checkCondition(long elapsedTimeInMs) {
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;
}
}, TimeUnit.MILLISECONDS, timeoutInMs);
long end = System.currentTimeMillis();
long time = (end - start);
if (!result) {
throw new RuntimeException("Timed out after " + timeoutInMs + " ms while waiting for network traffic to stop");
}
}
public void setOptions(Map options) {
if (options.containsKey("httpProxy")) {
client.setHttpProxy(options.get("httpProxy"));
}
}
}