restore simplified Line interface

This commit is contained in:
Shivaram Lingamneni 2019-03-03 15:11:50 -05:00
parent 5853469061
commit 74150f6eaf
2 changed files with 39 additions and 31 deletions

@ -276,24 +276,36 @@ func MakeMessage(tags map[string]string, prefix string, command string, params .
}
// Line returns a sendable line created from an IrcMessage.
// fromClient controls whether the server-side or client-side tag length limit
// is enforced. If truncateLen is nonzero, it is the length at which the
// non-tag portion of the message is truncated.
func (ircmsg *IrcMessage) Line(fromClient bool, truncateLen int) (string, error) {
bytes, err := ircmsg.line(fromClient, truncateLen)
return string(bytes), err
func (ircmsg *IrcMessage) Line() (result string, err error) {
bytes, err := ircmsg.line(0, 0, 0, 0)
if err == nil {
result = string(bytes)
}
return
}
// LineBytes returns a sendable line, as a []byte, created from an IrcMessage.
// LineBytesStrict returns a sendable line, as a []byte, created from an IrcMessage.
// fromClient controls whether the server-side or client-side tag length limit
// is enforced. If truncateLen is nonzero, it is the length at which the
// non-tag portion of the message is truncated.
func (ircmsg *IrcMessage) LineBytes(fromClient bool, truncateLen int) ([]byte, error) {
return ircmsg.line(fromClient, truncateLen)
func (ircmsg *IrcMessage) LineBytesStrict(fromClient bool, truncateLen int) ([]byte, error) {
var tagLimit, clientOnlyTagDataLimit, serverAddedTagDataLimit int
if fromClient {
// enforce client max tags:
// <client_max> (4096) :: '@' <tag_data 4094> ' '
tagLimit = MaxlenTagsFromClient
} else {
// on the server side, enforce separate client-only and server-added tag budgets:
// "Servers MUST NOT add tag data exceeding 4094 bytes to messages."
// <combined_max> (8191) :: '@' <tag_data 4094> ';' <tag_data 4094> ' '
clientOnlyTagDataLimit = MaxlenClientTagData
serverAddedTagDataLimit = MaxlenServerTagData
}
return ircmsg.line(tagLimit, clientOnlyTagDataLimit, serverAddedTagDataLimit, truncateLen)
}
// line returns a sendable line created from an IrcMessage.
func (ircmsg *IrcMessage) line(fromClient bool, truncateLen int) ([]byte, error) {
func (ircmsg *IrcMessage) line(tagLimit, clientOnlyTagDataLimit, serverAddedTagDataLimit, truncateLen int) ([]byte, error) {
if len(ircmsg.Command) < 1 {
return nil, ErrorCommandMissing
}
@ -330,14 +342,10 @@ func (ircmsg *IrcMessage) line(fromClient bool, truncateLen int) ([]byte, error)
}
lenTags = buf.Len()
if fromClient && MaxlenTagsFromClient < buf.Len() {
// enforce client max tags:
// <client_max> (4096) :: '@' <tag_data 4094> ' '
if 0 < tagLimit && tagLimit < buf.Len() {
return nil, ErrorLineTooLong
} else if !fromClient && (MaxlenClientTagData < lenClientOnlyTags || MaxlenServerTagData < lenRegularTags) {
// on the server side, enforce separate client-only and server-added tag budgets:
// "Servers MUST NOT add tag data exceeding 4094 bytes to messages."
// <combined_max> (8191) :: '@' <tag_data 4094> ';' <tag_data 4094> ' '
}
if (0 < clientOnlyTagDataLimit && clientOnlyTagDataLimit < lenClientOnlyTags) || (0 < serverAddedTagDataLimit && serverAddedTagDataLimit < lenRegularTags) {
return nil, ErrorLineTooLong
}

@ -156,7 +156,7 @@ var encodelentests = []testcodewithlen{
func TestEncode(t *testing.T) {
for _, pair := range encodetests {
line, err := pair.message.Line(true, 0)
line, err := pair.message.Line()
if err != nil {
t.Error(
"For", pair.raw,
@ -173,7 +173,7 @@ func TestEncode(t *testing.T) {
}
}
for _, pair := range encodelentests {
line, err := pair.message.Line(true, pair.length)
line, err := pair.message.LineBytesStrict(true, pair.length)
if err != nil {
t.Error(
"For", pair.raw,
@ -181,7 +181,7 @@ func TestEncode(t *testing.T) {
)
}
if line != pair.raw {
if string(line) != pair.raw {
t.Error(
"For", pair.message,
"expected", pair.raw,
@ -192,7 +192,7 @@ func TestEncode(t *testing.T) {
// make sure we fail on no command
msg := MakeMessage(nil, "example.com", "", "*")
_, err := msg.Line(true, 0)
_, err := msg.LineBytesStrict(true, 0)
if err == nil {
t.Error(
"For", "Test Failure 1",
@ -203,7 +203,7 @@ func TestEncode(t *testing.T) {
// make sure we fail with params in right way
msg = MakeMessage(nil, "example.com", "TEST", "*", "t s", "", "Param after empty!")
_, err = msg.Line(true, 0)
_, err = msg.LineBytesStrict(true, 0)
if err == nil {
t.Error(
"For", "Test Failure 2",
@ -271,11 +271,11 @@ var testMessages = []IrcMessage{
func TestEncodeDecode(t *testing.T) {
for _, message := range testMessages {
encoded, err := message.Line(false, 0)
encoded, err := message.LineBytesStrict(false, 0)
if err != nil {
t.Errorf("Couldn't encode %v: %v", message, err)
}
parsed, err := ParseLineStrict(encoded, true, 0)
parsed, err := ParseLineStrict(string(encoded), true, 0)
if err != nil {
t.Errorf("Couldn't re-decode %v: %v", encoded, err)
}
@ -292,7 +292,7 @@ func TestErrorLineTooLongGeneration(t *testing.T) {
Command: "PRIVMSG",
Params: []string{"aaaaaaaaaaaaaaaaaaaaa"},
}
_, err := message.LineBytes(true, 0)
_, err := message.LineBytesStrict(true, 0)
if err != nil {
t.Error(err)
}
@ -300,7 +300,7 @@ func TestErrorLineTooLongGeneration(t *testing.T) {
for i := 0; i < 100; i += 1 {
message.SetTag(fmt.Sprintf("+client-tag-%d", i), "ok")
}
line, err := message.LineBytes(true, 0)
line, err := message.LineBytesStrict(true, 0)
if err != nil {
t.Error(err)
}
@ -312,7 +312,7 @@ func TestErrorLineTooLongGeneration(t *testing.T) {
for i := 100; i < 500; i += 1 {
message.SetTag(fmt.Sprintf("+client-tag-%d", i), "ok")
}
line, err = message.LineBytes(true, 0)
line, err = message.LineBytesStrict(true, 0)
if err != ErrorLineTooLong {
t.Error(err)
}
@ -321,7 +321,7 @@ func TestErrorLineTooLongGeneration(t *testing.T) {
for i := 0; i < 500; i += 1 {
message.SetTag(fmt.Sprintf("server-tag-%d", i), "ok")
}
line, err = message.LineBytes(true, 0)
line, err = message.LineBytesStrict(true, 0)
if err != ErrorLineTooLong {
t.Error(err)
}
@ -333,12 +333,12 @@ func TestErrorLineTooLongGeneration(t *testing.T) {
message.SetTag(fmt.Sprintf("+client-tag-%d", i), "ok")
}
// client cannot send this much tag data:
line, err = message.LineBytes(true, 0)
line, err = message.LineBytesStrict(true, 0)
if err != ErrorLineTooLong {
t.Error(err)
}
// but a server can, since the tags are split between client and server budgets:
line, err = message.LineBytes(false, 0)
line, err = message.LineBytesStrict(false, 0)
if err != nil {
t.Error(err)
}
@ -353,7 +353,7 @@ func BenchmarkGenerate(b *testing.B) {
)
b.ResetTimer()
for i := 0; i < b.N; i++ {
msg.LineBytes(false, 0)
msg.LineBytesStrict(false, 0)
}
}