<commit_before>/*
 * Copyright 2006 ThoughtWorks, Inc.
 *
 *  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 org.openqa.selenium.server.browserlaunchers;

import java.io.*;
import java.net.*;
import java.util.regex.*;

import org.apache.tools.ant.taskdefs.condition.*;

public class FirefoxChromeLauncher implements BrowserLauncher {

    private static final String DEFAULT_NONWINDOWS_LOCATION = "/Applications/Firefox.app/Contents/MacOS/firefox-bin";
    
    private static boolean simple = false;
    
    private int port;
    private String sessionId;
    private File customProfileDir;
    private String[] cmdarray;
    private boolean closed = false;
    private String commandPath;
    private Process process;

    private static AsyncExecute exe = new AsyncExecute();
    
    public FirefoxChromeLauncher(int port, String sessionId) {
        this(port, sessionId, findBrowserLaunchLocation());
    }
    
    public FirefoxChromeLauncher(int port, String sessionId, String browserLaunchLocation) {
        commandPath = browserLaunchLocation;
        this.port = port;
        this.sessionId = sessionId;
        // Set MOZ_NO_REMOTE in order to ensure we always get a new Firefox process
        // http://blog.dojotoolkit.org/2005/12/01/running-multiple-versions-of-firefox-side-by-side
        exe.setEnvironment(new String[] {"MOZ_NO_REMOTE=1"});
        if (!WindowsUtils.thisIsWindows()) {
            // On unix, add command's directory to LD_LIBRARY_PATH
            File firefoxBin = AsyncExecute.whichExec(commandPath);
            if (firefoxBin == null) {
                File execDirect = new File(commandPath);
                if (execDirect.isAbsolute() && execDirect.exists()) firefoxBin = execDirect;
            }
            if (firefoxBin != null) {
                LauncherUtils.assertNotScriptFile(firefoxBin);
                String libPathKey = getLibPathKey();
                String libPath = WindowsUtils.loadEnvironment().getProperty(libPathKey);
                exe.setEnvironment(new String[] {
                    "MOZ_NO_REMOTE=1",
                    libPathKey+"="+libPath+":" + firefoxBin.getParent(),
                });
            }
        }
    }
    
    private static String getLibPathKey() {
        if (WindowsUtils.thisIsWindows()) return WindowsUtils.getExactPathEnvKey();
        if (Os.isFamily("mac")) return "DYLD_LIBRARY_PATH";
        // TODO other linux?
        return "LD_LIBRARY_PATH";
    }
    
    private static String findBrowserLaunchLocation() {
        String defaultPath = System.getProperty("firefoxDefaultPath");
        if (defaultPath == null) {
            if (WindowsUtils.thisIsWindows()) {
                defaultPath = WindowsUtils.getProgramFilesPath() + "\\Mozilla Firefox\\firefox.exe";
            } else {
                defaultPath = DEFAULT_NONWINDOWS_LOCATION;
            }
        }
        File defaultLocation = new File(defaultPath);
        if (defaultLocation.exists()) {
            return defaultLocation.getAbsolutePath();
        }
            if (WindowsUtils.thisIsWindows()) {
            	File firefoxEXE = AsyncExecute.whichExec("firefox.exe");
            	if (firefoxEXE != null) return firefoxEXE.getAbsolutePath();
            	throw new RuntimeException("Firefox couldn't be found in the path!\n" +
            			"Please add the directory containing firefox.exe to your PATH environment\n" +
            			"variable, or explicitly specify a path to Firefox like this:\n" +
            			"*firefox c:\\blah\\firefox.exe");
        }
                // On unix, prefer firefoxBin if it's on the path
                File firefoxBin = AsyncExecute.whichExec("firefox-bin");
                if (firefoxBin != null) {
                    return firefoxBin.getAbsolutePath();
                }
                throw new RuntimeException("Firefox couldn't be found in the path!\n" +
            			"Please add the directory containing 'firefox-bin' to your PATH environment\n" +
            			"variable, or explicitly specify a path to Firefox like this:\n" +
            			"*firefox /blah/blah/firefox-bin");
            }
            
    static final Pattern JAVA_STYLE_UNC_URL = Pattern.compile("^file:////([^/]+/.*)$");
    /**
     * Generates an URL suitable for use in browsers, unlike Java's URLs, which choke
     * on UNC paths.
     * 
     * <P>Java's URLs work in IE, but break in Mozilla.  Mozilla's team snobbily demanded
     * that <I>all</I> file paths must have the empty authority (file:///), even for UNC file paths.
     * On Mozilla \\socrates\build is therefore represented as file://///socrates/build.</P>  See
     * Mozilla bug <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=66194">66194</A>. 
     * @param path - the file path to convert to a browser URL
     * @return a nice Mozilla-compatible file URL
     */
    private static String pathToBrowserURL(String path) {
        if (path == null) return null;
        String url = (new File(path)).toURI().toString();
        Matcher m = JAVA_STYLE_UNC_URL.matcher(url);
        if (m.find()) {
            url = "file://///";
            url += m.group(1);
        }
        return url;
    }
    
    public void launch(String url, String htmlName) {
        try {
            String query = LauncherUtils.getQueryString(url);
            if (null == query) {
                query = "";
            }
            query += "&baseUrl=http://localhost:" + port + "/selenium-server/";
            String homePage = "chrome://src/content/" + htmlName + "?" + query;
            String profilePath = makeCustomProfile(homePage);
            
            String chromeURL = "chrome://killff/content/kill.html";
            
            cmdarray = new String[] {commandPath, "-profile", profilePath, chromeURL};
            
            /* The first time we launch Firefox with an empty profile directory,
             * Firefox will launch itself, populate the profile directory, then
             * kill/relaunch itself, so our process handle goes out of date.
             * So, the first time we launch Firefox, we'll start it up at an URL
             * that will immediately shut itself down. */
            System.out.println("Preparing Firefox profile...");
            
            exe.setCommandline(cmdarray);
            exe.execute();
            
            waitForFullProfileToBeCreated(20*1000);
            
            System.out.println("Launching Firefox...");
            
            cmdarray = new String[] {commandPath, "-profile", profilePath};
            exe.setCommandline(cmdarray);
            
            process = exe.asyncSpawn();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    

    private String makeCustomProfile(String homePage) throws IOException {
        customProfileDir = LauncherUtils.createCustomProfileDir(sessionId);
        
        if (simple) return customProfileDir.getAbsolutePath();
        
        embedKillFirefoxExtension();
        embedSeleniumExtension();
        
        // TODO Do we want to make these preferences configurable somehow?
        File prefsJS = new File(customProfileDir, "prefs.js");
        PrintStream out = new PrintStream(new FileOutputStream(prefsJS));
        // Don't ask if we want to switch default browsers
        out.println("user_pref('browser.shell.checkDefaultBrowser', false);");
        
        out.println("user_pref('startup.homepage_override_url', '" + homePage + "');");
        
        // Disable pop-up blocking
        out.println("user_pref('browser.allowpopups', true);");
        out.println("user_pref('dom.disable_open_during_load', false);");
        
        // Disable security warnings
        out.println("user_pref('security.warn_submit_insecure', false);");
        out.println("user_pref('security.warn_submit_insecure.show_once', false);");
        out.println("user_pref('security.warn_entering_secure', false);");
        out.println("user_pref('security.warn_entering_secure.show_once', false);");
        out.println("user_pref('security.warn_entering_weak', false);");
        out.println("user_pref('security.warn_entering_weak.show_once', false);");
        out.println("user_pref('security.warn_leaving_secure', false);");
        out.println("user_pref('security.warn_leaving_secure.show_once', false);");
        out.println("user_pref('security.warn_viewing_mixed', false);");<commit_msg>Silly me.  If I don't configure the proxy, then there's no way to configure the proxy in *chrome!<commit_after>/*
 * Copyright 2006 ThoughtWorks, Inc.
 *
 *  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 org.openqa.selenium.server.browserlaunchers;

import java.io.*;
import java.net.*;
import java.util.regex.*;

import org.apache.tools.ant.taskdefs.condition.*;

public class FirefoxChromeLauncher implements BrowserLauncher {

    private static final String DEFAULT_NONWINDOWS_LOCATION = "/Applications/Firefox.app/Contents/MacOS/firefox-bin";
    
    private static boolean simple = false;
    
    private int port;
    private String sessionId;
    private File customProfileDir;
    private String[] cmdarray;
    private boolean closed = false;
    private String commandPath;
    private Process process;

    private static AsyncExecute exe = new AsyncExecute();
    
    public FirefoxChromeLauncher(int port, String sessionId) {
        this(port, sessionId, findBrowserLaunchLocation());
    }
    
    public FirefoxChromeLauncher(int port, String sessionId, String browserLaunchLocation) {
        commandPath = browserLaunchLocation;
        this.port = port;
        this.sessionId = sessionId;
        // Set MOZ_NO_REMOTE in order to ensure we always get a new Firefox process
        // http://blog.dojotoolkit.org/2005/12/01/running-multiple-versions-of-firefox-side-by-side
        exe.setEnvironment(new String[] {"MOZ_NO_REMOTE=1"});
        if (!WindowsUtils.thisIsWindows()) {
            // On unix, add command's directory to LD_LIBRARY_PATH
            File firefoxBin = AsyncExecute.whichExec(commandPath);
            if (firefoxBin == null) {
                File execDirect = new File(commandPath);
                if (execDirect.isAbsolute() && execDirect.exists()) firefoxBin = execDirect;
            }
            if (firefoxBin != null) {
                LauncherUtils.assertNotScriptFile(firefoxBin);
                String libPathKey = getLibPathKey();
                String libPath = WindowsUtils.loadEnvironment().getProperty(libPathKey);
                exe.setEnvironment(new String[] {
                    "MOZ_NO_REMOTE=1",
                    libPathKey+"="+libPath+":" + firefoxBin.getParent(),
                });
            }
        }
    }
    
    private static String getLibPathKey() {
        if (WindowsUtils.thisIsWindows()) return WindowsUtils.getExactPathEnvKey();
        if (Os.isFamily("mac")) return "DYLD_LIBRARY_PATH";
        // TODO other linux?
        return "LD_LIBRARY_PATH";
    }
    
    private static String findBrowserLaunchLocation() {
        String defaultPath = System.getProperty("firefoxDefaultPath");
        if (defaultPath == null) {
            if (WindowsUtils.thisIsWindows()) {
                defaultPath = WindowsUtils.getProgramFilesPath() + "\\Mozilla Firefox\\firefox.exe";
            } else {
                defaultPath = DEFAULT_NONWINDOWS_LOCATION;
            }
        }
        File defaultLocation = new File(defaultPath);
        if (defaultLocation.exists()) {
            return defaultLocation.getAbsolutePath();
        }
            if (WindowsUtils.thisIsWindows()) {
            	File firefoxEXE = AsyncExecute.whichExec("firefox.exe");
            	if (firefoxEXE != null) return firefoxEXE.getAbsolutePath();
            	throw new RuntimeException("Firefox couldn't be found in the path!\n" +
            			"Please add the directory containing firefox.exe to your PATH environment\n" +
            			"variable, or explicitly specify a path to Firefox like this:\n" +
            			"*firefox c:\\blah\\firefox.exe");
        }
                // On unix, prefer firefoxBin if it's on the path
                File firefoxBin = AsyncExecute.whichExec("firefox-bin");
                if (firefoxBin != null) {
                    return firefoxBin.getAbsolutePath();
                }
                throw new RuntimeException("Firefox couldn't be found in the path!\n" +
            			"Please add the directory containing 'firefox-bin' to your PATH environment\n" +
            			"variable, or explicitly specify a path to Firefox like this:\n" +
            			"*firefox /blah/blah/firefox-bin");
            }
            
    static final Pattern JAVA_STYLE_UNC_URL = Pattern.compile("^file:////([^/]+/.*)$");
    /**
     * Generates an URL suitable for use in browsers, unlike Java's URLs, which choke
     * on UNC paths.
     * 
     * <P>Java's URLs work in IE, but break in Mozilla.  Mozilla's team snobbily demanded
     * that <I>all</I> file paths must have the empty authority (file:///), even for UNC file paths.
     * On Mozilla \\socrates\build is therefore represented as file://///socrates/build.</P>  See
     * Mozilla bug <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=66194">66194</A>. 
     * @param path - the file path to convert to a browser URL
     * @return a nice Mozilla-compatible file URL
     */
    private static String pathToBrowserURL(String path) {
        if (path == null) return null;
        String url = (new File(path)).toURI().toString();
        Matcher m = JAVA_STYLE_UNC_URL.matcher(url);
        if (m.find()) {
            url = "file://///";
            url += m.group(1);
        }
        return url;
    }
    
    public void launch(String url, String htmlName) {
        try {
            String query = LauncherUtils.getQueryString(url);
            if (null == query) {
                query = "";
            }
            query += "&baseUrl=http://localhost:" + port + "/selenium-server/";
            String homePage = "chrome://src/content/" + htmlName + "?" + query;
            String profilePath = makeCustomProfile(homePage);
            
            String chromeURL = "chrome://killff/content/kill.html";
            
            cmdarray = new String[] {commandPath, "-profile", profilePath, chromeURL};
            
            /* The first time we launch Firefox with an empty profile directory,
             * Firefox will launch itself, populate the profile directory, then
             * kill/relaunch itself, so our process handle goes out of date.
             * So, the first time we launch Firefox, we'll start it up at an URL
             * that will immediately shut itself down. */
            System.out.println("Preparing Firefox profile...");
            
            exe.setCommandline(cmdarray);
            exe.execute();
            
            waitForFullProfileToBeCreated(20*1000);
            
            System.out.println("Launching Firefox...");
            
            cmdarray = new String[] {commandPath, "-profile", profilePath};
            exe.setCommandline(cmdarray);
            
            process = exe.asyncSpawn();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    

    private String makeCustomProfile(String homePage) throws IOException {
        customProfileDir = LauncherUtils.createCustomProfileDir(sessionId);
        
        if (simple) return customProfileDir.getAbsolutePath();
        
        File proxyPAC = LauncherUtils.makeProxyPAC(customProfileDir, port);
        
        embedKillFirefoxExtension();
        embedSeleniumExtension();
        
        // TODO Do we want to make these preferences configurable somehow?
        File prefsJS = new File(customProfileDir, "prefs.js");
        PrintStream out = new PrintStream(new FileOutputStream(prefsJS));
        // Don't ask if we want to switch default browsers
        out.println("user_pref('browser.shell.checkDefaultBrowser', false);");
        
        out.println("user_pref('startup.homepage_override_url', '" + homePage + "');");
        
        // Disable pop-up blocking
        out.println("user_pref('browser.allowpopups', true);");
        out.println("user_pref('dom.disable_open_during_load', false);");
        
        // Configure us as the local proxy
        out.println("user_pref('network.proxy.type', 2);");
        out.println("user_pref('network.proxy.autoconfig_url', '" +
                pathToBrowserURL(proxyPAC.getAbsolutePath()) + 
                "');");
        
        // Disable security warnings
        out.println("user_pref('security.warn_submit_insecure', false);");
        out.println("user_pref('security.warn_submit_insecure.show_once', false);");
        out.println("user_pref('security.warn_entering_secure', false);");
        out.println("user_pref('security.warn_entering_secure.show_once', false);");
        out.println("user_pref('security.warn_entering_weak', false);");
        out.println("user_pref('security.warn_entering_weak.show_once', false);");
        out.println("user_pref('security.warn_leaving_secure', false);");
        out.println("user_pref('security.warn_leaving_secure.show_once', false);");
        out.println("user_pref('security.warn_viewing_mixed', false);");
{'fraction_non_alphanumeric': 0.10737344691009712, 'fraction_numerical': 0.0038522055233031305, 'mean_word_length': 2.336108597285068, 'pattern_counts': {'":': 2, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3321075', 'n_tokens_mistral': 5125, 'n_tokens_neox': 4833, 'n_words': 1300}