diff --git a/pyodide/index.html b/pyodide/index.html
index 22dcafc55..7f1f0da72 100644
--- a/pyodide/index.html
+++ b/pyodide/index.html
@@ -23,7 +23,14 @@
# Inject arguments to pretend it's called from the CLI
import sys
- sys.argv = ['supybot', '--allow-root', '--single-loop', '--disable-multiprocessing', 'limnoria.conf']
+ sys.argv = [
+ 'supybot',
+ '--allow-root',
+ '--single-loop',
+ '--disable-multiprocessing',
+ '--disable-threading',
+ 'limnoria.conf'
+ ]
# Initialize the bot
import supybot._main
diff --git a/pyodide/limnoria.conf b/pyodide/limnoria.conf
index f9c948ab8..5f9f295e2 100644
--- a/pyodide/limnoria.conf
+++ b/pyodide/limnoria.conf
@@ -3,7 +3,7 @@ supybot.networks.testnet.servers: [fdfe:4421:f18d:fe24:d51c:3fb4:b255:4f09]:8097
supybot.networks.testnet.channels: #limnoria-bots
supybot.reply.whenAddressedBy.nick: True
supybot.drivers.module: PyodideWebsocket
-supybot.log.stdout.level: DEBUG
+supybot.log.stdout.level: INFO
supybot.plugins: Debug Seen Format Status Unix Math Config Admin Anonymous Plugin MessageParser Network BadWords Chanreg AutoMode Aka Channel Sigyn Utilities Services Factoids Owner User ChannelStats PluginDownloader RSS Web Misc
supybot.plugins.Admin: True
diff --git a/pyodide/serve.py b/pyodide/serve.py
index 3624c6a2c..672bd794b 100644
--- a/pyodide/serve.py
+++ b/pyodide/serve.py
@@ -29,6 +29,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
self.wfile.write(fd.read())
elif self.path == '/limnoria.conf':
self.send_response(200)
+ self.send_header('Content-Type', 'text/plain')
with open(CONF_PATH, 'rb') as fd:
self.wfile.write(fd.read())
elif self.path == '/favicon.ico':
diff --git a/scripts/supybot-test b/scripts/supybot-test
index dcf582967..8cd0c4bda 100644
--- a/scripts/supybot-test
+++ b/scripts/supybot-test
@@ -163,6 +163,7 @@ if __name__ == '__main__':
(options, args) = parser.parse_args()
world.disableMultiprocessing = options.disableMultiprocessing
+ world.disableThreading = False
# This must go before checking for args, of course.
if options.excludePlugins:
diff --git a/src/_main.py b/src/_main.py
index 4fea96cd2..d204f8eeb 100644
--- a/src/_main.py
+++ b/src/_main.py
@@ -171,6 +171,10 @@ def main():
dest='disableMultiprocessing',
help='Disables multiprocessing stuff. May lead to '
'vulnerabilities.')
+ parser.add_option('', '--disable-threading', action='store_true',
+ dest='disableThreading',
+ help='Disables multiprocessing stuff. May lead to '
+ 'inefficiencies and denial of service.')
parser.add_option('', '--single-loop', action='store_true',
dest='singleLoop',
help='Do not use this unless you understand what it is.')
@@ -325,6 +329,7 @@ def main():
conf.allowDefaultOwner = options.allowDefaultOwner
world.disableMultiprocessing = options.disableMultiprocessing
+ world.disableThreading = options.disableThreading
if not os.path.exists(conf.supybot.directories.log()):
os.mkdir(conf.supybot.directories.log())
diff --git a/src/callbacks.py b/src/callbacks.py
index 1d1a620c8..e94eed9d7 100644
--- a/src/callbacks.py
+++ b/src/callbacks.py
@@ -765,6 +765,10 @@ class NestedCommandsIrcProxy(ReplyIrcProxy):
if hasattr(cb, 'invalidCommand'):
cbs.append(cb)
threaded = threaded or cb.threaded
+
+ if world.disableThreading:
+ threaded = False
+
def callInvalidCommands():
self.repliedTo = False
for cb in cbs:
diff --git a/src/world.py b/src/world.py
index b00d112d9..3951c1c83 100644
--- a/src/world.py
+++ b/src/world.py
@@ -63,6 +63,12 @@ class SupyThread(threading.Thread, object):
super(SupyThread, self).__init__(*args, **kwargs)
log.debug('Spawning thread %q.', self.getName())
+ def start(self):
+ if disableThreading:
+ self.run()
+ else:
+ super().start()
+
processesSpawned = 1 # Starts at one for the initial process.
class SupyProcess(multiprocessing.Process):
def __init__(self, *args, **kwargs):