Fix Firefox proxy PAC loop: handle proxyType and avoid re-apply when we have control
CI / Build & Test (push) Successful in 3m12s
CI / Build & Test (push) Successful in 3m12s
- Treat PAC as active when mode === 'pac_script' (Chrome) or proxyType === 'autoConfig' (Firefox) so we don't mis-detect "not active" in Firefox. - In proxy.settings.onChange, only call applyPAC() when levelOfControl !== 'controlled_by_this_extension'. When we still have control, return without re-applying to stop the set -> onChange -> applyPAC loop.
This commit is contained in:
@@ -5,7 +5,12 @@
|
||||
* or system setting overrides the proxy configuration.
|
||||
* Depends on: state.js (extensionState, pacConfirmedActive, DEFAULT_CONNECT_PROXY_PORT, DEFAULT_PROXY_PORT)
|
||||
* Depends on: logs.js (log, debugLog)
|
||||
*
|
||||
* In Firefox, proxy.settings requires "Allow in Private Windows" for the extension.
|
||||
* When that permission is missing we skip PAC set/clear and notify once.
|
||||
*/
|
||||
let pacFirefoxPrivateBrowsingBlocked = false;
|
||||
let pacFirefoxPrivateBrowsingNotified = false;
|
||||
|
||||
/** Extract unique two-label base domains from virtualHosts array, always including hole.sail */
|
||||
function getActiveTlds(virtualHosts) {
|
||||
@@ -29,6 +34,10 @@ function applyPAC(tlds) {
|
||||
log('applyPAC: SKIPPED - no browser.proxy.settings API');
|
||||
return;
|
||||
}
|
||||
if (pacFirefoxPrivateBrowsingBlocked) {
|
||||
debugLog('applyPAC: SKIPPED - Firefox private browsing permission required (user must enable in about:addons)');
|
||||
return;
|
||||
}
|
||||
const proxyPort = extensionState.connectProxyPort ?? DEFAULT_CONNECT_PROXY_PORT ?? extensionState.proxyPort ?? DEFAULT_PROXY_PORT;
|
||||
const activeTlds = tlds || getActiveTlds(extensionState.virtualHosts);
|
||||
log('applyPAC: setting PAC port=', proxyPort, 'tlds=', activeTlds);
|
||||
@@ -42,7 +51,25 @@ function applyPAC(tlds) {
|
||||
{ value: { mode: 'pac_script', pacScript: { data: pacData, mandatory: false } }, scope: 'regular' },
|
||||
() => {
|
||||
if (browser.runtime.lastError) {
|
||||
log('applyPAC: ERROR:', browser.runtime.lastError.message);
|
||||
const msg = browser.runtime.lastError.message || '';
|
||||
if (msg.includes('private browsing') || msg.includes('private window')) {
|
||||
pacFirefoxPrivateBrowsingBlocked = true;
|
||||
pacConfirmedActive = false;
|
||||
if (!pacFirefoxPrivateBrowsingNotified) {
|
||||
pacFirefoxPrivateBrowsingNotified = true;
|
||||
log('applyPAC: Firefox requires "Allow in Private Windows" for proxy. Enable it in about:addons for this extension.');
|
||||
if (browser.notifications && browser.notifications.create) {
|
||||
browser.notifications.create('holesail-pac-private-browsing', {
|
||||
type: 'basic',
|
||||
title: 'Holesail Browser',
|
||||
message: 'To use the proxy in Firefox, enable "Allow in Private Windows" for this extension in about:addons.',
|
||||
iconUrl: browser.runtime.getURL ? browser.runtime.getURL('icons/48.png') : undefined,
|
||||
}).catch(() => {});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
log('applyPAC: ERROR:', msg);
|
||||
pacConfirmedActive = false;
|
||||
return;
|
||||
}
|
||||
@@ -51,15 +78,18 @@ function applyPAC(tlds) {
|
||||
log('applyPAC: get ERROR:', browser.runtime.lastError.message);
|
||||
return;
|
||||
}
|
||||
const mode = details && details.value && details.value.mode;
|
||||
const val = details && details.value;
|
||||
const mode = val && val.mode;
|
||||
const proxyType = val && val.proxyType;
|
||||
const loc = details && details.levelOfControl;
|
||||
log('applyPAC: mode=', mode, 'levelOfControl=', loc);
|
||||
if (loc === 'controlled_by_this_extension' && mode === 'pac_script') {
|
||||
log('applyPAC: mode=', mode, 'proxyType=', proxyType, 'levelOfControl=', loc);
|
||||
const isPacActive = (mode === 'pac_script') || (proxyType === 'autoConfig');
|
||||
if (loc === 'controlled_by_this_extension' && isPacActive) {
|
||||
pacConfirmedActive = true;
|
||||
log('applyPAC: ACTIVE');
|
||||
} else {
|
||||
pacConfirmedActive = false;
|
||||
log('applyPAC: WARNING not active - mode=', mode, 'loc=', loc);
|
||||
log('applyPAC: WARNING not active - mode=', mode, 'proxyType=', proxyType, 'loc=', loc);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -70,10 +100,13 @@ function applyPAC(tlds) {
|
||||
if (browser.proxy && browser.proxy.settings && browser.proxy.settings.onChange) {
|
||||
browser.proxy.settings.onChange.addListener((details) => {
|
||||
const loc = details && details.levelOfControl;
|
||||
const mode = details && details.value && details.value.mode;
|
||||
log('proxy.settings.onChange: levelOfControl=', loc, 'mode=', mode);
|
||||
if (loc === 'controlled_by_this_extension' && mode === 'pac_script') {
|
||||
pacConfirmedActive = true;
|
||||
const val = details && details.value;
|
||||
const mode = val && val.mode;
|
||||
const proxyType = val && val.proxyType;
|
||||
log('proxy.settings.onChange: levelOfControl=', loc, 'mode=', mode, 'proxyType=', proxyType);
|
||||
if (loc === 'controlled_by_this_extension') {
|
||||
const isPacActive = (mode === 'pac_script') || (proxyType === 'autoConfig');
|
||||
if (isPacActive) pacConfirmedActive = true;
|
||||
return;
|
||||
}
|
||||
pacConfirmedActive = false;
|
||||
@@ -88,6 +121,7 @@ if (browser.proxy && browser.proxy.settings && browser.proxy.settings.onChange)
|
||||
*/
|
||||
function clearProxy() {
|
||||
debugLog('clearProxy');
|
||||
if (pacFirefoxPrivateBrowsingBlocked) return;
|
||||
if (!browser.proxy || !browser.proxy.settings) return;
|
||||
browser.proxy.settings.set({ value: { mode: 'direct' }, scope: 'regular' }).catch(() => {});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user