diff --git a/client/src/assembly/linux-jre.xml b/client/src/assembly/linux-jre.xml index 73a06723..21c6a1a1 100644 --- a/client/src/assembly/linux-jre.xml +++ b/client/src/assembly/linux-jre.xml @@ -26,6 +26,12 @@ true ctbrec-no-splash.sh + + ${project.basedir}/src/assembly/pac.js + ctbrec + true + pac.js + ${project.build.directory}/${project.artifactId}-${project.version}.jar ctbrec diff --git a/client/src/assembly/macos-jre.xml b/client/src/assembly/macos-jre.xml index e95f753c..72118aec 100644 --- a/client/src/assembly/macos-jre.xml +++ b/client/src/assembly/macos-jre.xml @@ -26,6 +26,12 @@ true ctbrec-no-splash.sh + + ${project.basedir}/src/assembly/pac.js + ctbrec + true + pac.js + ${project.build.directory}/${project.artifactId}-${project.version}.jar diff --git a/client/src/assembly/pac.js b/client/src/assembly/pac.js new file mode 100644 index 00000000..13e660ea --- /dev/null +++ b/client/src/assembly/pac.js @@ -0,0 +1,9 @@ +function FindProxyForURL(url, host) { + if (shExpMatch(host, "*stripchat.com")) { + return "SOCKS 127.0.0.1:1080"; + } else if (shExpMatch(host, "*chaturbate.com")) { + return "PROXY 127.0.0.1:8080"; + } else { + return "DIRECT"; + } +} \ No newline at end of file diff --git a/client/src/assembly/win64-jre.xml b/client/src/assembly/win64-jre.xml index 055294d8..f27fe380 100644 --- a/client/src/assembly/win64-jre.xml +++ b/client/src/assembly/win64-jre.xml @@ -22,6 +22,12 @@ ${project.build.directory}/ctbrec-no-splash.exe ctbrec + + ${project.basedir}/src/assembly/pac.js + ctbrec + true + pac.js + ${project.build.directory}/${project.artifactId}-${project.version}.jar ctbrec diff --git a/client/src/main/java/ctbrec/ui/settings/SettingsTab.java b/client/src/main/java/ctbrec/ui/settings/SettingsTab.java index f3ef962b..91dd91b4 100644 --- a/client/src/main/java/ctbrec/ui/settings/SettingsTab.java +++ b/client/src/main/java/ctbrec/ui/settings/SettingsTab.java @@ -85,6 +85,7 @@ public class SettingsTab extends Tab implements TabSelectionListener { private SimpleStringProperty proxyPort; private SimpleStringProperty proxyUser; private SimpleStringProperty proxyPassword; + private SimpleStringProperty pacUrl; private SimpleDirectoryProperty recordingsDir; private SimpleListProperty directoryStructure; private SimpleListProperty splitAfter; @@ -169,11 +170,12 @@ public class SettingsTab extends Tab implements TabSelectionListener { maximumResolutionPlayer = new SimpleIntegerProperty(null, "maximumResolutionPlayer", settings.maximumResolutionPlayer); showPlayerStarting = new SimpleBooleanProperty(null, "showPlayerStarting", settings.showPlayerStarting); singlePlayer = new SimpleBooleanProperty(null, "singlePlayer", settings.singlePlayer); - proxyType = new SimpleListProperty<>(null, "proxyType", FXCollections.observableList(List.of(DIRECT, HTTP, SOCKS4, SOCKS5))); + proxyType = new SimpleListProperty<>(null, "proxyType", FXCollections.observableList(List.of(DIRECT, HTTP, SOCKS4, SOCKS5, PAC))); proxyHost = new SimpleStringProperty(null, "proxyHost", settings.proxyHost); proxyPort = new SimpleStringProperty(null, "proxyPort", settings.proxyPort); proxyUser = new SimpleStringProperty(null, "proxyUser", settings.proxyUser); proxyPassword = new SimpleStringProperty(null, "proxyPassword", settings.proxyPassword); + pacUrl = new SimpleStringProperty(null, "pacUrl", settings.pacUrl); recordingsDir = new SimpleDirectoryProperty(null, "recordingsDir", settings.recordingsDir); directoryStructure = new SimpleListProperty<>(null, "recordingsDirStructure", FXCollections.observableList(List.of(FLAT, ONE_PER_MODEL, ONE_PER_GROUP, ONE_PER_RECORDING))); @@ -337,7 +339,8 @@ public class SettingsTab extends Tab implements TabSelectionListener { Setting.of("Host", proxyHost).needsRestart(), Setting.of("Port", proxyPort).needsRestart(), Setting.of("Username", proxyUser).needsRestart(), - Setting.of("Password", proxyPassword).needsRestart())), + Setting.of("Password", proxyPassword).needsRestart(), + Setting.of("PAC URL", pacUrl, "URL to your Proxy Auto-Config (PAC) file (e.g. http://example.com/pac.js or file:///G:/path/to/pac.js)").needsRestart())), Category.of("Advanced / Devtools", Group.of("Networking", Setting.of("Playlist request timeout (ms)", playlistRequestTimeout, "Timeout in ms for playlist requests"), diff --git a/common/pom.xml b/common/pom.xml index 67ac4199..563b674c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -8,7 +8,7 @@ ctbrec master - 25.9.22 + 25.9.27 ../master @@ -41,6 +41,11 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 + + org.bidib.com.github.markusbernhardt + proxy-vole + 1.1.6 + org.mapstruct mapstruct diff --git a/common/src/main/java/ctbrec/Settings.java b/common/src/main/java/ctbrec/Settings.java index f25d2a71..dac30376 100644 --- a/common/src/main/java/ctbrec/Settings.java +++ b/common/src/main/java/ctbrec/Settings.java @@ -32,7 +32,8 @@ public class Settings { DIRECT, HTTP, SOCKS4, - SOCKS5 + SOCKS5, + PAC } public enum SplitStrategy { @@ -151,6 +152,7 @@ public class Settings { public String proxyPort; public ProxyType proxyType = ProxyType.DIRECT; public String proxyUser; + public String pacUrl; public boolean recentlyWatched = true; public List recordLaterTableColumnOrder = new ArrayList<>(); public Map recordLaterTableColumnVisibility = new HashMap<>(); diff --git a/common/src/main/java/ctbrec/io/HttpClient.java b/common/src/main/java/ctbrec/io/HttpClient.java index c80533ec..4177a0d3 100644 --- a/common/src/main/java/ctbrec/io/HttpClient.java +++ b/common/src/main/java/ctbrec/io/HttpClient.java @@ -1,5 +1,7 @@ package ctbrec.io; +import com.github.markusbernhardt.proxy.selector.pac.PacProxySelector; +import com.github.markusbernhardt.proxy.selector.pac.UrlPacScriptSource; import com.fasterxml.jackson.core.type.TypeReference; import ctbrec.Config; import ctbrec.LoggingInterceptor; @@ -20,6 +22,7 @@ import java.io.File; import java.io.IOException; import java.net.Authenticator; import java.net.PasswordAuthentication; +import java.net.ProxySelector; import java.nio.file.Files; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -116,6 +119,18 @@ public abstract class HttpClient { Authenticator.setDefault(new SocksProxyAuth(username, password)); } break; + case PAC: + String pacUrl = config.getSettings().pacUrl; + if (pacUrl != null && !pacUrl.isEmpty()) { + try { + UrlPacScriptSource pacSource = new UrlPacScriptSource(pacUrl); + ProxySelector pacSelector = new PacProxySelector(pacSource); + ProxySelector.setDefault(pacSelector); + } catch (Exception e) { + log.warn("Failed to load PAC file: {}", e.getMessage()); + } + } + break; case DIRECT: default: System.clearProperty(ProxyConstants.HTTP_PROXY_HOST); @@ -248,6 +263,10 @@ public abstract class HttpClient { } } + if (config.getSettings().proxyType == ProxyType.PAC) { + builder.proxySelector(ProxySelector.getDefault()); + } + ProxyType proxyType = config.getSettings().proxyType; if (proxyType == ProxyType.HTTP) { String username = config.getSettings().proxyUser; diff --git a/server/src/assembly/pac.js b/server/src/assembly/pac.js new file mode 100644 index 00000000..13e660ea --- /dev/null +++ b/server/src/assembly/pac.js @@ -0,0 +1,9 @@ +function FindProxyForURL(url, host) { + if (shExpMatch(host, "*stripchat.com")) { + return "SOCKS 127.0.0.1:1080"; + } else if (shExpMatch(host, "*chaturbate.com")) { + return "PROXY 127.0.0.1:8080"; + } else { + return "DIRECT"; + } +} \ No newline at end of file diff --git a/server/src/assembly/server.xml b/server/src/assembly/server.xml index 54e2f54d..8ac19dd5 100644 --- a/server/src/assembly/server.xml +++ b/server/src/assembly/server.xml @@ -30,6 +30,12 @@ ${project.basedir}/LICENSE.txt ctbrec + + ${project.basedir}/src/assembly/pac.js + ctbrec + true + pac.js + ${project.basedir}/../CHANGELOG.md ctbrec