diff --git a/federationtypes.go b/federationtypes.go index 3f288970..7415905e 100644 --- a/federationtypes.go +++ b/federationtypes.go @@ -305,28 +305,18 @@ type RespMakeJoin struct { // A RespSendJoin is the content of a response to PUT /_matrix/federation/v1/send_join/{roomID}/{eventID} // It has the same data as a response to /state, but in a slightly different wire format. -type RespSendJoin RespState +type RespSendJoin struct { + StateEvents []Event + AuthEvents []Event + Origin string +} // MarshalJSON implements json.Marshaller func (r RespSendJoin) MarshalJSON() ([]byte, error) { - // SendJoinResponses contain the same data as a StateResponse but are - // formatted slightly differently on the wire: - // 1) The "pdus" field is renamed to "state". - // 2) The object is placed as the second element of a two element list - // where the first element is the constant integer 200. - // - // - // So a state response of: - // - // {"pdus": x, "auth_chain": y} - // - // Becomes: - // - // [200, {"state": x, "auth_chain": y}] - // + // RespSendJoin is sent as the second element + // of a two element list where the first element is the constant integer 200. // (This protocol oddity is the result of a typo in the synapse matrix // server, and is preserved to maintain compatibility.) - return json.Marshal([]interface{}{200, respSendJoinFields(r)}) } @@ -350,6 +340,15 @@ func (r *RespSendJoin) UnmarshalJSON(data []byte) error { type respSendJoinFields struct { StateEvents []Event `json:"state"` AuthEvents []Event `json:"auth_chain"` + Origin string `json:"origin"` +} + +// ToRespState returns a new RespState with the same data from the given RespSendJoin +func (r RespSendJoin) ToRespState() RespState { + return RespState{ + StateEvents: r.StateEvents, + AuthEvents: r.AuthEvents, + } } // Check that a response to /send_join is valid. @@ -361,7 +360,7 @@ func (r RespSendJoin) Check(ctx context.Context, keyRing JSONVerifier, joinEvent // // The response to /send_join has the same data as a response to /state // and the checks for a response to /state also apply. - if err := RespState(r).Check(ctx, keyRing); err != nil { + if err := r.ToRespState().Check(ctx, keyRing); err != nil { return err } diff --git a/federationtypes_test.go b/federationtypes_test.go index 2b35d1f8..0e8f7471 100644 --- a/federationtypes_test.go +++ b/federationtypes_test.go @@ -50,8 +50,8 @@ func TestParseServerName(t *testing.T) { } func TestRespSendJoinMarshalJSON(t *testing.T) { - inputData := `{"pdus":[],"auth_chain":[]}` - var input RespState + inputData := `{"state":[],"auth_chain":[],"origin":""}` + var input respSendJoinFields if err := json.Unmarshal([]byte(inputData), &input); err != nil { t.Fatal(err) } @@ -61,7 +61,7 @@ func TestRespSendJoinMarshalJSON(t *testing.T) { t.Fatal(err) } - want := `[200,{"state":[],"auth_chain":[]}]` + want := `[200,{"state":[],"auth_chain":[],"origin":""}]` got := string(gotBytes) if want != got { @@ -70,18 +70,18 @@ func TestRespSendJoinMarshalJSON(t *testing.T) { } func TestRespSendJoinUnmarshalJSON(t *testing.T) { - inputData := `[200,{"state":[],"auth_chain":[]}]` + inputData := `[200,{"state":[],"auth_chain":[],"origin":""}]` var input RespSendJoin if err := json.Unmarshal([]byte(inputData), &input); err != nil { t.Fatal(err) } - gotBytes, err := json.Marshal(RespState(input)) + gotBytes, err := json.Marshal(respSendJoinFields(input)) if err != nil { t.Fatal(err) } - want := `{"pdus":[],"auth_chain":[]}` + want := `{"state":[],"auth_chain":[],"origin":""}` got := string(gotBytes) if want != got {