mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-11 20:52:42 +01:00
Split 'CAP REQ' commands to not exceed 512 bytes.
This commit is contained in:
parent
0014b206ad
commit
9268356e97
@ -32,6 +32,7 @@ import copy
|
||||
import time
|
||||
import random
|
||||
import base64
|
||||
import textwrap
|
||||
import collections
|
||||
|
||||
try:
|
||||
@ -1300,19 +1301,24 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
self._addCapabilities(msg.args[3])
|
||||
elif len(msg.args) == 3: # End of LS
|
||||
self._addCapabilities(msg.args[2])
|
||||
common_supported_capabilities = set(self.state.capabilities_ls) & \
|
||||
self.REQUEST_CAPABILITIES
|
||||
|
||||
if 'sasl' in self.state.capabilities_ls:
|
||||
s = self.state.capabilities_ls['sasl']
|
||||
if s is not None:
|
||||
self.filterSaslMechanisms(set(s.split(',')))
|
||||
|
||||
# Normally at this point, self.state.capabilities_ack should be
|
||||
# empty; but let's just make sure we're not requesting the same
|
||||
# caps twice for no reason.
|
||||
new_caps = (
|
||||
set(self.state.capabilities_ls) &
|
||||
self.REQUEST_CAPABILITIES -
|
||||
self.state.capabilities_ack)
|
||||
# NOTE: Capabilities are requested in alphabetic order, because
|
||||
# sets are unordered, and their "order" is nondeterministic.
|
||||
# This is needed for the tests.
|
||||
if common_supported_capabilities:
|
||||
caps = ' '.join(sorted(common_supported_capabilities))
|
||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP',
|
||||
args=('REQ', caps)))
|
||||
if new_caps:
|
||||
self._requestCaps(new_caps)
|
||||
else:
|
||||
self.endCapabilityNegociation()
|
||||
else:
|
||||
@ -1353,9 +1359,15 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
|
||||
self.REQUEST_CAPABILITIES -
|
||||
self.state.capabilities_ack)
|
||||
if common_supported_unrequested_capabilities:
|
||||
caps = ' '.join(sorted(common_supported_unrequested_capabilities))
|
||||
self._requestCaps(common_supported_unrequested_capabilities)
|
||||
|
||||
def _requestCaps(self, caps):
|
||||
caps = ' '.join(sorted(caps))
|
||||
# textwrap works here because in ASCII, all chars are 1 bytes:
|
||||
cap_lines = textwrap.wrap(caps, MAX_LINE_SIZE-len('CAP REQ :'))
|
||||
for cap_line in cap_lines:
|
||||
self.sendMsg(ircmsgs.IrcMsg(command='CAP',
|
||||
args=('REQ', caps)))
|
||||
args=('REQ', cap_line)))
|
||||
|
||||
def monitor(self, targets):
|
||||
"""Increment a counter of how many callbacks monitor each target;
|
||||
|
@ -379,6 +379,37 @@ class IrcStateTestCase(SupyTestCase):
|
||||
st = irclib.IrcState()
|
||||
self.assert_(st.addMsg(self.irc, ircmsgs.IrcMsg('MODE foo +i')) or 1)
|
||||
|
||||
class IrcCapsTestCase(SupyTestCase):
|
||||
def testReqLineLength(self):
|
||||
self.irc = irclib.Irc('test')
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||
self.failUnless(m.args == ('LS', '302'), 'Expected CAP LS 302, got %r.' % m)
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'NICK', 'Expected NICK, got %r.' % m)
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'USER', 'Expected USER, got %r.' % m)
|
||||
|
||||
self.irc.REQUEST_CAPABILITIES = set(['a'*400, 'b'*400])
|
||||
caps = ' '.join(self.irc.REQUEST_CAPABILITIES)
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||
args=('*', 'LS', '*', 'a'*400)))
|
||||
self.irc.feedMsg(ircmsgs.IrcMsg(command='CAP',
|
||||
args=('*', 'LS', 'b'*400)))
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||
self.assertEqual(m.args[0], 'REQ', m)
|
||||
self.assertEqual(m.args[1], 'a'*400)
|
||||
|
||||
m = self.irc.takeMsg()
|
||||
self.failUnless(m.command == 'CAP', 'Expected CAP, got %r.' % m)
|
||||
self.assertEqual(m.args[0], 'REQ', m)
|
||||
self.assertEqual(m.args[1], 'b'*400)
|
||||
|
||||
class IrcTestCase(SupyTestCase):
|
||||
def setUp(self):
|
||||
self.irc = irclib.Irc('test')
|
||||
|
Loading…
Reference in New Issue
Block a user