diff --git a/db/active_replicator.go b/db/active_replicator.go index 527816693c..74fd209c6a 100644 --- a/db/active_replicator.go +++ b/db/active_replicator.go @@ -236,6 +236,12 @@ func connect(arc *activeReplicatorCommon, idSuffix string) (blipSender *blip.Sen return nil, nil, err } + // set active subprotocol after handshake + bsc.activeCBMobileSubprotocol, err = ParseSubprotocolString(blipContext.ActiveSubprotocol()) + if err != nil { + return nil, nil, err + } + return blipSender, bsc, nil } diff --git a/db/active_replicator_pull.go b/db/active_replicator_pull.go index c5f94c140c..b4e6611e5c 100644 --- a/db/active_replicator_pull.go +++ b/db/active_replicator_pull.go @@ -88,7 +88,7 @@ func (apr *ActivePullReplicator) _connect() error { } } - if apr.blipSyncContext.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV2 && apr.config.PurgeOnRemoval { + if apr.blipSyncContext.activeCBMobileSubprotocol <= CBMobileReplicationV2 && apr.config.PurgeOnRemoval { base.ErrorfCtx(apr.ctx, "Pull replicator ID:%s running with revocations enabled but target does not support revocations. Sync Gateway 3.0 required.", apr.config.ID) } diff --git a/db/attachment_test.go b/db/attachment_test.go index a29ccfa7f4..9439fc5af2 100644 --- a/db/attachment_test.go +++ b/db/attachment_test.go @@ -1322,22 +1322,24 @@ func TestAllowedAttachments(t *testing.T) { var tests = []struct { name string - inputBlipProtocol string + inputBlipProtocol CBMobileSubprotocolVersion inputAttVersion int }{ - {"TestAllowedAttachmentsCBMobile2AttVer1", BlipCBMobileReplicationV2, AttVersion1}, - {"TestAllowedAttachmentsCBMobile2AttVer2", BlipCBMobileReplicationV2, AttVersion2}, - {"TestAllowedAttachmentsCBMobile3AttVer1", BlipCBMobileReplicationV3, AttVersion1}, - {"TestAllowedAttachmentsCBMobile3AttVer2", BlipCBMobileReplicationV3, AttVersion2}, + {"TestAllowedAttachmentsCBMobile2AttVer1", CBMobileReplicationV2, AttVersion1}, + {"TestAllowedAttachmentsCBMobile2AttVer2", CBMobileReplicationV2, AttVersion2}, + {"TestAllowedAttachmentsCBMobile3AttVer1", CBMobileReplicationV3, AttVersion1}, + {"TestAllowedAttachmentsCBMobile3AttVer2", CBMobileReplicationV3, AttVersion2}, + {"TestAllowedAttachmentsCBMobile4AttVer2", CBMobileReplicationV4, AttVersion2}, + {"TestAllowedAttachmentsCBMobile4AttVer2", CBMobileReplicationV4, AttVersion2}, } isAllowedAttachment := func(ctx *BlipSyncContext, key string) bool { return ctx.allowedAttachment(key).counter > 0 } - requireIsAttachmentAllowedTrue := func(t *testing.T, ctx *BlipSyncContext, docID string, meta []AttachmentStorageMeta, activeSubprotocol string) { + requireIsAttachmentAllowedTrue := func(t *testing.T, ctx *BlipSyncContext, docID string, meta []AttachmentStorageMeta, activeSubprotocol CBMobileSubprotocolVersion) { docIDForAllowedAttKey := docID - if activeSubprotocol == BlipCBMobileReplicationV2 { + if activeSubprotocol <= CBMobileReplicationV2 { docIDForAllowedAttKey = "" } for _, att := range meta { @@ -1346,9 +1348,9 @@ func TestAllowedAttachments(t *testing.T) { } } - requireIsAttachmentAllowedFalse := func(t *testing.T, ctx *BlipSyncContext, docID string, meta []AttachmentStorageMeta, activeSubprotocol string) { + requireIsAttachmentAllowedFalse := func(t *testing.T, ctx *BlipSyncContext, docID string, meta []AttachmentStorageMeta, activeSubprotocol CBMobileSubprotocolVersion) { docIDForAllowedAttKey := docID - if activeSubprotocol == BlipCBMobileReplicationV2 { + if activeSubprotocol <= CBMobileReplicationV2 { docIDForAllowedAttKey = "" } for _, att := range meta { @@ -1413,9 +1415,9 @@ func TestAllowedAttachments(t *testing.T) { ctx.removeAllowedAttachments(docID1, meta, tt.inputBlipProtocol) requireIsAttachmentAllowedTrue(t, ctx, docID2, meta, tt.inputBlipProtocol) - if tt.inputBlipProtocol == BlipCBMobileReplicationV2 { + if tt.inputBlipProtocol <= CBMobileReplicationV2 { requireIsAttachmentAllowedTrue(t, ctx, docID1, meta, tt.inputBlipProtocol) - } else if tt.inputBlipProtocol == BlipCBMobileReplicationV3 { + } else if tt.inputBlipProtocol <= CBMobileReplicationV3 { requireIsAttachmentAllowedFalse(t, ctx, docID1, meta, tt.inputBlipProtocol) } @@ -1443,9 +1445,9 @@ func TestAllowedAttachments(t *testing.T) { ctx.removeAllowedAttachments(docID1, meta, tt.inputBlipProtocol) requireIsAttachmentAllowedTrue(t, ctx, docID2, meta, tt.inputBlipProtocol) - if tt.inputBlipProtocol == BlipCBMobileReplicationV2 { + if tt.inputBlipProtocol <= CBMobileReplicationV2 { requireIsAttachmentAllowedTrue(t, ctx, docID1, meta, tt.inputBlipProtocol) - } else if tt.inputBlipProtocol == BlipCBMobileReplicationV3 { + } else if tt.inputBlipProtocol <= CBMobileReplicationV3 { requireIsAttachmentAllowedFalse(t, ctx, docID1, meta, tt.inputBlipProtocol) } diff --git a/db/blip.go b/db/blip.go index e6e410e047..7d9d0722a6 100644 --- a/db/blip.go +++ b/db/blip.go @@ -19,13 +19,6 @@ import ( "github.com/couchbase/sync_gateway/base" ) -const ( - // BlipCBMobileReplicationV2 / BlipCBMobileReplicationV3 is the AppProtocolId part of the BLIP websocket - // sub protocol. One must match identically with one provided by the peer (CBLite / ISGR) - BlipCBMobileReplicationV2 = "CBMobile_2" - BlipCBMobileReplicationV3 = "CBMobile_3" -) - var ( // compressedTypes are MIME types that explicitly indicate they're compressed: compressedTypes = regexp.MustCompile(`(?i)\bg?zip\b`) @@ -44,10 +37,7 @@ var ( // NewSGBlipContext returns a go-blip context with the given ID, initialized for use in Sync Gateway. func NewSGBlipContext(ctx context.Context, id string) (bc *blip.Context, err error) { - // V3 is first here as it is the preferred communication method - // In the host case this means SGW can accept both V3 and V2 clients - // In the client case this means we prefer V3 but can fallback to V2 - return NewSGBlipContextWithProtocols(ctx, id, BlipCBMobileReplicationV3, BlipCBMobileReplicationV2) + return NewSGBlipContextWithProtocols(ctx, id, supportedSubprotocols()...) } func NewSGBlipContextWithProtocols(ctx context.Context, id string, protocol ...string) (bc *blip.Context, err error) { diff --git a/db/blip_handler.go b/db/blip_handler.go index 79a21c1c8b..74e4dc796d 100644 --- a/db/blip_handler.go +++ b/db/blip_handler.go @@ -454,7 +454,7 @@ func (bh *blipHandler) sendChanges(sender *blip.Sender, opts *sendChangesOptions // If change is a removal and we're running with protocol V3 and change change is not a tombstone // fall into 3.0 removal handling. // Changes with change.Revoked=true have already evaluated UserHasDocAccess in changes.go, don't check again. - if change.allRemoved && bh.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV3 && !change.Deleted && !change.Revoked { + if change.allRemoved && bh.activeCBMobileSubprotocol <= CBMobileReplicationV3 && !change.Deleted && !change.Revoked { // If client doesn't want removals / revocations, don't send change if !opts.revocations { continue @@ -517,7 +517,7 @@ func (bh *blipHandler) sendChanges(sender *blip.Sender, opts *sendChangesOptions func (bh *blipHandler) buildChangesRow(change *ChangeEntry, revID string) []interface{} { var changeRow []interface{} - if bh.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV3 { + if bh.activeCBMobileSubprotocol <= CBMobileReplicationV3 { deletedFlags := changesDeletedFlag(0) if change.Deleted { deletedFlags |= changesDeletedFlagDeleted @@ -688,7 +688,7 @@ func (bh *blipHandler) handleChanges(rq *blip.Message) error { } - if bh.purgeOnRemoval && bh.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV3 && + if bh.purgeOnRemoval && bh.activeCBMobileSubprotocol <= CBMobileReplicationV3 && (deletedFlags.HasFlag(changesDeletedFlagRevoked) || deletedFlags.HasFlag(changesDeletedFlagRemoved)) { err := bh.collection.Purge(bh.loggingCtx, docID) if err != nil { @@ -881,7 +881,7 @@ func (bsc *BlipSyncContext) sendRevAsDelta(sender *blip.Sender, docID, revID str func (bh *blipHandler) handleNoRev(rq *blip.Message) error { docID, revID := rq.Properties[NorevMessageId], rq.Properties[NorevMessageRev] var seqStr string - if bh.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV2 && bh.clientType == BLIPClientTypeSGR2 { + if bh.activeCBMobileSubprotocol <= CBMobileReplicationV2 && bh.clientType == BLIPClientTypeSGR2 { seqStr = rq.Properties[NorevMessageSeq] } else { seqStr = rq.Properties[NorevMessageSequence] @@ -1270,7 +1270,7 @@ func (bh *blipHandler) handleGetAttachment(rq *blip.Message) error { docID := "" attachmentAllowedKey := digest - if bh.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV3 { + if bh.activeCBMobileSubprotocol <= CBMobileReplicationV3 { docID = getAttachmentParams.docID() if docID == "" { return base.HTTPErrorf(http.StatusBadRequest, "Missing 'docID'") @@ -1283,7 +1283,7 @@ func (bh *blipHandler) handleGetAttachment(rq *blip.Message) error { return base.HTTPErrorf(http.StatusForbidden, "Attachment's doc not being synced") } - if bh.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV2 { + if bh.activeCBMobileSubprotocol <= CBMobileReplicationV2 { docID = allowedAttachment.docID } @@ -1319,7 +1319,7 @@ func (bh *blipHandler) sendGetAttachment(sender *blip.Sender, docID string, name outrq.Properties[BlipCompress] = trueProperty } - if bh.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV3 { + if bh.activeCBMobileSubprotocol <= CBMobileReplicationV3 { outrq.Properties[GetAttachmentID] = docID } @@ -1459,7 +1459,7 @@ func (bsc *BlipSyncContext) incrementSerialNumber() uint64 { return atomic.AddUint64(&bsc.handlerSerialNumber, 1) } -func (bsc *BlipSyncContext) addAllowedAttachments(docID string, attMeta []AttachmentStorageMeta, activeSubprotocol string) { +func (bsc *BlipSyncContext) addAllowedAttachments(docID string, attMeta []AttachmentStorageMeta, activeSubprotocol CBMobileSubprotocolVersion) { if len(attMeta) == 0 { return } @@ -1488,7 +1488,7 @@ func (bsc *BlipSyncContext) addAllowedAttachments(docID string, attMeta []Attach base.TracefCtx(bsc.loggingCtx, base.KeySync, "addAllowedAttachments, added: %v current set: %v", attMeta, bsc.allowedAttachments) } -func (bsc *BlipSyncContext) removeAllowedAttachments(docID string, attMeta []AttachmentStorageMeta, activeSubprotocol string) { +func (bsc *BlipSyncContext) removeAllowedAttachments(docID string, attMeta []AttachmentStorageMeta, activeSubprotocol CBMobileSubprotocolVersion) { if len(attMeta) == 0 { return } @@ -1512,8 +1512,8 @@ func (bsc *BlipSyncContext) removeAllowedAttachments(docID string, attMeta []Att base.TracefCtx(bsc.loggingCtx, base.KeySync, "removeAllowedAttachments, removed: %v current set: %v", attMeta, bsc.allowedAttachments) } -func allowedAttachmentKey(docID, digest, activeSubprotocol string) string { - if activeSubprotocol == BlipCBMobileReplicationV3 { +func allowedAttachmentKey(docID, digest string, activeCBMobileSubprotocol CBMobileSubprotocolVersion) string { + if activeCBMobileSubprotocol == CBMobileReplicationV3 { return docID + digest } return digest diff --git a/db/blip_subprotocol.go b/db/blip_subprotocol.go new file mode 100644 index 0000000000..5ff56cb89c --- /dev/null +++ b/db/blip_subprotocol.go @@ -0,0 +1,60 @@ +package db + +import ( + "fmt" + "strconv" + "strings" +) + +type CBMobileSubprotocolVersion int + +const ( + // CBMobileReplicationV2 the original subprotocol used by CBLite 2.x + CBMobileReplicationV2 CBMobileSubprotocolVersion = iota + 2 + // CBMobileReplicationV3 minor changes to support revocation and ISGR + CBMobileReplicationV3 + // CBMobileReplicationV4 switched from RevTree-based revision IDs to Version Vectors (Hybrid Logical Vector) + CBMobileReplicationV4 + + // _nextCBMobileSubprotocolVersions reserved for maxCBMobileSubprotocolVersion + _nextCBMobileSubprotocolVersions + + // minCBMobileSubprotocolVersion is the minimum supported subprotocol version by SG + minCBMobileSubprotocolVersion = CBMobileReplicationV2 + // maxCBMobileSubprotocolVersion is the maximum supported subprotocol version by SG + maxCBMobileSubprotocolVersion = _nextCBMobileSubprotocolVersions - 1 +) + +const cbMobileBLIPSubprotocolPrefix = "CBMobile_" + +// Format must match the AppProtocolId provided by the peer (CBLite / ISGR) +func (v CBMobileSubprotocolVersion) SubprotocolString() string { + return cbMobileBLIPSubprotocolPrefix + strconv.Itoa(int(v)) +} + +// ParseSubprotocolString takes a 'CBMobile_' prefixed string and returns the subprotocol version. +func ParseSubprotocolString(s string) (CBMobileSubprotocolVersion, error) { + vStr, ok := strings.CutPrefix(s, cbMobileBLIPSubprotocolPrefix) + if !ok { + return 0, fmt.Errorf("invalid subprotocol string: %q", s) + } + v, err := strconv.Atoi(vStr) + if err != nil { + return 0, fmt.Errorf("invalid subprotocol string: %q: %w", s, err) + } + if v < int(minCBMobileSubprotocolVersion) || v > int(maxCBMobileSubprotocolVersion) { + return 0, fmt.Errorf("invalid subprotocol version: %q", s) + } + return CBMobileSubprotocolVersion(v), nil +} + +// supportedSubprotocols returns a list of supported subprotocol versions, in order of most preferred first +func supportedSubprotocols() []string { + numSubprotocols := maxCBMobileSubprotocolVersion - minCBMobileSubprotocolVersion + 1 + subProtocols := make([]string, 0, numSubprotocols) + // iterate backwards so we prefer the latest protocol versions + for i := maxCBMobileSubprotocolVersion; i >= minCBMobileSubprotocolVersion; i-- { + subProtocols = append(subProtocols, i.SubprotocolString()) + } + return subProtocols +} diff --git a/db/blip_sync_context.go b/db/blip_sync_context.go index 1514c14645..841fe5d7fd 100644 --- a/db/blip_sync_context.go +++ b/db/blip_sync_context.go @@ -83,9 +83,10 @@ func NewBlipSyncContext(ctx context.Context, bc *blip.Context, db *Database, con // This connection remains open until the client closes it, and can receive any number of requests. type BlipSyncContext struct { blipContext *blip.Context - blipContextDb *Database // 'master' database instance for the replication, used as source when creating handler-specific databases - loggingCtx context.Context // logging context for connection - dbUserLock sync.RWMutex // Must be held when refreshing the db user + activeCBMobileSubprotocol CBMobileSubprotocolVersion // The active subprotocol version for this connection + blipContextDb *Database // 'master' database instance for the replication, used as source when creating handler-specific databases + loggingCtx context.Context // logging context for connection + dbUserLock sync.RWMutex // Must be held when refreshing the db user allowedAttachments map[string]AllowedAttachment allowedAttachmentsLock sync.Mutex handlerSerialNumber uint64 // Each handler within a context gets a unique serial number for logging @@ -136,6 +137,12 @@ type AllowedAttachment struct { docID string // docID, used for BlipCBMobileReplicationV2 retrieval of V2 attachments } +// SetActiveCBMobileSubprotocol returns the active subprotocol version +func (bsc *BlipSyncContext) SetActiveCBMobileSubprotocol(subprotocol string) (err error) { + bsc.activeCBMobileSubprotocol, err = ParseSubprotocolString(subprotocol) + return err +} + func (bsc *BlipSyncContext) SetClientType(clientType BLIPSyncContextClientType) { bsc.clientType = clientType } @@ -420,7 +427,7 @@ func (bsc *BlipSyncContext) sendRevisionWithProperties(sender *blip.Sender, docI // asynchronously wait for a response if we have attachment digests to verify, if we sent a delta and want to error check, or if we have a registered callback. awaitResponse := len(attMeta) > 0 || properties[RevMessageDeltaSrc] != "" || collectionCtx.sgr2PushProcessedSeqCallback != nil - activeSubprotocol := bsc.blipContext.ActiveSubprotocol() + activeSubprotocol := bsc.activeCBMobileSubprotocol if awaitResponse { // Allow client to download attachments in 'atts', but only while pulling this rev bsc.addAllowedAttachments(docID, attMeta, activeSubprotocol) @@ -437,7 +444,7 @@ func (bsc *BlipSyncContext) sendRevisionWithProperties(sender *blip.Sender, docI bsc.reportComputeStat(outrq.Message, startTime) if awaitResponse { - go func(activeSubprotocol string) { + go func(activeSubprotocol CBMobileSubprotocolVersion) { defer func() { if panicked := recover(); panicked != nil { bsc.replicationStats.NumHandlersPanicked.Add(1) @@ -568,7 +575,7 @@ func (bsc *BlipSyncContext) sendNoRev(sender *blip.Sender, docID, revID string, noRevRq.SetId(docID) noRevRq.SetRev(revID) noRevRq.SetCollection(collectionIdx) - if bsc.blipContext.ActiveSubprotocol() == BlipCBMobileReplicationV2 && bsc.clientType == BLIPClientTypeSGR2 { + if bsc.activeCBMobileSubprotocol <= CBMobileReplicationV2 && bsc.clientType == BLIPClientTypeSGR2 { noRevRq.SetSeq(seq) } else { noRevRq.SetSequence(seq) diff --git a/db/blip_test.go b/db/blip_test.go new file mode 100644 index 0000000000..969b34d565 --- /dev/null +++ b/db/blip_test.go @@ -0,0 +1,17 @@ +package db + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// TestSubprotocolString roundtrips the parse/format Subprotocol methods on the subprotocol constants. +func TestSubprotocolString(t *testing.T) { + for i := minCBMobileSubprotocolVersion; i <= maxCBMobileSubprotocolVersion; i++ { + str := i.SubprotocolString() + parsed, err := ParseSubprotocolString(str) + require.NoError(t, err) + require.Equal(t, i, parsed) + } +} diff --git a/go.mod b/go.mod index 4272f5499f..913afe93ba 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/coreos/go-oidc v2.2.1+incompatible github.com/couchbase/cbgt v1.3.8 github.com/couchbase/clog v0.1.0 - github.com/couchbase/go-blip v0.0.0-20231017145500-e4a51837754e + github.com/couchbase/go-blip v0.0.0-20231117144304-a98451269d7e github.com/couchbase/gocb/v2 v2.6.4 github.com/couchbase/gocbcore/v10 v10.2.8 github.com/couchbase/gomemcached v0.2.1 @@ -56,7 +56,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect - github.com/klauspost/compress v1.15.11 // indirect + github.com/klauspost/compress v1.17.3 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -80,5 +80,5 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - nhooyr.io/websocket v1.8.7 // indirect + nhooyr.io/websocket v1.8.10 // indirect ) diff --git a/go.sum b/go.sum index 8da9b6abd9..27a2c280b2 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,8 @@ github.com/couchbase/cbgt v1.3.8 h1:DmIHNfbuGkmNi85lcWFxeDReoame9Xz2c7LjvbMuhZs= github.com/couchbase/cbgt v1.3.8/go.mod h1:kkK2gk/2LTuw6A+a4W22m2Pcta7JHu1PiXS8sJ3ow9g= github.com/couchbase/clog v0.1.0 h1:4Kh/YHkhRjMCbdQuvRVsm39XZh4FtL1d8fAwJsHrEPY= github.com/couchbase/clog v0.1.0/go.mod h1:7tzUpEOsE+fgU81yfcjy5N1H6XtbVC8SgOz/3mCjmd4= -github.com/couchbase/go-blip v0.0.0-20231017145500-e4a51837754e h1:WWe9B68e4z1+05ASEYIp4fHAYSAUr5neJx966YOYYRk= -github.com/couchbase/go-blip v0.0.0-20231017145500-e4a51837754e/go.mod h1:nSpldGTqAhTOaDDL0Li2dSE0smqbISKagT7fIqYIRec= +github.com/couchbase/go-blip v0.0.0-20231117144304-a98451269d7e h1:aMRocs8+Maz7THb+3LHe7XZJS8VA6R3+L+iWEgfsT7k= +github.com/couchbase/go-blip v0.0.0-20231117144304-a98451269d7e/go.mod h1:Dz8Keu17/4cjF7hvKYqOjH4pRXOh1CCnzsKlBOJaoJE= github.com/couchbase/go-couchbase v0.1.1 h1:ClFXELcKj/ojyoTYbsY34QUrrYCBi/1G749sXSCkdhk= github.com/couchbase/go-couchbase v0.1.1/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A= github.com/couchbase/gocb/v2 v2.6.4 h1:o5k5JnxYkgamVL9svx+vbXc7vKF5X72tNt/qORs+L30= @@ -73,27 +73,9 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/ github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -101,7 +83,6 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -113,8 +94,6 @@ github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graphql-go/graphql v0.8.0/go.mod h1:nKiHzRM0qopJEwCITUuIsxk9PlVlwIiiI8pnJEhordQ= github.com/graphql-go/graphql v0.8.1 h1:p7/Ou/WpmulocJeEx7wjQy611rtXGQaAcXGqanuMMgc= @@ -123,24 +102,18 @@ github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1: github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60= github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= +github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -148,7 +121,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= @@ -192,10 +164,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -225,7 +193,6 @@ golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -239,14 +206,12 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -279,5 +244,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= +nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/rest/blip_api_attachment_test.go b/rest/blip_api_attachment_test.go index 15a16c2c62..962c5204e4 100644 --- a/rest/blip_api_attachment_test.go +++ b/rest/blip_api_attachment_test.go @@ -54,7 +54,7 @@ func TestBlipPushPullV2AttachmentV2Client(t *testing.T) { defer rt.Close() opts := &BlipTesterClientOpts{} - opts.SupportedBLIPProtocols = []string{db.BlipCBMobileReplicationV2} + opts.SupportedBLIPProtocols = []string{db.CBMobileReplicationV2.SubprotocolString()} btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, opts) defer btc.Close() @@ -203,7 +203,7 @@ func TestBlipProveAttachmentV2(t *testing.T) { defer rt.Close() btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, &BlipTesterClientOpts{ - SupportedBLIPProtocols: []string{db.BlipCBMobileReplicationV2}, + SupportedBLIPProtocols: []string{db.CBMobileReplicationV2.SubprotocolString()}, }) defer btc.Close() @@ -263,7 +263,7 @@ func TestBlipProveAttachmentV2Push(t *testing.T) { defer rt.Close() btc := btcRunner.NewBlipTesterClientOptsWithRT(rt, &BlipTesterClientOpts{ - SupportedBLIPProtocols: []string{db.BlipCBMobileReplicationV2}, + SupportedBLIPProtocols: []string{db.CBMobileReplicationV2.SubprotocolString()}, }) defer btc.Close() // Create two docs with the same attachment data on the client - v2 attachments intentionally result in two copies stored on the server, despite the client being able to share the data for both. diff --git a/rest/blip_api_crud_test.go b/rest/blip_api_crud_test.go index 581abbe797..8ea4509d21 100644 --- a/rest/blip_api_crud_test.go +++ b/rest/blip_api_crud_test.go @@ -1694,7 +1694,7 @@ func TestGetRemovedDoc(t *testing.T) { btSpec := BlipTesterSpec{ connectingUsername: "user1", connectingPassword: "1234", - blipProtocols: []string{db.BlipCBMobileReplicationV2}, + blipProtocols: []string{db.CBMobileReplicationV2.SubprotocolString()}, } bt, err := NewBlipTesterFromSpecWithRT(t, &btSpec, rt) require.NoError(t, err, "Unexpected error creating BlipTester") @@ -1708,7 +1708,7 @@ func TestGetRemovedDoc(t *testing.T) { connectingUsername: "user2", connectingPassword: "1234", connectingUserChannelGrants: []string{"user1"}, // so it can see user1's docs - blipProtocols: []string{db.BlipCBMobileReplicationV2}, + blipProtocols: []string{db.CBMobileReplicationV2.SubprotocolString()}, } bt2, err := NewBlipTesterFromSpecWithRT(t, &btSpec2, rt) require.NoError(t, err, "Unexpected error creating BlipTester") diff --git a/rest/blip_api_delta_sync_test.go b/rest/blip_api_delta_sync_test.go index 1bb5e7aaaa..305f4ea8a4 100644 --- a/rest/blip_api_delta_sync_test.go +++ b/rest/blip_api_delta_sync_test.go @@ -447,7 +447,7 @@ func TestBlipDeltaSyncPullRemoved(t *testing.T) { Username: "alice", Channels: []string{"public"}, ClientDeltas: true, - SupportedBLIPProtocols: []string{db.BlipCBMobileReplicationV2}, + SupportedBLIPProtocols: []string{db.CBMobileReplicationV2.SubprotocolString()}, }) defer client.Close() diff --git a/rest/blip_client_test.go b/rest/blip_client_test.go index c663a14f6a..6129f81101 100644 --- a/rest/blip_client_test.go +++ b/rest/blip_client_test.go @@ -340,7 +340,7 @@ func (btr *BlipTesterReplicator) initHandlers(btc *BlipTesterClient) { if _, found := btcr.attachments[digest]; !found { missingDigests = append(missingDigests, digest) } else { - if btr.bt.blipContext.ActiveSubprotocol() == db.BlipCBMobileReplicationV2 { + if btr.bt.activeSubprotocol == db.CBMobileReplicationV2 { // only v2 clients care about proveAttachments knownDigests = append(knownDigests, digest) } @@ -400,7 +400,7 @@ func (btr *BlipTesterReplicator) initHandlers(btc *BlipTesterClient) { outrq := blip.NewRequest() outrq.SetProfile(db.MessageGetAttachment) outrq.Properties[db.GetAttachmentDigest] = digest - if btr.bt.blipContext.ActiveSubprotocol() == db.BlipCBMobileReplicationV3 { + if btr.bt.activeSubprotocol >= db.CBMobileReplicationV3 { outrq.Properties[db.GetAttachmentID] = docID } diff --git a/rest/blip_sync.go b/rest/blip_sync.go index 1b8ba15e29..8243cd0b12 100644 --- a/rest/blip_sync.go +++ b/rest/blip_sync.go @@ -72,7 +72,14 @@ func (h *handler) handleBLIPSync() error { middleware := func(next http.Handler) http.Handler { return http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { - h.logStatus(http.StatusSwitchingProtocols, fmt.Sprintf("[%s] Upgraded to WebSocket protocol %s+%s%s", blipContext.ID, blip.WebSocketSubProtocolPrefix, blipContext.ActiveSubprotocol(), h.formattedEffectiveUserName())) + subprotocol := blipContext.ActiveSubprotocol() + h.logStatus(http.StatusSwitchingProtocols, fmt.Sprintf("[%s] Upgraded to WebSocket protocol %s+%s%s", blipContext.ID, blip.WebSocketSubProtocolPrefix, subprotocol, h.formattedEffectiveUserName())) + err := ctx.SetActiveCBMobileSubprotocol(subprotocol) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + _, _ = w.Write([]byte(err.Error())) + return + } defer base.InfofCtx(h.ctx(), base.KeyHTTP, "%s: --> BLIP+WebSocket connection closed", h.formatSerialNumber()) next.ServeHTTP(w, r) }) diff --git a/rest/utilities_testing.go b/rest/utilities_testing.go index 078284cca8..002c4026f8 100644 --- a/rest/utilities_testing.go +++ b/rest/utilities_testing.go @@ -1257,7 +1257,8 @@ type BlipTester struct { // The blip context which contains blip related state and the sender/reciever goroutines associated // with this websocket connection - blipContext *blip.Context + blipContext *blip.Context + activeSubprotocol db.CBMobileSubprotocolVersion // The blip sender that can be used for sending messages over the websocket connection sender *blip.Sender @@ -1397,7 +1398,7 @@ func createBlipTesterWithSpec(tb testing.TB, spec BlipTesterSpec, rt *RestTester // If protocols are not set use V3 as a V3 client would protocols := spec.blipProtocols if len(protocols) == 0 { - protocols = []string{db.BlipCBMobileReplicationV3} + protocols = []string{db.CBMobileReplicationV3.SubprotocolString()} } // Make BLIP/Websocket connection @@ -1430,6 +1431,11 @@ func createBlipTesterWithSpec(tb testing.TB, spec BlipTesterSpec, rt *RestTester return nil, err } + bt.activeSubprotocol, err = db.ParseSubprotocolString(bt.blipContext.ActiveSubprotocol()) + if err != nil { + tb.Fatalf("Unable to parse subprotocol string: %v", err) + } + collections := bt.restTester.getCollectionsForBLIP() if !spec.skipCollectionsInitialization && len(collections) > 0 { bt.initializeCollections(collections) @@ -1966,7 +1972,7 @@ func (bt *BlipTester) PullDocs() (docs map[string]RestDocument) { getAttachmentRequest := blip.NewRequest() getAttachmentRequest.SetProfile(db.MessageGetAttachment) getAttachmentRequest.Properties[db.GetAttachmentDigest] = attachment.Digest - if bt.blipContext.ActiveSubprotocol() == db.BlipCBMobileReplicationV3 { + if bt.activeSubprotocol >= db.CBMobileReplicationV3 { getAttachmentRequest.Properties[db.GetAttachmentID] = docId } bt.addCollectionProperty(getAttachmentRequest)