Implement /state endpoint

This commit is contained in:
Brendan Abolivier 2017-09-21 19:12:25 +02:00
parent 91fa5d6a12
commit 67f2fecb26
No known key found for this signature in database
GPG key ID: 8EF1500759F70623
3 changed files with 59 additions and 0 deletions

View file

@ -33,4 +33,9 @@ func Setup(apiMux *mux.Router, srp *sync.RequestPool, deviceDB *devices.Database
r0mux.Handle("/sync", common.MakeAuthAPI("sync", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
return srp.OnIncomingSyncRequest(req, device)
})).Methods("GET")
r0mux.Handle("/rooms/{roomID}/state", common.MakeAuthAPI("room_state", deviceDB, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
vars := mux.Vars(req)
return srp.OnIncomingStateRequest(req, vars["roomID"])
}))
}

View file

@ -162,6 +162,16 @@ func (d *SyncServerDatabase) GetStateEvent(
return d.roomstate.selectStateEvent(ctx, evType, roomID, stateKey)
}
func (d *SyncServerDatabase) GetStateEventsForRoom(
ctx context.Context, roomID string,
) (stateEvents []gomatrixserverlib.Event, err error) {
err = common.WithTransaction(d.db, func(txn *sql.Tx) error {
stateEvents, err = d.roomstate.selectCurrentState(ctx, txn, roomID)
return err
})
return
}
// SyncStreamPosition returns the latest position in the sync stream. Returns 0 if there are no events yet.
func (d *SyncServerDatabase) SyncStreamPosition(ctx context.Context) (types.StreamPosition, error) {
return d.syncStreamPositionTx(ctx, nil)

View file

@ -15,6 +15,8 @@
package sync
import (
"encoding/json"
"fmt"
"net/http"
"time"
@ -105,6 +107,48 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtype
}
}
type stateEventInResp struct {
gomatrixserverlib.ClientEvent
PrevContent json.RawMessage `json:"prev_content,omitempty"`
ReplacesState string `json:"replaces_state,omitempty"`
}
func (rp *RequestPool) OnIncomingStateRequest(req *http.Request, roomID string) util.JSONResponse {
stateEvents, err := rp.db.GetStateEventsForRoom(req.Context(), roomID)
if err != nil {
return httputil.LogThenError(req, err)
}
resp := []stateEventInResp{}
// Fill the prev_content and replaces_state keys if necessary
for _, event := range stateEvents {
stateEvent := stateEventInResp{ClientEvent: gomatrixserverlib.ToClientEvent(event, gomatrixserverlib.FormatAll)}
var prevEventRef types.PrevEventRef
fmt.Println(len(event.Unsigned()))
if len(event.Unsigned()) > 0 {
if err := json.Unmarshal(event.Unsigned(), &prevEventRef); err != nil {
return httputil.LogThenError(req, err)
}
// Fills the previous state event ID if the state event replaces another
// state event
if len(prevEventRef.ReplacesState) > 0 {
stateEvent.ReplacesState = prevEventRef.ReplacesState
}
// Fill the previous event if the state event references a previous event
if prevEventRef.PrevContent != nil {
stateEvent.PrevContent = prevEventRef.PrevContent
}
}
resp = append(resp, stateEvent)
}
return util.JSONResponse{
Code: 200,
JSON: resp,
}
}
func (rp *RequestPool) currentSyncForUser(req syncRequest, currentPos types.StreamPosition) (*types.Response, error) {
// TODO: handle ignored users
if req.since == types.StreamPosition(0) {