Skip to content

Commit 8ddf3f4

Browse files
ndanner-wesleyancsvringar
authored andcommitted
feat(browser_manager): enable full XPI cleanup
1 parent 02f745a commit 8ddf3f4

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

openwpm/browser_manager.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,25 @@ def check_queue(launch_status: Dict[str, bool]) -> Any:
158158
# Resets the command/status queues
159159
(self.command_queue, self.status_queue) = (Queue(), Queue())
160160

161+
# Create a unique temporary directory for this spawn attempt.
162+
# This is created inside the loop so each retry gets a fresh
163+
# tmpdir (close_browser_manager deletes it on failure).
164+
if self.browser_params.tmpdir is not None:
165+
self.logger.debug(
166+
"BROWSER %i: Deleting leftover temp directory %s"
167+
% (self.browser_id, self.browser_params.tmpdir)
168+
)
169+
shutil.rmtree(self.browser_params.tmpdir, ignore_errors=True)
170+
self.browser_params.tmpdir = Path(
171+
tempfile.mkdtemp(
172+
prefix="openwpm_", dir=os.getenv("TMPDIR", default="/tmp")
173+
)
174+
)
175+
self.logger.debug(
176+
"BROWSER %i: Using temp dir %s"
177+
% (self.browser_id, self.browser_params.tmpdir)
178+
)
179+
161180
# builds and launches the browser_manager
162181

163182
self.browser_manager = BrowserManager(
@@ -341,6 +360,22 @@ def close_browser_manager(self, force: bool = False) -> None:
341360
if not shutdown_complete:
342361
self.kill_browser_manager()
343362

363+
# Delete the temporary directory used by geckodriver.
364+
if self.browser_params.tmpdir is not None:
365+
try:
366+
shutil.rmtree(self.browser_params.tmpdir)
367+
self.logger.debug(
368+
"BROWSER %i: Deleted temp dir %s"
369+
% (self.browser_id, self.browser_params.tmpdir)
370+
)
371+
self.browser_params.tmpdir = None
372+
except Exception:
373+
self.logger.warning(
374+
"BROWSER %i: Failed to delete temp dir %s"
375+
% (self.browser_id, self.browser_params.tmpdir),
376+
exc_info=True,
377+
)
378+
344379
def execute_command_sequence(
345380
self,
346381
# Quoting to break cyclic import, see https://stackoverflow.com/a/39757388

openwpm/config.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class BrowserParams(DataClassJsonMixin):
103103
default=Path(tempfile.gettempdir()),
104104
metadata=DCJConfig(encoder=path_to_str, decoder=str_to_path),
105105
)
106+
106107
"""
107108
The tmp_profile_dir defaults to the OS's temporary file folder (typically /tmp) and is where the generated
108109
browser profiles and residual files are stored.
@@ -139,6 +140,18 @@ class BrowserParams(DataClassJsonMixin):
139140
140141
"""
141142

143+
tmpdir: Optional[Path] = field(
144+
default=None,
145+
metadata=DCJConfig(encoder=path_to_str, decoder=str_to_path),
146+
)
147+
"""
148+
The temporary directory used by `geckodriver`. This is configured in
149+
`BrowserManager.run` and then deleted when the browser is finished. We do
150+
this because it seems that `geckodriver` doesn't clean up its temporary
151+
files (in particular, a copy of the extension XPI file), so we need to do
152+
so ourselves.
153+
"""
154+
142155
recovery_tar: Optional[Path] = None
143156
donottrack: bool = False
144157
tracking_protection: bool = False

openwpm/deploy_browsers/deploy_firefox.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,15 @@ def deploy_firefox(
140140
# Launch the webdriver
141141
status_queue.put(("STATUS", "Launch Attempted", None))
142142

143+
# Use browser_params.tmpdir as the temporary directory. This is so that
144+
# geckodriver makes its copy of the extension XPI file in tmpdir, so
145+
# we can delete it later and not have it left behind. I make a shallow
146+
# copy of `os.environ` because I'm a little nervous about modifying the
147+
# OpenWPM process' environment.
148+
env = os.environ.copy()
149+
if browser_params.tmpdir is not None:
150+
env["TMPDIR"] = str(browser_params.tmpdir)
151+
143152
fo.binary_location = firefox_binary_path
144153
geckodriver_path = subprocess.check_output(
145154
"which geckodriver", encoding="utf-8", shell=True
@@ -149,6 +158,7 @@ def deploy_firefox(
149158
service=Service(
150159
executable_path=geckodriver_path,
151160
log_output=open(webdriver_interceptor.fifo, "w"),
161+
env=env,
152162
),
153163
)
154164

0 commit comments

Comments
 (0)