/** * Sahi - Web Automation and Test Tool * * Copyright 2006 V Narayan Raman * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sf.sahi; import net.sf.sahi.config.Configuration; import net.sf.sahi.ssl.SSLHelper; import net.sf.sahi.util.BrowserTypesLoader; import net.sf.sahi.util.Diagnostics; import net.sf.sahi.util.Utils; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Proxy manages Sahi's proxy server. <br/> * Proxy needs to know the base directory of Sahi. <br/> * This is configured by calling Configuration.init(String sahiBaseDir, String userDataDirectory) <br/> * <p/> * <pre> * Usage: * * String sahiBasePath = "D:\\path\\to\\sahi_dir"; * Sting userDataDirectory = "D:\\path\\to\\userdata_dir"; // userdata_dir is in sahiBasePath/userdata by default * * net.sf.sahi.config.Configuration.initJava(sahiBasePath, userDataDirectory); * * proxy = new Proxy(); * proxy.start(true); // true represents asynchronous. The proxy server will listen on a separate thread. * * // browser actions * * proxy.stop(); * </pre> */ public class Proxy { static Proxy currentInstance; private static Logger logger = Logger.getLogger(Proxy.class); private int port = 9999; private ServerSocket server; private ExecutorService pool; private boolean forceClosed; public Proxy(int port) { this.port = port; } public Proxy() { this.port = Configuration.getPort(); } private static void configureLogging() { PropertyConfigurator.configureAndWatch("log4j.properties"); } public static void main(String[] args) { configureLogging(); if (args.length == 2) { Configuration.init(args[0], args[1]); } else if (args.length == 1) { Configuration.init(args[0]); } else { Configuration.init(); } final Proxy proxy = new Proxy(Configuration.getPort()); currentInstance = proxy; proxy.start(false); } public static void stopCurrentIntance() { currentInstance.stop(); } /** * Stops the proxy. */ public void stop() { if (server != null) { try { forceClosed = true; server.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * Starts the proxy. * * @param asynch If true, starts Sahi's proxy in a separate thread. */ public void start(boolean asynch) { if (!asynch) { try { startProxy(); } catch (IOException e) { e.printStackTrace(); } } else { try { Runnable runnable = new Runnable() { public void run() { try { startProxy(); } catch (IOException e) { e.printStackTrace(); } } }; Thread thread = new Thread(runnable); thread.start(); } catch (Exception e) { e.printStackTrace(); } } } /** * Indicates whether this proxy server can receive connections from clients * * @return see above */ public boolean isRunning() { return server != null && !server.isClosed(); } private synchronized void startProxy() throws IOException { try { byte[] probe = Utils.readURL("http://localhost:" + Configuration.getPort() + "/_s_/spr/probe.htm", false); if (probe != null) { logger.warn("Port " + Configuration.getPort() + " is already being used"); return; } server = new ServerSocket(); pool = Executors.newCachedThreadPool(); server.setReuseAddress(true); server.bind(new InetSocketAddress(port), 300); SSLHelper.getInstance().checkRootCA(); logger.info("Sahi started. Listening on port: " + port); logger.info("Configure your browser to use this server and port as its proxy"); logger.info("Browse any page and CTRL-ALT-DblClick on the page to bring up the Sahi Controller"); BrowserTypesLoader.getAvailableBrowserTypes(true); new Thread(new Diagnostics()).start(); while (true && !forceClosed && !server.isClosed()) { try { Socket client = server.accept(); pool.execute(new ProxyProcessor(client)); } catch (Exception e) { logger.error(e.getMessage(), e); e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } finally { if (server != null) server.close(); } } }