summaryrefslogtreecommitdiff
path: root/internal/server
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-10 23:02:37 +0300
committerPaul Buetow <paul@buetow.org>2026-04-10 23:02:37 +0300
commit5b8deb6658b06625f50c35a07c507e02a0bbe074 (patch)
treea83cd2316a9667e7384d4019a3f127112e9f28c7 /internal/server
parentc6629d2a35c744c3a605c725b40f21c6656a2fd8 (diff)
task 80: fix protocol compatibility parsing
Diffstat (limited to 'internal/server')
-rw-r--r--internal/server/handlers/protocol_codec.go23
-rw-r--r--internal/server/handlers/protocol_codec_test.go32
2 files changed, 51 insertions, 4 deletions
diff --git a/internal/server/handlers/protocol_codec.go b/internal/server/handlers/protocol_codec.go
index 192cc81..58c78c0 100644
--- a/internal/server/handlers/protocol_codec.go
+++ b/internal/server/handlers/protocol_codec.go
@@ -29,16 +29,16 @@ func (c protocolCodec) handleProtocolVersion(args []string) ([]string, int, stri
}
if args[1] != protocol.ProtocolCompat {
- clientCompat, _ := strconv.Atoi(args[1])
- serverCompat, _ := strconv.Atoi(protocol.ProtocolCompat)
- if clientCompat <= 3 {
+ clientMajor, clientMinor := parseProtocolCompat(args[1])
+ serverMajor, serverMinor := parseProtocolCompat(protocol.ProtocolCompat)
+ if clientMajor <= 3 {
// Protocol version 3 or lower expect a newline as message separator
// One day (after 2 major versions) this exception may be removed!
add = "\n"
}
toUpdate := "client"
- if clientCompat > serverCompat {
+ if clientMajor > serverMajor || (clientMajor == serverMajor && clientMinor > serverMinor) {
toUpdate = "server"
}
err := fmt.Errorf("the DTail server protocol version '%s' does not match "+
@@ -50,6 +50,21 @@ func (c protocolCodec) handleProtocolVersion(args []string) ([]string, int, stri
return args[2:], argc - 2, add, nil
}
+func parseProtocolCompat(version string) (int, int) {
+ major := 0
+ minor := 0
+
+ parts := strings.SplitN(version, ".", 2)
+ if len(parts) > 0 {
+ major, _ = strconv.Atoi(parts[0])
+ }
+ if len(parts) == 2 {
+ minor, _ = strconv.Atoi(parts[1])
+ }
+
+ return major, minor
+}
+
func (c protocolCodec) handleBase64(args []string, argc int) ([]string, int, error) {
err := errors.New("unable to decode client message, DTail server and client " +
"versions may not be compatible")
diff --git a/internal/server/handlers/protocol_codec_test.go b/internal/server/handlers/protocol_codec_test.go
new file mode 100644
index 0000000..a182d18
--- /dev/null
+++ b/internal/server/handlers/protocol_codec_test.go
@@ -0,0 +1,32 @@
+package handlers
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/mimecast/dtail/internal/protocol"
+)
+
+func TestHandleProtocolVersionUsesSemanticCompatComparison(t *testing.T) {
+ codec := newProtocolCodec(nil)
+
+ args, argc, add, err := codec.handleProtocolVersion([]string{"protocol", "4", "tail", "payload"})
+ if err == nil {
+ t.Fatal("expected protocol mismatch error")
+ }
+ if argc != 4 {
+ t.Fatalf("unexpected argc: got %d want 4", argc)
+ }
+ if len(args) != 4 || args[0] != "protocol" || args[1] != "4" {
+ t.Fatalf("unexpected args returned: %#v", args)
+ }
+ if add != "" {
+ t.Fatalf("unexpected message separator: %q", add)
+ }
+ if !strings.Contains(err.Error(), "please update DTail client") {
+ t.Fatalf("expected client update guidance, got %q", err)
+ }
+ if !strings.Contains(err.Error(), protocol.ProtocolCompat) {
+ t.Fatalf("expected error to mention server protocol version, got %q", err)
+ }
+}