1414922026
* sytest: Make 'Inbound federation can backfill events' pass This breaks 'Outbound federation can backfill events' because now we are returning the right number of events, which the previous test was relying on. Previously, /messages was backfilling the membership event, causing the test to pass. Now we are no longer backfilling the membership event due to the change in this commit, causing the test to fail. The test should instead be returning the membership event locally from synacpis database, but it doesn't do it fast enough, resulting in a no-op /sync response with a next_batch=s0_0 which will never pick up the local membership event when it rolls in. The test does attempt to retry, but doesn't take the new next_batch=s1_0 resulting in it missing from the /messages response. * Linting
131 lines
3.8 KiB
Go
131 lines
3.8 KiB
Go
// Copyright 2018 New Vector 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 routing
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
|
"github.com/matrix-org/dendrite/common/config"
|
|
"github.com/matrix-org/dendrite/roomserver/api"
|
|
"github.com/matrix-org/gomatrixserverlib"
|
|
"github.com/matrix-org/util"
|
|
)
|
|
|
|
// Backfill implements the /backfill federation endpoint.
|
|
// https://matrix.org/docs/spec/server_server/unstable.html#get-matrix-federation-v1-backfill-roomid
|
|
func Backfill(
|
|
httpReq *http.Request,
|
|
request *gomatrixserverlib.FederationRequest,
|
|
rsAPI api.RoomserverInternalAPI,
|
|
roomID string,
|
|
cfg *config.Dendrite,
|
|
) util.JSONResponse {
|
|
var res api.QueryBackfillResponse
|
|
var eIDs []string
|
|
var limit string
|
|
var exists bool
|
|
var err error
|
|
|
|
// Check the room ID's format.
|
|
if _, _, err = gomatrixserverlib.SplitID('!', roomID); err != nil {
|
|
return util.JSONResponse{
|
|
Code: http.StatusBadRequest,
|
|
JSON: jsonerror.MissingArgument("Bad room ID: " + err.Error()),
|
|
}
|
|
}
|
|
|
|
// Check if all of the required parameters are there.
|
|
eIDs, exists = httpReq.URL.Query()["v"]
|
|
if !exists {
|
|
return util.JSONResponse{
|
|
Code: http.StatusBadRequest,
|
|
JSON: jsonerror.MissingArgument("v is missing"),
|
|
}
|
|
}
|
|
limit = httpReq.URL.Query().Get("limit")
|
|
if len(limit) == 0 {
|
|
return util.JSONResponse{
|
|
Code: http.StatusBadRequest,
|
|
JSON: jsonerror.MissingArgument("limit is missing"),
|
|
}
|
|
}
|
|
|
|
// Populate the request.
|
|
req := api.QueryBackfillRequest{
|
|
RoomID: roomID,
|
|
// we don't know who the successors are for these events, which won't
|
|
// be a problem because we don't use that information when servicing /backfill requests,
|
|
// only when making them. TODO: Think of a better API shape
|
|
BackwardsExtremities: map[string][]string{
|
|
"": eIDs,
|
|
},
|
|
ServerName: request.Origin(),
|
|
}
|
|
if req.Limit, err = strconv.Atoi(limit); err != nil {
|
|
util.GetLogger(httpReq.Context()).WithError(err).Error("strconv.Atoi failed")
|
|
return util.JSONResponse{
|
|
Code: http.StatusBadRequest,
|
|
JSON: jsonerror.InvalidArgumentValue(fmt.Sprintf("limit %q is invalid format", limit)),
|
|
}
|
|
}
|
|
|
|
// Query the roomserver.
|
|
if err = rsAPI.QueryBackfill(httpReq.Context(), &req, &res); err != nil {
|
|
util.GetLogger(httpReq.Context()).WithError(err).Error("query.QueryBackfill failed")
|
|
return jsonerror.InternalServerError()
|
|
}
|
|
|
|
// Filter any event that's not from the requested room out.
|
|
evs := make([]gomatrixserverlib.Event, 0)
|
|
|
|
var ev gomatrixserverlib.HeaderedEvent
|
|
for _, ev = range res.Events {
|
|
if ev.RoomID() == roomID {
|
|
evs = append(evs, ev.Event)
|
|
}
|
|
}
|
|
|
|
var eventJSONs []json.RawMessage
|
|
for _, e := range gomatrixserverlib.ReverseTopologicalOrdering(
|
|
evs,
|
|
gomatrixserverlib.TopologicalOrderByPrevEvents,
|
|
) {
|
|
eventJSONs = append(eventJSONs, e.JSON())
|
|
}
|
|
|
|
// sytest wants these in reversed order, similar to /messages, so reverse them now.
|
|
for i := len(eventJSONs)/2 - 1; i >= 0; i-- {
|
|
opp := len(eventJSONs) - 1 - i
|
|
eventJSONs[i], eventJSONs[opp] = eventJSONs[opp], eventJSONs[i]
|
|
}
|
|
|
|
txn := gomatrixserverlib.Transaction{
|
|
Origin: cfg.Matrix.ServerName,
|
|
PDUs: eventJSONs,
|
|
OriginServerTS: gomatrixserverlib.AsTimestamp(time.Now()),
|
|
}
|
|
|
|
// Send the events to the client.
|
|
return util.JSONResponse{
|
|
Code: http.StatusOK,
|
|
JSON: txn,
|
|
}
|
|
}
|