Index: src/main/java/org/openqa/selenium/server/browserlaunchers/SafariCustomProfileLauncher.java =================================================================== --- src/main/java/org/openqa/selenium/server/browserlaunchers/SafariCustomProfileLauncher.java (revision 1825) +++ src/main/java/org/openqa/selenium/server/browserlaunchers/SafariCustomProfileLauncher.java (working copy) @@ -16,25 +16,34 @@ */ package org.openqa.selenium.server.browserlaunchers; +import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.condition.Os; +import org.apache.tools.ant.taskdefs.*; import org.openqa.selenium.server.SeleniumServer; import java.io.*; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class SafariCustomProfileLauncher extends AbstractBrowserLauncher { private static final String DEFAULT_LOCATION = "/Applications/Safari.app/Contents/MacOS/Safari"; private static final String REDIRECT_TO_GO_TO_SELENIUM = "redirect_to_go_to_selenium.htm"; + + private static final String NETWORK_SETUP_LOCATION = "/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Support/"; // private int port; private File customProfileDir; private String[] cmdarray; + private String[] proxycmdarray; private boolean closed = false; private String commandPath; private Process process; private static AsyncExecute exe = new AsyncExecute(); + private static Execute proxyExe = new Execute(); public SafariCustomProfileLauncher(int port, String sessionId) { this(port, sessionId, findBrowserLaunchLocation()); @@ -90,6 +99,17 @@ "*Safari /blah/blah/Safari"); } + private static String findNetworkSetupBin() { + String defaultPath = "/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Support/networksetup"; + File defaultLocation = new File(defaultPath); + if (defaultLocation.exists()) { + return defaultLocation.getAbsolutePath(); + } + throw new RuntimeException("networksetup couldn't be found in the path!\n" + + "Please add the directory containing 'networksetup' to your PATH environment\n" + + "variable."); + } + protected void launch(String url) { try { cmdarray = new String[]{commandPath}; @@ -99,15 +119,80 @@ System.out.println("Launching Safari to visit " + url + " via " + redirectHtmlFileName + "..."); cmdarray = new String[]{commandPath, redirectHtmlFileName}; - exe.setCommandline(cmdarray); + /* This was to print out the values I wanted -- and to get + * some experience with the execution model. + proxycmdarray = new String[]{"echo", extractNetworkName()}; + proxyExe.setCommandline(proxycmdarray); + proxyExe.execute(); + + proxycmdarray = new String[]{"echo", determineNetworkInterface()}; + proxyExe.setCommandline(proxycmdarray); + proxyExe.execute(); + */ + proxycmdarray = generateProxyCmd(); + proxyExe.setCommandline(proxycmdarray); + proxyExe.execute(); + exe.setCommandline(cmdarray); process = exe.asyncSpawn(); } catch (IOException e) { throw new RuntimeException(e); } } + //TODO(trybka): I'm not sure this is necessary. + protected String determineNetworkInterface(){ + /* + * OS X based only. + */ + Project p = new Project(); + ExecTask exec = new ExecTask(); + exec.setProject(p); + exec.setTaskType("route"); + exec.setExecutable("route"); + exec.setFailonerror(true); + exec.createArg().setValue("get"); + exec.createArg().setValue("default"); + exec.setOutputproperty("netwiface"); + exec.execute(); + String output = p.getProperty("netwiface"); + Pattern patt = Pattern.compile("^ *interface: (.*)"); + String[] foo = output.split(System.getProperty("line.separator")); + for (int i = 0; i < foo.length; i++){ + Matcher match = patt.matcher(foo[i]); + boolean bingo = match.matches(); + if (bingo) { + return match.group(1); + } + } + return output; + } + + protected String extractNetworkName(){ + Project p = new Project(); + ExecTask exec = new ExecTask(); + exec.setProject(p); + exec.setTaskType("/bin/bash system_profiler"); + exec.setExecutable("/bin/bash"); + exec.createArg().setValue("-c"); + //TODO(trybka): This should probably be refactored to use Java + // String operations, not grep, awk, and cut... + exec.createArg().setValue("/usr/sbin/system_profiler SPNetworkDataType | grep -B4 -E \"^ *BSD Device Name: $(route get default | grep interface | awk '{ print $2}')$\" | grep -v '^.*: .*$' | grep -v -E '^ *$' | cut -d: -f1"); + exec.setFailonerror(true); + exec.setOutputproperty("netwname"); + exec.execute(); + String output = p.getProperty("netwname").trim(); + return output; + } + + protected String[] generateProxyCmd(){ + String[] proxycmd = new String[]{findNetworkSetupBin(), "-setwebproxy", extractNetworkName(), "localhost", "4444"}; + //this is only for normal HTTP. To do HTTPS you could change the flag to + //-setsecurewebproxy I think. + return proxycmd; + } + protected String makeRedirectionHtml(File parentDir, String url) { File f = new File(parentDir, REDIRECT_TO_GO_TO_SELENIUM); PrintStream out; @@ -130,6 +215,7 @@ public void close() { if (closed) return; if (process == null) return; + /* TODO(trybka): Do Proxy Clean Up here*/ System.out.println("Killing Safari..."); int exitValue = AsyncExecute.killProcess(process); if (exitValue == 0) {