aboutsummaryrefslogtreecommitdiff
path: root/syncapi/sync/request.go
diff options
context:
space:
mode:
Diffstat (limited to 'syncapi/sync/request.go')
-rw-r--r--syncapi/sync/request.go44
1 files changed, 36 insertions, 8 deletions
diff --git a/syncapi/sync/request.go b/syncapi/sync/request.go
index 35a15f6f..a5d2f60f 100644
--- a/syncapi/sync/request.go
+++ b/syncapi/sync/request.go
@@ -16,8 +16,10 @@ package sync
import (
"context"
+ "errors"
"net/http"
"strconv"
+ "strings"
"time"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
@@ -36,7 +38,7 @@ type syncRequest struct {
device authtypes.Device
limit int
timeout time.Duration
- since *types.StreamPosition // nil means that no since token was supplied
+ since *types.SyncPosition // nil means that no since token was supplied
wantFullState bool
log *log.Entry
}
@@ -73,15 +75,41 @@ func getTimeout(timeoutMS string) time.Duration {
}
// getSyncStreamPosition tries to parse a 'since' token taken from the API to a
-// stream position. If the string is empty then (nil, nil) is returned.
-func getSyncStreamPosition(since string) (*types.StreamPosition, error) {
+// types.SyncPosition. If the string is empty then (nil, nil) is returned.
+// There are two forms of tokens: The full length form containing all PDU and EDU
+// positions separated by "_", and the short form containing only the PDU
+// position. Short form can be used for, e.g., `prev_batch` tokens.
+func getSyncStreamPosition(since string) (*types.SyncPosition, error) {
if since == "" {
return nil, nil
}
- i, err := strconv.Atoi(since)
- if err != nil {
- return nil, err
+
+ posStrings := strings.Split(since, "_")
+ if len(posStrings) != 2 && len(posStrings) != 1 {
+ // A token can either be full length or short (PDU-only).
+ return nil, errors.New("malformed batch token")
+ }
+
+ positions := make([]int64, len(posStrings))
+ for i, posString := range posStrings {
+ pos, err := strconv.ParseInt(posString, 10, 64)
+ if err != nil {
+ return nil, err
+ }
+ positions[i] = pos
+ }
+
+ if len(positions) == 2 {
+ // Full length token; construct SyncPosition with every entry in
+ // `positions`. These entries must have the same order with the fields
+ // in struct SyncPosition, so we disable the govet check below.
+ return &types.SyncPosition{ //nolint:govet
+ positions[0], positions[1],
+ }, nil
+ } else {
+ // Token with PDU position only
+ return &types.SyncPosition{
+ PDUPosition: positions[0],
+ }, nil
}
- token := types.StreamPosition(i)
- return &token, nil
}