From 6a0994038e9439f6e38f8a3ad0c3f584337b7566 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 6 Sep 2015 19:50:03 +0200 Subject: [PATCH] Start working on #888 (new IPC path). --- qutebrowser/misc/ipc.py | 29 ++++++++++++++++++-------- tests/unit/misc/test_ipc.py | 41 +++++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/qutebrowser/misc/ipc.py b/qutebrowser/misc/ipc.py index c7a1c5108..f90a94561 100644 --- a/qutebrowser/misc/ipc.py +++ b/qutebrowser/misc/ipc.py @@ -30,7 +30,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject from PyQt5.QtNetwork import QLocalSocket, QLocalServer, QAbstractSocket import qutebrowser -from qutebrowser.utils import log, usertypes, error, objreg +from qutebrowser.utils import log, usertypes, error, objreg, standarddir CONNECT_TIMEOUT = 100 @@ -39,15 +39,28 @@ READ_TIMEOUT = 5000 PROTOCOL_VERSION = 1 -def _get_socketname(basedir, user=None): +def _get_socketname(basedir, runtime_dir, legacy=True, user=None): """Get a socketname to use.""" if user is None: user = getpass.getuser() - parts = ['qutebrowser', user] - if basedir is not None: + + if basedir is None: + basedir_md5 = None + else: md5 = hashlib.md5(basedir.encode('utf-8')) - parts.append(md5.hexdigest()) - return '-'.join(parts) + basedir_md5 = md5.hexdigest() + + if legacy or os.name == 'nt': + parts = ['qutebrowser', user] + if basedir_md5 is not None: + parts.append(basedir_md5) + return '-'.join(parts) + else: + parts = ['qutebrowser-ipc'] + if basedir_md5 is not None: + parts.append(basedir_md5) + return os.path.join(runtime_dir, '-'.join(parts)) + class Error(Exception): @@ -374,14 +387,14 @@ def send_or_listen(args): The IPCServer instance if no running instance was detected. None if an instance was running and received our request. """ - socketname = _get_socketname(args.basedir) + socketname = _get_socketname(args.basedir, standarddir.runtime()) try: try: sent = send_to_running_instance(socketname, args.command) if sent: return None log.init.debug("Starting IPC server...") - server = IPCServer(_get_socketname(args.basedir)) + server = IPCServer(socketname) server.listen() objreg.register('ipc-server', server) return server diff --git a/tests/unit/misc/test_ipc.py b/tests/unit/misc/test_ipc.py index e1c79fc03..841003b4a 100644 --- a/tests/unit/misc/test_ipc.py +++ b/tests/unit/misc/test_ipc.py @@ -70,6 +70,12 @@ def qlocalsocket(qapp): socket.waitForDisconnected(1000) +@pytest.fixture(autouse=True) +def fake_runtime_dir(monkeypatch, tmpdir): + monkeypatch.setenv('XDG_RUNTIME_DIR', str(tmpdir)) + return str(tmpdir) + + class FakeSocket(QObject): """A stub for a QLocalSocket. @@ -159,16 +165,21 @@ def test_getpass_getuser(): assert getpass.getuser() -@pytest.mark.parametrize('username, basedir, expected', [ - ('florian', None, 'qutebrowser-florian'), - ('florian', '/x', 'qutebrowser-florian-cc8755609ad61864910f145119713de9'), +@pytest.mark.parametrize('username, basedir, legacy, expected', [ + ('florian', None, True, 'qutebrowser-florian'), + ('florian', '/x', True, + 'qutebrowser-florian-cc8755609ad61864910f145119713de9'), + (None, None, True, 'qutebrowser-{}'.format(getpass.getuser())), + + ('florian', None, False, '/runtimedir/qutebrowser-ipc'), + ('florian', '/x', False, + '/runtimedir/qutebrowser-ipc-cc8755609ad61864910f145119713de9'), + (None, None, False, '/runtimedir/qutebrowser-ipc'), ]) -def test_get_socketname(username, basedir, expected): - assert ipc._get_socketname(basedir, user=username) == expected - - -def test_get_socketname_no_user(): - assert ipc._get_socketname(None).startswith('qutebrowser-') +def test_get_socketname(username, basedir, legacy, expected): + socketname = ipc._get_socketname(basedir, '/runtimedir', legacy=legacy, + user=username) + assert socketname == expected class TestExceptions: @@ -622,3 +633,15 @@ class TestSendOrListen: 'string (error 4)', ] assert msgs[-5:] == error_msgs + + +def test_long_username(fake_runtime_dir): + """See https://github.com/The-Compiler/qutebrowser/issues/888.""" + name = ipc._get_socketname(basedir='/foo', + runtime_dir=fake_runtime_dir, + user='alexandercogneau') + server = ipc.IPCServer(name) + try: + server.listen() + finally: + server.shutdown()