Don't enqueue stdout from Meek subprocess in a Thread, just read it as it comes. Solves infinite loop queue read issue on cleanup()

This commit is contained in:
Miguel Jacq 2021-12-15 18:28:55 +11:00
parent 4b18cb7d0f
commit 2689f35635
No known key found for this signature in database
GPG key ID: EEA4341C6D97A0B6

View file

@ -20,8 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import subprocess
import time
from queue import Queue, Empty
from threading import Thread
class Meek(object):
@ -67,14 +65,6 @@ class Meek(object):
Start the Meek Client and populate the SOCKS proxies dict
for use with requests to the Tor Moat API.
"""
# Small method to read stdout from the subprocess.
# We use this to obtain the random port that Meek
# started on
def enqueue_output(out, queue):
for line in iter(out.readline, b""):
queue.put(line)
out.close()
# Abort early if we can't find the Meek client
if self.meek_client_file_path is None or not os.path.exists(
self.meek_client_file_path
@ -124,34 +114,22 @@ class Meek(object):
universal_newlines=True,
)
# Queue up the stdout from the subprocess for polling later
q = Queue()
t = Thread(target=enqueue_output, args=(self.meek_proc.stdout, q))
t.daemon = True # thread dies with the program
t.start()
# Obtain the host and port that meek is running on
for line in iter(self.meek_proc.stdout.readline, b""):
if "CMETHOD meek socks5" in line:
self.meek_host = line.split(" ")[3].split(":")[0]
self.meek_port = line.split(" ")[3].split(":")[1]
self.common.log(
"Meek",
"start",
f"Meek running on {self.meek_host}:{self.meek_port}",
)
break
while True:
# read stdout without blocking
try:
line = q.get_nowait()
self.common.log("Meek", "start", line.strip())
except Empty:
# no stdout yet?
pass
else: # we got stdout
if "CMETHOD meek socks5" in line:
self.meek_host = line.split(" ")[3].split(":")[0]
self.meek_port = line.split(" ")[3].split(":")[1]
self.common.log(
"Meek",
"start",
f"Meek running on {self.meek_host}:{self.meek_port}",
)
break
if "CMETHOD-ERROR" in line:
self.cleanup()
raise MeekNotRunning()
if "CMETHOD-ERROR" in line:
self.cleanup()
raise MeekNotRunning()
break
if self.meek_port:
self.meek_proxies = {