mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-12 09:23:09 -06:00
Add a very basic /initialSync implementation
This is done by coercing a full sync response into the right shape. Some notable TODOs: - Support specifying a limt - Support invites - Correctly format events - Add presence, account data, etc
This commit is contained in:
parent
bcf58fad84
commit
214d856674
|
|
@ -352,23 +352,4 @@ func Setup(
|
||||||
return util.JSONResponse{Code: 200, JSON: struct{}{}}
|
return util.JSONResponse{Code: 200, JSON: struct{}{}}
|
||||||
}),
|
}),
|
||||||
).Methods("PUT", "OPTIONS")
|
).Methods("PUT", "OPTIONS")
|
||||||
|
|
||||||
// Stub implementations for sytest
|
|
||||||
r0mux.Handle("/events",
|
|
||||||
common.MakeExternalAPI("events", func(req *http.Request) util.JSONResponse {
|
|
||||||
return util.JSONResponse{Code: 200, JSON: map[string]interface{}{
|
|
||||||
"chunk": []interface{}{},
|
|
||||||
"start": "",
|
|
||||||
"end": "",
|
|
||||||
}}
|
|
||||||
}),
|
|
||||||
).Methods("GET")
|
|
||||||
|
|
||||||
r0mux.Handle("/initialSync",
|
|
||||||
common.MakeExternalAPI("initial_sync", func(req *http.Request) util.JSONResponse {
|
|
||||||
return util.JSONResponse{Code: 200, JSON: map[string]interface{}{
|
|
||||||
"end": "",
|
|
||||||
}}
|
|
||||||
}),
|
|
||||||
).Methods("GET")
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,7 @@ func (m *monolith) setupAPIs() {
|
||||||
|
|
||||||
syncapi_routing.Setup(m.api, syncapi_sync.NewRequestPool(
|
syncapi_routing.Setup(m.api, syncapi_sync.NewRequestPool(
|
||||||
m.syncAPIDB, m.syncAPINotifier, m.accountDB,
|
m.syncAPIDB, m.syncAPINotifier, m.accountDB,
|
||||||
), m.deviceDB)
|
), m.deviceDB, m.syncAPIDB)
|
||||||
|
|
||||||
federationapi_routing.Setup(
|
federationapi_routing.Setup(
|
||||||
m.api, *m.cfg, m.queryAPI, m.roomServerProducer, m.keyRing, m.federation,
|
m.api, *m.cfg, m.queryAPI, m.roomServerProducer, m.keyRing, m.federation,
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ func main() {
|
||||||
log.Info("Starting sync server on ", cfg.Listen.SyncAPI)
|
log.Info("Starting sync server on ", cfg.Listen.SyncAPI)
|
||||||
|
|
||||||
api := mux.NewRouter()
|
api := mux.NewRouter()
|
||||||
routing.Setup(api, sync.NewRequestPool(db, n, adb), deviceDB)
|
routing.Setup(api, sync.NewRequestPool(db, n, adb), deviceDB, db)
|
||||||
common.SetupHTTPAPI(http.DefaultServeMux, api)
|
common.SetupHTTPAPI(http.DefaultServeMux, api)
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(string(cfg.Listen.SyncAPI), nil))
|
log.Fatal(http.ListenAndServe(string(cfg.Listen.SyncAPI), nil))
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
|
"github.com/matrix-org/dendrite/syncapi/storage"
|
||||||
"github.com/matrix-org/dendrite/syncapi/sync"
|
"github.com/matrix-org/dendrite/syncapi/sync"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
|
@ -28,7 +29,12 @@ import (
|
||||||
const pathPrefixR0 = "/_matrix/client/r0"
|
const pathPrefixR0 = "/_matrix/client/r0"
|
||||||
|
|
||||||
// Setup configures the given mux with sync-server listeners
|
// Setup configures the given mux with sync-server listeners
|
||||||
func Setup(apiMux *mux.Router, srp *sync.RequestPool, deviceDB *devices.Database) {
|
func Setup(
|
||||||
|
apiMux *mux.Router,
|
||||||
|
srp *sync.RequestPool,
|
||||||
|
deviceDB *devices.Database,
|
||||||
|
syncDB *storage.SyncServerDatabase,
|
||||||
|
) {
|
||||||
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
|
r0mux := apiMux.PathPrefix(pathPrefixR0).Subrouter()
|
||||||
|
|
||||||
r0mux.Handle("/sync", common.MakeAuthAPI("sync", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
|
r0mux.Handle("/sync", common.MakeAuthAPI("sync", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
|
||||||
|
|
@ -39,4 +45,23 @@ func Setup(apiMux *mux.Router, srp *sync.RequestPool, deviceDB *devices.Database
|
||||||
vars := mux.Vars(req)
|
vars := mux.Vars(req)
|
||||||
return srp.OnIncomingStateRequest(req, vars["roomID"])
|
return srp.OnIncomingStateRequest(req, vars["roomID"])
|
||||||
})).Methods("GET")
|
})).Methods("GET")
|
||||||
|
|
||||||
|
// Stub implementations for sytest
|
||||||
|
r0mux.Handle("/events",
|
||||||
|
common.MakeExternalAPI("events", func(req *http.Request) util.JSONResponse {
|
||||||
|
return util.JSONResponse{Code: 200, JSON: map[string]interface{}{
|
||||||
|
"chunk": []interface{}{},
|
||||||
|
"start": "",
|
||||||
|
"end": "",
|
||||||
|
}}
|
||||||
|
}),
|
||||||
|
).Methods("GET")
|
||||||
|
|
||||||
|
r0mux.Handle("/initialSync",
|
||||||
|
common.MakeAuthAPI("initial_sync", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
|
||||||
|
return sync.GetInitialSync(
|
||||||
|
req, device, syncDB,
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
).Methods("GET")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
// Copyright 2017 Vector Creations Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sync
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
|
"github.com/matrix-org/dendrite/syncapi/storage"
|
||||||
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetInitialSync gets called on an /initialSync request.
|
||||||
|
func GetInitialSync(
|
||||||
|
req *http.Request, device *authtypes.Device,
|
||||||
|
db *storage.SyncServerDatabase,
|
||||||
|
) util.JSONResponse {
|
||||||
|
// TODO: Support limit
|
||||||
|
syncResponse, err := db.CompleteSync(
|
||||||
|
req.Context(), device.UserID, DefaultTimelineLimit,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return httputil.LogThenError(req, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
intialSyncResponse := syncResponseToIntialSync(syncResponse)
|
||||||
|
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 200,
|
||||||
|
JSON: intialSyncResponse,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func syncResponseToIntialSync(syncResponse *types.Response) initialSyncResponse {
|
||||||
|
var rooms []initialSyncRoomResponse
|
||||||
|
|
||||||
|
for roomID, room := range syncResponse.Rooms.Join {
|
||||||
|
rooms = append(rooms, initialSyncRoomResponse{
|
||||||
|
RoomID: roomID,
|
||||||
|
Membership: "join",
|
||||||
|
|
||||||
|
Messages: initialSyncChunk{
|
||||||
|
Chunk: room.Timeline.Events, // TODO: Correctly format events
|
||||||
|
End: room.Timeline.PrevBatch, // TODO: Start?
|
||||||
|
},
|
||||||
|
|
||||||
|
State: initialSyncChunk{
|
||||||
|
Chunk: room.State.Events, // TODO: Add state from timeline
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Invites, leaves, account data, presence, etc.
|
||||||
|
|
||||||
|
return initialSyncResponse{
|
||||||
|
Rooms: rooms,
|
||||||
|
End: syncResponse.NextBatch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type initialSyncResponse struct {
|
||||||
|
End string `json:"end"`
|
||||||
|
Rooms []initialSyncRoomResponse `json:"rooms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type initialSyncRoomResponse struct {
|
||||||
|
Membership string `json:"membership"`
|
||||||
|
RoomID string `json:"room_id"`
|
||||||
|
Messages initialSyncChunk `json:"messages,omitempty"`
|
||||||
|
State initialSyncChunk `json:"state,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type initialSyncChunk struct {
|
||||||
|
Start string `json:"start"`
|
||||||
|
End string `json:"end"`
|
||||||
|
Chunk []gomatrixserverlib.ClientEvent `json:"chunk"`
|
||||||
|
}
|
||||||
|
|
@ -286,7 +286,7 @@ func newTestSyncRequest(userID string, since types.StreamPosition) syncRequest {
|
||||||
timeout: 1 * time.Minute,
|
timeout: 1 * time.Minute,
|
||||||
since: since,
|
since: since,
|
||||||
wantFullState: false,
|
wantFullState: false,
|
||||||
limit: defaultTimelineLimit,
|
limit: DefaultTimelineLimit,
|
||||||
log: util.GetLogger(context.TODO()),
|
log: util.GetLogger(context.TODO()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultSyncTimeout = time.Duration(30) * time.Second
|
const defaultSyncTimeout = time.Duration(30) * time.Second
|
||||||
const defaultTimelineLimit = 20
|
|
||||||
|
// DefaultTimelineLimit is the default number limit of timeline entries if no
|
||||||
|
// limit was given.
|
||||||
|
const DefaultTimelineLimit = 20
|
||||||
|
|
||||||
// syncRequest represents a /sync request, with sensible defaults/sanity checks applied.
|
// syncRequest represents a /sync request, with sensible defaults/sanity checks applied.
|
||||||
type syncRequest struct {
|
type syncRequest struct {
|
||||||
|
|
@ -54,7 +57,7 @@ func newSyncRequest(req *http.Request, userID string) (*syncRequest, error) {
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
since: since,
|
since: since,
|
||||||
wantFullState: wantFullState,
|
wantFullState: wantFullState,
|
||||||
limit: defaultTimelineLimit, // TODO: read from filter
|
limit: DefaultTimelineLimit, // TODO: read from filter
|
||||||
log: util.GetLogger(req.Context()),
|
log: util.GetLogger(req.Context()),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue