package com.codeborne.selenide.proxy; import net.lightbody.bmp.BrowserMobProxy; import net.lightbody.bmp.BrowserMobProxyServer; import net.lightbody.bmp.client.ClientUtil; import net.lightbody.bmp.filters.RequestFilter; import net.lightbody.bmp.filters.RequestFilterAdapter; import net.lightbody.bmp.filters.ResponseFilter; import net.lightbody.bmp.filters.ResponseFilterAdapter; import org.openqa.selenium.Proxy; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Map; import static java.lang.Integer.parseInt; /** * Selenide own proxy server to intercept server responses * * It holds map of request and response filters by name. */ public class SelenideProxyServer { protected final Proxy outsideProxy; protected BrowserMobProxy proxy = new BrowserMobProxyServer() { int maxSize = 64 * 1024 * 1024; // 64 MB @Override public void addRequestFilter(RequestFilter filter) { addFirstHttpFilterFactory(new RequestFilterAdapter.FilterSource(filter, maxSize)); } @Override public void addResponseFilter(ResponseFilter filter) { addLastHttpFilterFactory(new ResponseFilterAdapter.FilterSource(filter, maxSize)); } }; protected int port; protected Map<String, RequestFilter> requestFilters = new HashMap<>(); protected Map<String, ResponseFilter> responseFilters = new HashMap<>(); /** * Create server * Note that server is not started nor activated yet. * * @param outsideProxy another proxy server used by test author for his own need (can be null) */ public SelenideProxyServer(Proxy outsideProxy) { this.outsideProxy = outsideProxy; } /** * Start the server * * It automatically adds one response filter "download" that can intercept downloaded files. */ public void start() { proxy.setTrustAllServers(true); if (outsideProxy != null) { proxy.setChainedProxy(getProxyAddress(outsideProxy)); } addRequestFilter("requestSizeWatchdog", new RequestSizeWatchdog()); addResponseFilter("responseSizeWatchdog", new ResponseSizeWatchdog()); addResponseFilter("download", new FileDownloadFilter()); proxy.start(); port = proxy.getPort(); } private void addRequestFilter(String name, RequestFilter requestFilter) { proxy.addRequestFilter(requestFilter); requestFilters.put(name, requestFilter); } private void addResponseFilter(String name, ResponseFilter responseFilter) { proxy.addResponseFilter(responseFilter); responseFilters.put(name, responseFilter); } static InetSocketAddress getProxyAddress(Proxy proxy) { String httpProxy = proxy.getHttpProxy(); String host = httpProxy.replaceFirst("(.*):.*", "$1"); String port = httpProxy.replaceFirst(".*:(.*)", "$1"); return new InetSocketAddress(host, parseInt(port)); } /** * Converts this proxy to a "selenium" proxy that can be used by webdriver */ public Proxy createSeleniumProxy() { return ClientUtil.createSeleniumProxy(proxy); } /** * Stop the server */ public void shutdown() { proxy.abort(); } @Override public String toString() { return String.format("Selenide proxy server :%s", port); } /** * Get request filter by name */ @SuppressWarnings("unchecked") public <T extends RequestFilter> T requestFilter(String name) { return (T) requestFilters.get(name); } /** * Get response filter by name * * By default, the only one filter "download" is available. */ @SuppressWarnings("unchecked") public <T extends ResponseFilter> T responseFilter(String name) { return (T) responseFilters.get(name); } }