2022-08-07 12:40:11 -04:00
|
|
|
package net.i2p.i2pfirefox;
|
2022-08-07 02:00:32 -04:00
|
|
|
|
|
|
|
import java.io.File;
|
2022-08-07 02:26:04 -04:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.Socket;
|
2022-08-07 02:00:32 -04:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
2022-08-27 13:27:28 -04:00
|
|
|
/**
|
2022-08-21 23:49:08 -04:00
|
|
|
* I2PFirefox.java
|
|
|
|
* Copyright (C) 2022 idk <hankhill19580@gmail.com>
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the MIT License. See LICENSE.md for details.
|
2022-08-30 15:49:44 -04:00
|
|
|
*
|
2022-08-21 23:49:08 -04:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*
|
2022-08-30 15:49:44 -04:00
|
|
|
*
|
2022-08-21 23:49:08 -04:00
|
|
|
* @author idk
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
2022-09-04 10:59:35 -04:00
|
|
|
public class I2PFirefox extends I2PCommonBrowser {
|
2022-08-30 15:49:44 -04:00
|
|
|
private final String[] FIREFOX_SEARCH_PATHS = FIREFOX_FINDER();
|
|
|
|
private final int DEFAULT_TIMEOUT = 200;
|
|
|
|
private Process p = null;
|
2022-08-30 17:36:30 -04:00
|
|
|
public static boolean usability = false;
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Construct an I2PFirefox class which manages an instance of Firefox and
|
|
|
|
* an accompanying Firefox profile. This version includes Firefox variants
|
|
|
|
* and forks.
|
|
|
|
*
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public I2PFirefox() {
|
|
|
|
for (String path : FIREFOX_SEARCH_PATHS) {
|
|
|
|
File f = new File(path);
|
|
|
|
if (f.exists()) {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Found Firefox at " + path);
|
2022-08-30 15:49:44 -04:00
|
|
|
return;
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
private static String[] FIND_FIREFOX_SEARCH_PATHS_UNIX() {
|
|
|
|
String[] path = new String[] {"/usr/bin", "/usr/local/bin",
|
|
|
|
"/opt/firefox/bin", "/snap/bin"};
|
|
|
|
String[] exes = new String[] {"firefox", "firefox-bin", "firefox-esr",
|
|
|
|
"waterfox", "waterfox-bin", "librewolf"};
|
|
|
|
String[] exePath = new String[path.length * exes.length];
|
|
|
|
int i = 0;
|
|
|
|
for (String s : path) {
|
|
|
|
for (String exe : exes) {
|
|
|
|
exePath[i] = s + "/" + exe;
|
|
|
|
i++;
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return exePath;
|
|
|
|
}
|
|
|
|
private static String[] FIND_FIREFOX_SEARCH_PATHS_OSX() {
|
|
|
|
String[] path =
|
|
|
|
new String[] {"/Applications/Firefox.app/Contents/MacOS/",
|
|
|
|
"/Applications/Waterfox.app/Contents/MacOS/",
|
|
|
|
"/Applications/Librewolf.app/Contents/MacOS/"};
|
|
|
|
String[] exes = new String[] {"firefox", "firefox-bin", "firefox-esr",
|
|
|
|
"waterfox", "waterfox-bin", "librewolf"};
|
|
|
|
String[] exePath = new String[path.length * exes.length];
|
|
|
|
int i = 0;
|
|
|
|
for (String s : path) {
|
|
|
|
for (String exe : exes) {
|
|
|
|
exePath[i] = s + "/" + exe;
|
|
|
|
i++;
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return exePath;
|
|
|
|
}
|
|
|
|
private static String[] FIND_FIREFOX_SEARCH_PATHS_WINDOWS() {
|
|
|
|
String userHome = System.getProperty("user.home");
|
|
|
|
String programFiles = System.getenv("ProgramFiles");
|
|
|
|
// String localAppData = System.getenv("LOCALAPPDATA");
|
|
|
|
// Is there some way Mozilla does adminless installs to LocalAppData? Don't
|
|
|
|
// know for sure.
|
|
|
|
String programFiles86 = System.getenv("ProgramFiles(x86)");
|
2022-08-08 01:37:52 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
String[] tbPath = new String[] {
|
|
|
|
new File(userHome, "/OneDrive/Desktop/Tor Browser/Browser/").toString(),
|
|
|
|
new File(userHome, "/Desktop/Tor Browser/Browser/").toString()};
|
|
|
|
|
|
|
|
String[] path = new String[] {
|
|
|
|
tbPath[0],
|
|
|
|
tbPath[1],
|
|
|
|
new File(programFiles, "Mozilla Firefox/").toString(),
|
|
|
|
new File(programFiles86, "Mozilla Firefox/").toString(),
|
|
|
|
new File(programFiles, "Waterfox/").toString(),
|
|
|
|
new File(programFiles86, "Waterfox/").toString(),
|
|
|
|
new File(programFiles, "Librewolf/").toString(),
|
|
|
|
};
|
|
|
|
String[] exes = new String[] {
|
|
|
|
"firefox.exe", "firefox-bin.exe", "firefox-esr.exe",
|
|
|
|
"waterfox.exe", "waterfox-bin.exe", "librewolf.exe",
|
|
|
|
};
|
|
|
|
String[] exePath = new String[path.length * exes.length];
|
|
|
|
int i = 0;
|
|
|
|
for (String s : path) {
|
|
|
|
for (String exe : exes) {
|
|
|
|
exePath[i] = s + "\\" + exe;
|
|
|
|
i++;
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return exePath;
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
private static String[] FIND_ALL_FIREFOX_SEARCH_PATHS() {
|
|
|
|
String[] Unix = FIND_FIREFOX_SEARCH_PATHS_UNIX();
|
|
|
|
String[] Windows = FIND_FIREFOX_SEARCH_PATHS_WINDOWS();
|
|
|
|
String[] Mac = FIND_FIREFOX_SEARCH_PATHS_OSX();
|
|
|
|
String[] exePath = new String[Unix.length + Windows.length + Mac.length];
|
|
|
|
int i = 0;
|
|
|
|
for (String s : Unix) {
|
|
|
|
exePath[i] = s;
|
|
|
|
i++;
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
for (String s : Windows) {
|
|
|
|
exePath[i] = s;
|
|
|
|
i++;
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
for (String s : Mac) {
|
|
|
|
exePath[i] = s;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return exePath;
|
|
|
|
}
|
|
|
|
private static String[] FIND_FIREFOX_SEARCH_PATHS() {
|
|
|
|
switch (getOperatingSystem()) {
|
|
|
|
case "Windows":
|
|
|
|
return FIND_FIREFOX_SEARCH_PATHS_WINDOWS();
|
|
|
|
case "Linux":
|
|
|
|
return FIND_FIREFOX_SEARCH_PATHS_UNIX();
|
|
|
|
case "Mac":
|
|
|
|
return FIND_FIREFOX_SEARCH_PATHS_OSX();
|
|
|
|
case "BSD":
|
|
|
|
return FIND_FIREFOX_SEARCH_PATHS_UNIX();
|
|
|
|
default:
|
|
|
|
return FIND_ALL_FIREFOX_SEARCH_PATHS();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private static String[] NEARBY_FIREFOX_SEARCH_PATHS() {
|
|
|
|
// obtain the PLUGIN environment variable
|
|
|
|
String plugin = System.getenv("PLUGIN");
|
|
|
|
// search the plugin directory for anything named "firefox", "firefox-bin",
|
|
|
|
// "firefox-esr", "waterfox", "waterfox-bin", "librewolf" up to a depth of 2
|
|
|
|
// directories deep. list the directories in the plugin directory
|
|
|
|
if (plugin != null && !plugin.isEmpty()) {
|
|
|
|
File pluginDir = new File(plugin);
|
|
|
|
if (pluginDir.exists()) {
|
|
|
|
File[] pluginDirs = pluginDir.listFiles();
|
|
|
|
// list the files in the plugin directory
|
|
|
|
for (File pluginDir1 : pluginDirs) {
|
|
|
|
File[] pluginFiles = pluginDir1.listFiles();
|
|
|
|
// list the files in the plugin directory
|
|
|
|
if (pluginFiles != null) {
|
|
|
|
for (File pluginFile : pluginFiles) {
|
|
|
|
if (pluginFile.getName().equals("firefox") ||
|
|
|
|
pluginFile.getName().equals("firefox-bin") ||
|
|
|
|
pluginFile.getName().equals("firefox-esr") ||
|
|
|
|
pluginFile.getName().equals("waterfox") ||
|
|
|
|
pluginFile.getName().equals("waterfox-bin") ||
|
|
|
|
pluginFile.getName().equals("librewolf")) {
|
|
|
|
return new String[] {pluginFile.getAbsolutePath()};
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// now, do the same thing, but with user.dir instead of plugin
|
|
|
|
// list the directories in the user.dir directory
|
|
|
|
File userDir = new File(System.getProperty("user.dir"));
|
|
|
|
if (userDir.exists()) {
|
|
|
|
File[] userDirs = userDir.listFiles();
|
|
|
|
// list the files in the user.dir directory
|
|
|
|
for (File userDir1 : userDirs) {
|
|
|
|
File[] userFiles = userDir1.listFiles();
|
|
|
|
// list the files in the user.dir directory
|
|
|
|
if (userFiles != null) {
|
|
|
|
for (File userFile : userFiles) {
|
2022-09-05 21:08:11 -04:00
|
|
|
if (userFile.isDirectory())
|
|
|
|
continue;
|
2022-08-30 15:49:44 -04:00
|
|
|
if (userFile.getName().equals("firefox") ||
|
|
|
|
userFile.getName().equals("firefox-bin") ||
|
|
|
|
userFile.getName().equals("firefox-esr") ||
|
|
|
|
userFile.getName().equals("waterfox") ||
|
|
|
|
userFile.getName().equals("waterfox-bin") ||
|
|
|
|
userFile.getName().equals("librewolf")) {
|
|
|
|
return new String[] {userFile.getAbsolutePath()};
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return new String[] {};
|
|
|
|
}
|
|
|
|
private static String[] FIREFOX_FINDER() {
|
|
|
|
String[] nearby = NEARBY_FIREFOX_SEARCH_PATHS();
|
|
|
|
String[] all = FIND_FIREFOX_SEARCH_PATHS();
|
2022-08-07 12:06:05 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
if (nearby != null && nearby.length > 0) {
|
|
|
|
return nearby;
|
|
|
|
} else if (all != null && all.length > 0) {
|
|
|
|
return all;
|
|
|
|
} else {
|
|
|
|
return new String[] {};
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
|
|
|
private static String getOperatingSystem() {
|
|
|
|
String os = System.getProperty("os.name");
|
|
|
|
if (os.startsWith("Windows")) {
|
|
|
|
return "Windows";
|
|
|
|
} else if (os.contains("Linux")) {
|
|
|
|
return "Linux";
|
|
|
|
} else if (os.contains("BSD")) {
|
|
|
|
return "BSD";
|
|
|
|
} else if (os.contains("Mac")) {
|
|
|
|
return "Mac";
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return "Unknown";
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Check our list of firefox paths for a valid firefox binary.
|
|
|
|
* Just an existence check for now, but should check versions
|
|
|
|
* in the future.
|
|
|
|
*
|
|
|
|
* @return a list of usable Firefoxes, or an empty list if none are found.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public String[] onlyValidFirefoxes() {
|
|
|
|
String[] firefoxes = FIREFOX_FINDER();
|
|
|
|
ArrayList<String> validFirefoxes = new ArrayList<String>();
|
|
|
|
for (String firefox : firefoxes) {
|
|
|
|
File firefoxFile = new File(firefox);
|
|
|
|
if (firefoxFile.exists()) {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Found valid firefox at " + firefox);
|
2022-08-30 15:49:44 -04:00
|
|
|
validFirefoxes.add(firefox);
|
|
|
|
}
|
2022-09-05 00:19:59 -04:00
|
|
|
println("firefox at " + firefox + "does not exist");
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return validFirefoxes.toArray(new String[validFirefoxes.size()]);
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Return the best available Firefox from the list of Firefoxes we have.
|
|
|
|
*
|
|
|
|
* @return the path to the best available Firefox, or null if none are found.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public String topFirefox() {
|
|
|
|
// get the FIREFOX environment variable
|
|
|
|
String firefox = System.getenv("FIREFOX");
|
|
|
|
// if it is not null and not empty
|
|
|
|
if (firefox != null && !firefox.isEmpty()) {
|
|
|
|
// check if the file exists
|
|
|
|
File firefoxFile = new File(firefox);
|
|
|
|
if (firefoxFile.exists()) {
|
|
|
|
// if it does, return it
|
|
|
|
return firefox;
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
String[] firefoxes = onlyValidFirefoxes();
|
|
|
|
if (firefoxes.length > 0) {
|
|
|
|
return firefoxes[0];
|
|
|
|
} else {
|
|
|
|
return "";
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Return the best available Firefox from the list of Firefoxes we have.
|
|
|
|
* if override is passed it will be validated and if it validates, it will
|
|
|
|
* be used.
|
|
|
|
*
|
|
|
|
* @param override the path to a valid Firefox binary to use.
|
|
|
|
* @return the path to the best available Firefox, or null if none are found.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public String topFirefox(String overrideFirefox) {
|
|
|
|
if (overrideFirefox != null && !overrideFirefox.isEmpty()) {
|
|
|
|
File firefoxFile = new File(overrideFirefox);
|
|
|
|
if (firefoxFile.exists()) {
|
|
|
|
return overrideFirefox;
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return topFirefox();
|
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Build a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile.
|
|
|
|
*
|
|
|
|
* @return a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public ProcessBuilder defaultProcessBuilder() {
|
|
|
|
return processBuilder(new String[] {});
|
|
|
|
}
|
2022-08-27 13:27:28 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* * Build a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile.
|
|
|
|
*
|
|
|
|
* @param args the args to pass to the Firefox binary
|
|
|
|
* @return a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile.
|
|
|
|
*/
|
|
|
|
public ProcessBuilder defaultProcessBuilder(String[] args) {
|
|
|
|
return processBuilder(args);
|
|
|
|
}
|
2022-08-19 18:30:14 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Build a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile. Pass the --private-window flag to
|
|
|
|
* open a private window.
|
|
|
|
*
|
|
|
|
* @param args the arguments to pass to the Firefox binary.
|
|
|
|
* @return a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public ProcessBuilder privateProcessBuilder() {
|
|
|
|
return processBuilder(new String[] {"--private-window"});
|
|
|
|
}
|
2022-08-27 13:27:28 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* * Build a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile. Pass the --private-window flag to
|
|
|
|
* open a private window.
|
|
|
|
*
|
|
|
|
* @param args the arguments to pass to the Firefox binary
|
|
|
|
* @return a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile.
|
|
|
|
*/
|
|
|
|
public ProcessBuilder privateProcessBuilder(String[] args) {
|
|
|
|
ArrayList<String> argList = new ArrayList<String>();
|
|
|
|
argList.add("--private-window");
|
2022-09-03 21:38:20 -04:00
|
|
|
if (args != null) {
|
|
|
|
if (args.length > 0) {
|
|
|
|
for (String arg : args) {
|
|
|
|
argList.add(arg);
|
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-27 13:27:28 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return processBuilder(argList.toArray(new String[argList.size()]));
|
|
|
|
}
|
2022-08-27 13:27:28 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Build a ProcessBuilder for the top Firefox binary and
|
|
|
|
* the default profile, with a specific set of extended
|
|
|
|
* arguments.
|
|
|
|
*
|
|
|
|
* @param args the extended arguments to pass to the Firefox binary.
|
|
|
|
* @return a ProcessBuilder for the top Firefox binary and
|
|
|
|
* default profile, with a specific set of extended arguments.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public ProcessBuilder processBuilder(String[] args) {
|
|
|
|
String firefox = topFirefox();
|
|
|
|
if (!firefox.isEmpty()) {
|
2022-09-03 21:38:20 -04:00
|
|
|
int arglength = 0;
|
|
|
|
if (args != null)
|
|
|
|
arglength = args.length;
|
2022-09-05 10:16:52 -04:00
|
|
|
String[] newArgs = new String[arglength + 5];
|
2022-08-30 15:49:44 -04:00
|
|
|
newArgs[0] = firefox;
|
2022-09-04 23:11:25 -04:00
|
|
|
newArgs[1] = "-attach-console";
|
2022-09-05 10:16:52 -04:00
|
|
|
newArgs[2] = "--new-instance";
|
|
|
|
newArgs[3] = "--profile";
|
|
|
|
newArgs[4] = I2PFirefoxProfileBuilder.profileDirectory();
|
2022-09-03 21:38:20 -04:00
|
|
|
if (args != null) {
|
|
|
|
if (arglength > 0) {
|
|
|
|
for (int i = 0; i < arglength; i++) {
|
2022-09-05 10:16:52 -04:00
|
|
|
newArgs[i + 5] = args[i];
|
2022-09-03 21:38:20 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
|
|
|
return new ProcessBuilder(newArgs).directory(
|
|
|
|
I2PFirefoxProfileBuilder.runtimeDirectory(true));
|
|
|
|
} else {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("No Firefox found.");
|
2022-08-30 15:49:44 -04:00
|
|
|
return new ProcessBuilder(args);
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Waits for an HTTP proxy on port 4444 to be ready.
|
|
|
|
* Returns false on timeout of 200 seconds.
|
|
|
|
*
|
|
|
|
* @return true if the proxy is ready, false if it is not.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public boolean waitForProxy() { return waitForProxy(DEFAULT_TIMEOUT); }
|
2022-08-07 13:12:43 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Waits for an HTTP proxy on port 4444 to be ready.
|
|
|
|
* Returns false on timeout of the specified number of seconds.
|
|
|
|
*
|
|
|
|
* @param timeout the number of seconds to wait for the proxy to be ready.
|
|
|
|
* @return true if the proxy is ready, false if it is not.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public boolean waitForProxy(int timeout) {
|
|
|
|
return waitForProxy(timeout, 4444);
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Waits for an HTTP proxy on the specified port to be ready.
|
|
|
|
* Returns false on timeout of the specified number of seconds.
|
|
|
|
*
|
|
|
|
* @param timeout the number of seconds to wait for the proxy to be ready.
|
|
|
|
* @param port the port to wait for the proxy to be ready on.
|
|
|
|
* @return true if the proxy is ready, false if it is not.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public boolean waitForProxy(int timeout, int port) {
|
|
|
|
return waitForProxy(timeout, port, "localhost");
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Waits for an HTTP proxy on the specified port to be ready.
|
|
|
|
* Returns false on timeout of the specified number of seconds.
|
|
|
|
*
|
|
|
|
* @param timeout the number of seconds to wait for the proxy to be ready.
|
|
|
|
* @param port the port to wait for the proxy to be ready on.
|
|
|
|
* @param host the host to wait for the proxy to be ready on.
|
|
|
|
* @return true if the proxy is ready, false if it is not.
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public boolean waitForProxy(int timeout, int port, String host) {
|
|
|
|
for (int i = 0; i < timeout; i++) {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Waiting for proxy");
|
2022-08-30 15:49:44 -04:00
|
|
|
if (checkifPortIsOccupied(port, host)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
Thread.sleep(1000);
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2022-08-07 02:26:04 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
private boolean checkifPortIsOccupied(int port, String host) {
|
|
|
|
try {
|
|
|
|
Socket socket = new Socket(host, port);
|
|
|
|
socket.close();
|
|
|
|
return true;
|
|
|
|
} catch (IOException e) {
|
|
|
|
return false;
|
2022-08-07 02:26:04 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-28 00:25:21 -04:00
|
|
|
|
2022-08-30 17:23:56 -04:00
|
|
|
private String usabilityMode() {
|
|
|
|
if (usability) {
|
|
|
|
return "usability";
|
|
|
|
}
|
|
|
|
return "base";
|
|
|
|
}
|
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
public Process launchAndDetatch(boolean privateWindow, String[] url) {
|
2022-09-05 21:08:11 -04:00
|
|
|
validateUserDir();
|
2022-08-30 15:49:44 -04:00
|
|
|
if (waitForProxy()) {
|
|
|
|
String profileDirectory = I2PFirefoxProfileBuilder.profileDirectory();
|
|
|
|
if (I2PFirefoxProfileChecker.validateProfileDirectory(profileDirectory)) {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Valid profile directory: " + profileDirectory);
|
2022-08-30 15:49:44 -04:00
|
|
|
} else {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Invalid profile directory: " + profileDirectory +
|
|
|
|
" rebuilding...");
|
2022-08-30 17:23:56 -04:00
|
|
|
if (!I2PFirefoxProfileBuilder.copyBaseProfiletoProfile(
|
|
|
|
usabilityMode())) {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Failed to rebuild profile directory: " + profileDirectory);
|
2022-08-30 15:49:44 -04:00
|
|
|
return null;
|
|
|
|
} else {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Rebuilt profile directory: " + profileDirectory);
|
2022-08-28 00:25:21 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-09-04 10:59:35 -04:00
|
|
|
if (validateProfileFirstRun(profileDirectory))
|
|
|
|
return null;
|
2022-08-30 15:49:44 -04:00
|
|
|
ProcessBuilder pb;
|
|
|
|
if (privateWindow) {
|
|
|
|
pb = privateProcessBuilder(url);
|
|
|
|
} else {
|
|
|
|
pb = defaultProcessBuilder(url);
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
System.out.println(pb.command());
|
|
|
|
p = pb.start();
|
2022-09-05 00:19:59 -04:00
|
|
|
println("I2PFirefox");
|
2022-08-30 15:49:44 -04:00
|
|
|
sleep(2000);
|
|
|
|
return p;
|
|
|
|
} catch (Throwable e) {
|
|
|
|
System.out.println(e);
|
|
|
|
}
|
2022-08-28 00:25:21 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return null;
|
|
|
|
}
|
2022-08-28 00:25:21 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Populates a profile directory with a proxy configuration.
|
|
|
|
* Waits for an HTTP proxy on the port 4444 to be ready.
|
|
|
|
* Launches Firefox with the profile directory.
|
|
|
|
*
|
|
|
|
* @param bool if true, the profile will be ephemeral(i.e. a --private-window
|
|
|
|
* profile).
|
|
|
|
* @param String[] a list of URL's to pass to the browser window
|
|
|
|
* @since 0.0.17
|
|
|
|
*/
|
|
|
|
public void launch(boolean privateWindow, String[] url) {
|
|
|
|
if (waitForProxy()) {
|
|
|
|
p = launchAndDetatch(privateWindow, url);
|
2022-09-04 10:59:35 -04:00
|
|
|
if (p == null)
|
|
|
|
return;
|
2022-08-30 15:49:44 -04:00
|
|
|
try {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Waiting for I2PFirefox to close...");
|
2022-08-30 15:49:44 -04:00
|
|
|
int exit = p.waitFor();
|
2022-09-05 00:19:59 -04:00
|
|
|
println("I2PFirefox exited with value: " + exit);
|
2022-08-30 15:49:44 -04:00
|
|
|
} catch (Exception e) {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Error: " + e.getMessage());
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:26:04 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:26:04 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Populates a profile directory with a proxy configuration.
|
|
|
|
* Waits for an HTTP proxy on the port 4444 to be ready.
|
|
|
|
* Launches Firefox with the profile directory.
|
|
|
|
*
|
|
|
|
* @param bool if true, the profile will be ephemeral(i.e. a --private-window
|
|
|
|
* profile).
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public void launch(boolean privateWindow) { launch(privateWindow, null); }
|
2022-08-27 13:27:28 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
/**
|
|
|
|
* Populates a profile directory with a proxy configuration.
|
|
|
|
* Waits for an HTTP proxy on the port 4444 to be ready.
|
|
|
|
* Launches Firefox with the profile directory. Uses a semi-permanent
|
|
|
|
* profile.
|
|
|
|
*
|
|
|
|
* @since 0.0.1
|
|
|
|
*/
|
|
|
|
public void launch() { launch(false); }
|
2022-08-19 18:30:14 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
private static String ValidURL(String inUrl) {
|
|
|
|
String[] schemes = {"http", "https"};
|
|
|
|
for (String scheme : schemes) {
|
|
|
|
if (inUrl.startsWith(scheme)) {
|
2022-09-05 00:19:59 -04:00
|
|
|
println("Valid URL: " + inUrl);
|
2022-08-30 15:49:44 -04:00
|
|
|
return inUrl;
|
|
|
|
}
|
2022-08-27 13:27:28 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
return "";
|
|
|
|
}
|
2022-08-27 13:27:28 -04:00
|
|
|
|
2022-08-30 15:49:44 -04:00
|
|
|
public static void main(String[] args) {
|
2022-09-05 21:08:11 -04:00
|
|
|
validateUserDir();
|
2022-08-30 15:49:44 -04:00
|
|
|
boolean privateBrowsing = false;
|
2022-09-05 00:19:59 -04:00
|
|
|
println("checking for private browsing");
|
2022-08-30 15:49:44 -04:00
|
|
|
ArrayList<String> visitURL = new ArrayList<String>();
|
2022-09-03 21:38:20 -04:00
|
|
|
if (args != null) {
|
|
|
|
if (args.length > 0) {
|
|
|
|
for (String arg : args) {
|
|
|
|
if (arg.equals("-private")) {
|
|
|
|
privateBrowsing = true;
|
2022-09-05 00:19:59 -04:00
|
|
|
println(
|
2022-09-03 21:38:20 -04:00
|
|
|
"private browsing is true, profile will be discarded at end of session");
|
|
|
|
}
|
|
|
|
if (arg.equals("-usability")) {
|
|
|
|
usability = true;
|
|
|
|
}
|
|
|
|
if (!arg.startsWith("-")) {
|
|
|
|
// check if it's a URL
|
|
|
|
visitURL.add(ValidURL(arg));
|
|
|
|
}
|
2022-08-21 20:01:34 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
|
|
|
}
|
2022-09-05 00:19:59 -04:00
|
|
|
println("I2PFirefox");
|
2022-08-30 15:49:44 -04:00
|
|
|
I2PFirefox i2pFirefox = new I2PFirefox();
|
|
|
|
i2pFirefox.launch(privateBrowsing,
|
|
|
|
visitURL.toArray(new String[visitURL.size()]));
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void sleep(int millis) {
|
|
|
|
try {
|
|
|
|
Thread.sleep(millis);
|
|
|
|
} catch (InterruptedException bad) {
|
|
|
|
bad.printStackTrace();
|
|
|
|
throw new RuntimeException(bad);
|
2022-08-21 20:01:34 -04:00
|
|
|
}
|
2022-08-30 15:49:44 -04:00
|
|
|
}
|
2022-08-07 02:00:32 -04:00
|
|
|
}
|