Skip to content

Commit 0089073

Browse files
worryg0djoao-r-reis
authored andcommitted
Prevent setting a compression flag in a frame header when native proto v5 is being used
Previously, during frame construction, the driver was setting the frame compression flag for each frame if a compressor is set in the ClusterConfig. However, for the Native Protocol 5 version the compression flag is deprecated. While Cassandra 4.0 just ignores this flag, some other third-party applications that rely on v5 proto could experience errors as the body of the frame is not actually compressed. Now it adds the compression flag only if the compressor is set and proto version < 5. Patch by Bohdan Siryk; Reviewed by João Reis for CASSGO-98
1 parent 0326fae commit 0089073

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616

1717
- Prevent panic with queries during session init (CASSGO-92)
1818
- Return correct values from RowData (CASSGO-95)
19+
- Prevent setting a compression flag in a frame header when native proto v5 is being used (CASSGO-98)
1920

2021
## [2.0.0]
2122

frame.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ func newFramer(compressor Compressor, version byte, r *RegisteredTypes) *framer
393393
types: r,
394394
}
395395
var flags byte
396-
if compressor != nil {
396+
if compressor != nil && version < protoVersion5 {
397397
flags |= flagCompress
398398
}
399399

frame_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import (
3434
"reflect"
3535
"testing"
3636

37+
"github.com/apache/cassandra-gocql-driver/v2/lz4"
38+
"github.com/apache/cassandra-gocql-driver/v2/snappy"
3739
"github.com/stretchr/testify/assert"
3840
"github.com/stretchr/testify/require"
3941
)
@@ -836,3 +838,58 @@ func BenchmarkFramerReadCol_Set(b *testing.B) {
836838
_ = framer.readCol(&col, nil, true, "", "")
837839
}
838840
}
841+
842+
func Test_newFrame_compressionFlag(t *testing.T) {
843+
tests := []struct {
844+
name string
845+
protoVersion protoVersion
846+
compressor Compressor
847+
expectedFlags byte
848+
}{
849+
{
850+
name: "proto3-nil-compressor",
851+
protoVersion: protoVersion3,
852+
compressor: nil,
853+
expectedFlags: 0, // no flags
854+
},
855+
{
856+
name: "proto3-snappy-compressor",
857+
protoVersion: protoVersion3,
858+
compressor: snappy.SnappyCompressor{},
859+
expectedFlags: 0b1, // compressions is enabled
860+
},
861+
{
862+
name: "proto4-nil-compressor",
863+
protoVersion: protoVersion4,
864+
compressor: nil,
865+
expectedFlags: 0,
866+
},
867+
{
868+
name: "proto4-snappy-compressor",
869+
protoVersion: protoVersion4,
870+
compressor: snappy.SnappyCompressor{},
871+
expectedFlags: 0b1,
872+
},
873+
{
874+
name: "proto5-nil-compressor",
875+
protoVersion: protoVersion5,
876+
compressor: nil,
877+
expectedFlags: 0,
878+
},
879+
{
880+
// In protocol v5 compression happens on the segment level (v5 new frame format). The body of the frame (envelope)
881+
// is not compressed, so we don't have to set compression flag in the frame header
882+
name: "proto5-lz4-compressor-no-compression-flag",
883+
protoVersion: protoVersion5,
884+
compressor: lz4.LZ4Compressor{},
885+
expectedFlags: 0,
886+
},
887+
}
888+
889+
for _, test := range tests {
890+
t.Run(test.name, func(t *testing.T) {
891+
f := newFramer(test.compressor, byte(test.protoVersion), GlobalTypes)
892+
require.Equal(t, test.expectedFlags, f.flags)
893+
})
894+
}
895+
}

0 commit comments

Comments
 (0)