Skip to content
Snippets Groups Projects
Verified Commit d783693d authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame :jack_o_lantern:
Browse files

fixup! Bug 40933: Add tor-launcher functionality

Bug 42479: Remove localization from the backend files.

Also, use an Error object when the bootstrap fail, in preparation to the
removal of TorBootstrapRequest.
parent 05bda694
Branches
Tags
1 merge request!968Draft: Bug 42479: Improve TorConnect error handling
import { setTimeout, clearTimeout } from "resource://gre/modules/Timer.sys.mjs";
import { TorProviderBuilder } from "resource://gre/modules/TorProviderBuilder.sys.mjs";
import { TorLauncherUtil } from "resource://gre/modules/TorLauncherUtil.sys.mjs";
/* tor-launcher observer topics */
export const TorTopics = Object.freeze({
BootstrapStatus: "TorBootstrapStatus",
BootstrapError: "TorBootstrapError",
LogHasWarnOrErr: "TorLogHasWarnOrErr",
});
// modeled after XMLHttpRequest
// nicely encapsulates the observer register/unregister logic
// TODO: Remove this class, and move its logic inside the TorProvider.
export class TorBootstrapRequest {
// number of ms to wait before we abandon the bootstrap attempt
// a value of 0 implies we never wait
......@@ -20,7 +19,7 @@ export class TorBootstrapRequest {
// callbacks for bootstrap process status updates
onbootstrapstatus = (progress, status) => {};
onbootstrapcomplete = () => {};
onbootstraperror = (message, details) => {};
onbootstraperror = error => {};
// internal resolve() method for bootstrap
#bootstrapPromiseResolve = null;
......@@ -32,8 +31,8 @@ export class TorBootstrapRequest {
switch (topic) {
case TorTopics.BootstrapStatus: {
const progress = obj.PROGRESS;
const status = TorLauncherUtil.getLocalizedBootstrapStatus(obj, "TAG");
if (this.onbootstrapstatus) {
const status = obj.TAG;
this.onbootstrapstatus(progress, status);
}
if (progress === 100) {
......@@ -49,7 +48,9 @@ export class TorBootstrapRequest {
}
case TorTopics.BootstrapError: {
console.info("TorBootstrapRequest: observerd TorBootstrapError", obj);
this.#stop(obj?.message, obj?.details);
const error = new Error(obj.summary);
error.details = obj;
this.#stop(error);
break;
}
}
......@@ -103,7 +104,7 @@ export class TorBootstrapRequest {
}
// Internal implementation. Do not use directly, but call cancel, instead.
async #stop(message, details) {
async #stop(error) {
// first stop our bootstrap timeout before handling the error
if (this.#timeoutID !== null) {
clearTimeout(this.#timeoutID);
......@@ -121,14 +122,13 @@ export class TorBootstrapRequest {
await provider?.stopBootstrap();
} catch (e) {
console.error("Failed to stop the bootstrap.", e);
if (!message) {
message = e.message;
details = "";
if (!error) {
error = e;
}
}
if (this.onbootstraperror && message) {
this.onbootstraperror(message, details);
if (this.onbootstraperror && error) {
this.onbootstraperror(error);
}
this.#bootstrapPromiseResolve(false);
......
......@@ -441,58 +441,6 @@ export const TorLauncherUtil = Object.freeze({
return aStringName;
},
getLocalizedBootstrapStatus(aStatusObj, aKeyword) {
if (!aStatusObj || !aKeyword) {
return "";
}
let result;
let fallbackStr;
if (aStatusObj[aKeyword]) {
let val = aStatusObj[aKeyword].toLowerCase();
let key;
if (aKeyword === "TAG") {
// The bootstrap status tags in tagMap below are used by Tor
// versions prior to 0.4.0.x. We map each one to the tag that will
// produce the localized string that is the best fit.
const tagMap = {
conn_dir: "conn",
handshake_dir: "onehop_create",
conn_or: "enough_dirinfo",
handshake_or: "ap_conn",
};
if (val in tagMap) {
val = tagMap[val];
}
key = "bootstrapStatus." + val;
fallbackStr = aStatusObj.SUMMARY;
} else if (aKeyword === "REASON") {
if (val === "connectreset") {
val = "connectrefused";
}
key = "bootstrapWarning." + val;
fallbackStr = aStatusObj.WARNING;
}
result = TorLauncherUtil.getLocalizedString(key);
if (result === key) {
result = undefined;
}
}
if (!result) {
result = fallbackStr;
}
if (aKeyword === "REASON" && aStatusObj.HOSTADDR) {
result += " - " + aStatusObj.HOSTADDR;
}
return result ? result : "";
},
/**
* Determine what kind of SOCKS port has been requested for this session or
* the browser has been configured for.
......
......@@ -911,6 +911,7 @@ export class TorProvider {
* @param {object} status The status object
*/
onBootstrapStatus(status) {
logger.debug("Received bootstrap status update", status);
this.#processBootstrapStatus(status, true);
}
......@@ -939,6 +940,7 @@ export class TorProvider {
this.#isBootstrapDone = false;
// Can TYPE ever be ERR for STATUS_CLIENT?
if (
isNotification &&
statusObj.TYPE === "WARN" &&
......@@ -959,20 +961,7 @@ export class TorProvider {
} catch (e) {
logger.warn(`Cannot set ${Preferences.PromptAtStartup}`, e);
}
// TODO: Move l10n to the above layers?
const phase = TorLauncherUtil.getLocalizedBootstrapStatus(statusObj, "TAG");
const reason = TorLauncherUtil.getLocalizedBootstrapStatus(
statusObj,
"REASON"
);
const details = TorLauncherUtil.getFormattedLocalizedString(
"tor_bootstrap_failed_details",
[phase, reason],
2
);
logger.error(
`Tor bootstrap error: [${statusObj.TAG}/${statusObj.REASON}] ${details}`
);
logger.error("Tor bootstrap error", statusObj);
if (
statusObj.TAG !== this.#lastWarning.phase ||
......@@ -981,11 +970,19 @@ export class TorProvider {
this.#lastWarning.phase = statusObj.TAG;
this.#lastWarning.reason = statusObj.REASON;
const message = TorLauncherUtil.getLocalizedString(
"tor_bootstrap_failed"
);
// FIXME: currently, this is observed only by TorBoostrapRequest.
// We should remove that class, and use an async method to do the
// bootstrap here.
// At that point, the lastWarning mechanism will probably not be necessary
// anymore, since the first error eligible for notification will as a
// matter of fact cancel the bootstrap.
Services.obs.notifyObservers(
{ message, details },
{
phase: statusObj.TAG,
reason: statusObj.REASON,
summary: statusObj.SUMMARY,
warning: statusObj.WARNING,
},
TorProviderTopics.BootstrapError
);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment