Closed bmeh closed 5 years ago
the values are used here, thus changing to struct{}{}
would break this: https://github.com/lrstanley/girc/blob/102f17f86306c2152a8c6188f9bb8b0e7288de31/cap.go#L103-L123
This is actually odd, I changed everything to struct{}
and struct{}{}
and modified the snippet you posted, albeit I left parseCap()
alone. It compiled and the tests were successful. I even used it to connect to a server through SASL (PLAIN), and it says it has the proper capabilities, but it says it doesn't have capability sasl
through c.HasCapability
, nor with mine or the original version. Yet the test cap_test
(where you use possibleCapList["sasl"]
instead though) passes, both with your version and mine.
Although I figured the reason you use []string
is that a capability can be in the form of sasl=PLAIN,EXTERNAL
, and you need to store both PLAIN
, and EXTERNAL
, but then why does all tests pass, and seemingly have identical results after I make those modifications? Everything seems to work correctly.
Loosely-related: is it possible right now to get PLAIN
and EXTERNAL
? Is it exposed? c.HasCapability
returns only a bool
, but what if I want to know the arguments of said capabilities? Should c.HasCapability
return (bool, []string)
perhaps? Worth noting again that c.HasCapability("sasl")
returns false, so we probably wouldn't be able to get PLAIN
and EXTERNAL
if it doesn't even find the capability sasl
. Maybe this part needs a complete rewrite or something. I might get into it later, unless you decide to do so, but I have to finish something first that relies on this library, and I don't need to check for the capability sasl
. :P
c.HasCapability("sasl")
works for me without issue, both on servers that don't provide any params (so it's assumed to be PLAIN
), and servers that provide PLAIN,EXTERNAL
. Did you verify the SASL connection was a success? Can you provide the server you used to test this on? This is what I used (can also test with testnet.oragono.io
).
package main
import (
"log"
"os"
"github.com/nmeum/girc"
)
func main() {
client := girc.New(girc.Config{
Server: "irc.byteirc.org",
Port: 6667,
Nick: "girc-test1",
User: "girc",
Debug: os.Stdout,
SASL: &girc.SASLPlain{User: "*truncated*", Pass: "*truncated*"},
})
client.Handlers.AddBg(girc.CONNECTED, func(c *girc.Client, e girc.Event) {
log.Printlny(c.HasCapability("sasl"))
})
if err := client.Connect(); err != nil {
log.Fatal(err)
}
}
As for HasCapability
, this is not the capabilities of the server, rather the capabilities that were successful between the client and server. Unfortunately, the IRCv3 spec does not specify the successful params back in the ACK
response if the client happens to acknowledge one of the sasl mechanisms. So, the only way that HasCapability
could return the specific ones that were acknowledged, is if the writing method appends that. That would have to be manually implemented for each IRCv3 extension which has parameters (which isn't really worth the effort or complexity), and would also break if the user decides to acknowledge things outside of the internal sasl ack in girc.
As for replacing []string
with struct{}
/struct{}{}
/etc, it's a non-issue. The memory consumption doesn't matter since it's only used once maybe twice, in a very small scope. In addition, changing it would make the code more complex (we have to compare the possibleCap
list against the SupportedCaps
, why spend the time to try and differentiate struct{}
vs []string
when you can just compare the two). Lastly, this method supports future extensions of the IRCv3 spec, as future extensions, we may only support specific params, and this will take advantage of that. It's not really used right now, as only one entry of the spec really uses params.
Ah, I just added:
if c.HasCapability("sasl") {
log.Println("Has capability 'sasl'")
} else {
log.Println("Does not have capability 'sasl'")
}
to my own code and it seems to work, so I am not entirely sure what the issue could have been. I did indeed check for RPL_SASLSUCCESS
, and despite that, c.HasCapability("sasl")
didn't work. It might have been my fault though, I have several different versions scattered around my filesystem, so it's possible that I was running a version without SASL enabled (but then why did I get SASL authentication succeeded
?). Sorry about that. Sleep deprivation at its finest. :D
checking right after RPL_SASLSUCCESS may be a timing issue, since the client doesn't consider SASL fully successful until the CAP transaction is complete and shows SASL in the ACK list iirc (on my phone atm). I usually wait for the custom CONNECTED event, as generally at that point the handshaking and other connection related state changes are complete.
---- On Wed, 05 Sep 2018 22:14:05 -0500 notifications@github.com wrote ----
Ah, I just added:
if c.HasCapability("sasl") { log.Println("Has capability 'sasl'") } else { log.Println("Does not have capability 'sasl'") } to my own code and it seems to work, so I am not entirely sure what the issue could have been. I did indeed check for RPL_SASLSUCCESS, and despite that, c.HasCapability("sasl") didn't work. It might have been my fault though, I have several different versions scattered around my filesystem, so it's possible that I was running a version without SASL enabled. Sorry about that. Sleep deprivation at its finest. :D
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub, or mute the thread.
What I meant by checking RPL_SASLSUCCESS
is that I added a handler for it which prints a message that it succeeded, and then I did an INVITE
(poor man's test case) afterwards which calls c.HasCapability("sasl")
, and it failed. I cannot reproduce this now anymore, so I am not exactly sure what caused this issue. It all seems to work just fine now using my latest code. I will give a detailed report and dig deeper if I run into this issue.
It might have been that I used my friend's server who ran the same version of oragono
, but with a different configuration. I remember not being able to type NICK <account>
in case the nick was registered (hence "account"), which was odd because according to oragono
's documentations, the account name has nothing to do with the nick. Sadly I cannot reproduce this either, I will have to ask my friend to set his server up which: 1) doesn't append nicknames in responses, causing more off-by-one issues, 2) requires SASL before sending the raw command NICK <name>
where name
is an account. It works fine with my configuration, so I really have to ask him for his. :D
Edit: I did mention some more details in the other opened issue (https://github.com/lrstanley/girc/issues/19?ts=2#issuecomment-419084095) regarding those peculiar behaviors.
I have stumbled upon the code here, where you are using
string
(as inmap[string][]string
) andnil
, instead ofstruct{}
andstruct{}{}
. From a quick glance I cannot see you using the value anywhere, and usingstruct{}
would communicate this intent better, therefore making the codebase slightly cleaner, and additionally it would consume less memory, but this memory consumption is negligible either way.From:
to:
You may also like to compare the assembly output: https://go.godbolt.org/z/4IMjlE