summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
156f88b)
When servers implement CAP LS but do not offer any capabilities, end
negotiation and continue connecting as usual.
Modify processIrcEventCap to allow for commands with two parameters.
CAP LS and CAP LIST can have empty replies to signify no
capabilities are available/active.
Add a dedicated 'endCapNegotiation' function to avoid code
duplication.
Fixes repeated connection timeouts for IRCv3-compliant servers that
don't have any capabilities to offer.
void CoreNetwork::beginCapNegotiation()
{
// Don't begin negotiation if no capabilities are queued to request
void CoreNetwork::beginCapNegotiation()
{
// Don't begin negotiation if no capabilities are queued to request
- if (!capNegotiationInProgress())
+ if (!capNegotiationInProgress()) {
+ // If the server doesn't have any capabilities, but supports CAP LS, continue on with the
+ // normal connection.
+ displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("No capabilities available"));
+ endCapNegotiation();
_capNegotiationActive = true;
displayMsg(Message::Server, BufferInfo::StatusBuffer, "",
_capNegotiationActive = true;
displayMsg(Message::Server, BufferInfo::StatusBuffer, "",
_capNegotiationActive = false;
}
_capNegotiationActive = false;
}
- // If nick registration is already complete, CAP END is not required
- if (!_capInitialNegotiationEnded) {
- putRawLine(serverEncode(QString("CAP END")));
- _capInitialNegotiationEnded = true;
- }
+ endCapNegotiation();
+ }
+}
+
+void CoreNetwork::endCapNegotiation()
+{
+ // If nick registration is already complete, CAP END is not required
+ if (!_capInitialNegotiationEnded) {
+ putRawLine(serverEncode(QString("CAP END")));
+ _capInitialNegotiationEnded = true;
*/
void beginCapNegotiation();
*/
void beginCapNegotiation();
+ /**
+ * Ends capability negotiation.
+ *
+ * This won't have effect if other CAP commands are in the command queue before calling this
+ * command. It should only be called when capability negotiation is complete.
+ */
+ void endCapNegotiation();
+
/**
* List of capabilities requiring further core<->server messages to configure.
*
/**
* List of capabilities requiring further core<->server messages to configure.
*
// Handle capability negotiation
// See: http://ircv3.net/specs/core/capability-negotiation-3.2.html
// And: http://ircv3.net/specs/core/capability-negotiation-3.1.html
// Handle capability negotiation
// See: http://ircv3.net/specs/core/capability-negotiation-3.2.html
// And: http://ircv3.net/specs/core/capability-negotiation-3.1.html
- if (e->params().count() >= 3) {
+
+ // All commands require at least 2 parameters
+ if (!checkParamCount(e, 2))
+ return;
+
+ if (e->params().count() >= 2) {
CoreNetwork *coreNet = coreNetwork(e);
QString capCommand = e->params().at(1).trimmed().toUpper();
if (capCommand == "LS" || capCommand == "NEW") {
CoreNetwork *coreNet = coreNetwork(e);
QString capCommand = e->params().at(1).trimmed().toUpper();
if (capCommand == "LS" || capCommand == "NEW") {
} else {
// Single line reply
capListFinished = true;
} else {
// Single line reply
capListFinished = true;
- availableCaps = e->params().at(2).split(' ');
+ if (e->params().count() >= 3) {
+ // Some capabilities are specified, add them
+ availableCaps = e->params().at(2).split(' ');
+ } else {
+ // No capabilities available, add an empty list
+ availableCaps = QStringList();
+ }
}
// Sort capabilities before requesting for consistency among networks. This may avoid
// unexpected cases when some networks offer capabilities in a different order than
}
// Sort capabilities before requesting for consistency among networks. This may avoid
// unexpected cases when some networks offer capabilities in a different order than
if (capListFinished)
coreNet->beginCapNegotiation();
} else if (capCommand == "ACK") {
if (capListFinished)
coreNet->beginCapNegotiation();
} else if (capCommand == "ACK") {
+ // CAP ACK requires at least 3 parameters (no empty response allowed)
+ if (!checkParamCount(e, 3))
+ return;
+
// Server: CAP * ACK :multi-prefix sasl
// Got the capability we want, handle as needed.
// As only one capability is requested at a time, no need to split
// Server: CAP * ACK :multi-prefix sasl
// Got the capability we want, handle as needed.
// As only one capability is requested at a time, no need to split
coreNet->sendNextCap();
}
} else if (capCommand == "NAK" || capCommand == "DEL") {
coreNet->sendNextCap();
}
} else if (capCommand == "NAK" || capCommand == "DEL") {
+ // CAP NAK/DEL require at least 3 parameters (no empty response allowed)
+ if (!checkParamCount(e, 3))
+ return;
+
// Either something went wrong with this capability, or it is no longer supported
// > For CAP NAK
// Server: CAP * NAK :multi-prefix sasl
// Either something went wrong with this capability, or it is no longer supported
// > For CAP NAK
// Server: CAP * NAK :multi-prefix sasl