Merge remote-tracking branch 'upstream/main' into conduwuit-changes
This commit is contained in:
commit
9900d06765
@ -23,7 +23,9 @@ use ruma_events::{
|
||||
};
|
||||
use serde::{de::Error as _, Deserialize, Serialize};
|
||||
|
||||
use super::{v5, DeviceLists, UnreadNotificationsCount};
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
use super::v5;
|
||||
use super::{DeviceLists, UnreadNotificationsCount};
|
||||
|
||||
const METADATA: Metadata = metadata! {
|
||||
method: POST,
|
||||
@ -928,6 +930,7 @@ impl Typing {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::Request> for Request {
|
||||
fn from(value: v5::Request) -> Self {
|
||||
Self {
|
||||
@ -952,6 +955,7 @@ impl From<v5::Request> for Request {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::List> for SyncRequestList {
|
||||
fn from(value: v5::request::List) -> Self {
|
||||
Self {
|
||||
@ -974,12 +978,14 @@ impl From<v5::request::List> for SyncRequestList {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::RoomDetails> for RoomDetailsConfig {
|
||||
fn from(value: v5::request::RoomDetails) -> Self {
|
||||
Self { required_state: value.required_state, timeline_limit: value.timeline_limit }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::ListFilters> for SyncRequestListFilters {
|
||||
fn from(value: v5::request::ListFilters) -> Self {
|
||||
Self {
|
||||
@ -990,6 +996,7 @@ impl From<v5::request::ListFilters> for SyncRequestListFilters {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::RoomSubscription> for RoomSubscription {
|
||||
fn from(value: v5::request::RoomSubscription) -> Self {
|
||||
Self {
|
||||
@ -1000,6 +1007,7 @@ impl From<v5::request::RoomSubscription> for RoomSubscription {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::Extensions> for ExtensionsConfig {
|
||||
fn from(value: v5::request::Extensions) -> Self {
|
||||
Self {
|
||||
@ -1014,6 +1022,7 @@ impl From<v5::request::Extensions> for ExtensionsConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::ToDevice> for ToDeviceConfig {
|
||||
fn from(value: v5::request::ToDevice) -> Self {
|
||||
Self {
|
||||
@ -1026,18 +1035,21 @@ impl From<v5::request::ToDevice> for ToDeviceConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::E2EE> for E2EEConfig {
|
||||
fn from(value: v5::request::E2EE) -> Self {
|
||||
Self { enabled: value.enabled }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::AccountData> for AccountDataConfig {
|
||||
fn from(value: v5::request::AccountData) -> Self {
|
||||
Self { enabled: value.enabled, lists: value.lists, rooms: value.rooms }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::Receipts> for ReceiptsConfig {
|
||||
fn from(value: v5::request::Receipts) -> Self {
|
||||
Self {
|
||||
@ -1048,6 +1060,7 @@ impl From<v5::request::Receipts> for ReceiptsConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::ReceiptsRoom> for RoomReceiptConfig {
|
||||
fn from(value: v5::request::ReceiptsRoom) -> Self {
|
||||
match value {
|
||||
@ -1057,6 +1070,7 @@ impl From<v5::request::ReceiptsRoom> for RoomReceiptConfig {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc4186")]
|
||||
impl From<v5::request::Typing> for TypingConfig {
|
||||
fn from(value: v5::request::Typing) -> Self {
|
||||
Self { enabled: value.enabled, lists: value.lists, rooms: value.rooms }
|
||||
|
@ -18,6 +18,11 @@ Improvements:
|
||||
- Stabilize support for muting in VoIP calls, according to Matrix 1.11
|
||||
- All the root `Any*EventContent` types now have a `EventContentFromType` implementations
|
||||
automatically derived by the `event_enum!` macro.
|
||||
- `CallMemberEventContent` now supports two different formats: Session memberships and Legacy memberships.
|
||||
The new format (Session) is required to reliably display the call member count (reliable call member events).
|
||||
`CallMemberEventContent` is now an enum to model the two different formats.
|
||||
- `CallMemberStateKey` (instead of `OwnedUserId`) is now used as the state key type for `CallMemberEventContent`.
|
||||
This guarantees correct formatting of the event key.
|
||||
|
||||
Breaking changes:
|
||||
|
||||
|
@ -11,7 +11,7 @@ mod member_state_key;
|
||||
pub use focus::*;
|
||||
pub use member_data::*;
|
||||
pub use member_state_key::*;
|
||||
use ruma_common::MilliSecondsSinceUnixEpoch;
|
||||
use ruma_common::{MilliSecondsSinceUnixEpoch, OwnedDeviceId};
|
||||
use ruma_macros::{EventContent, StringEnum};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -56,7 +56,7 @@ impl CallMemberEventContent {
|
||||
/// Creates a new [`CallMemberEventContent`] with [`SessionMembershipData`].
|
||||
pub fn new(
|
||||
application: Application,
|
||||
device_id: String,
|
||||
device_id: OwnedDeviceId,
|
||||
focus_active: ActiveFocus,
|
||||
foci_preferred: Vec<Focus>,
|
||||
created_ts: Option<MilliSecondsSinceUnixEpoch>,
|
||||
@ -234,8 +234,8 @@ mod tests {
|
||||
|
||||
use assert_matches2::assert_matches;
|
||||
use ruma_common::{
|
||||
device_id, user_id, MilliSecondsSinceUnixEpoch as TS, OwnedEventId, OwnedRoomId,
|
||||
OwnedUserId,
|
||||
device_id, owned_device_id, user_id, MilliSecondsSinceUnixEpoch as TS, OwnedEventId,
|
||||
OwnedRoomId, OwnedUserId,
|
||||
};
|
||||
use serde_json::{from_value as from_json_value, json, Value as JsonValue};
|
||||
|
||||
@ -257,7 +257,7 @@ mod tests {
|
||||
call_id: "123456".to_owned(),
|
||||
scope: CallScope::Room,
|
||||
}),
|
||||
device_id: "ABCDE".to_owned(),
|
||||
device_id: owned_device_id!("ABCDE"),
|
||||
expires: Duration::from_secs(3600),
|
||||
foci_active: vec![Focus::Livekit(LivekitFocus {
|
||||
alias: "1".to_owned(),
|
||||
@ -274,7 +274,7 @@ mod tests {
|
||||
call_id: "123456".to_owned(),
|
||||
scope: CallScope::Room,
|
||||
}),
|
||||
"ABCDE".to_owned(),
|
||||
owned_device_id!("ABCDE"),
|
||||
ActiveFocus::Livekit(ActiveLivekitFocus {
|
||||
focus_selection: FocusSelection::OldestMembership,
|
||||
}),
|
||||
@ -354,7 +354,7 @@ mod tests {
|
||||
call_id: "123456".to_owned(),
|
||||
scope: CallScope::Room,
|
||||
}),
|
||||
"THIS_DEVICE".to_owned(),
|
||||
owned_device_id!("THIS_DEVICE"),
|
||||
ActiveFocus::Livekit(ActiveLivekitFocus {
|
||||
focus_selection: FocusSelection::OldestMembership,
|
||||
}),
|
||||
@ -404,7 +404,7 @@ mod tests {
|
||||
call_id: "123456".to_owned(),
|
||||
scope: CallScope::Room,
|
||||
}),
|
||||
device_id: "THIS_DEVICE".to_owned(),
|
||||
device_id: owned_device_id!("THIS_DEVICE"),
|
||||
expires: Duration::from_secs(3600),
|
||||
foci_active: vec![Focus::Livekit(LivekitFocus {
|
||||
alias: "room1".to_owned(),
|
||||
@ -418,7 +418,7 @@ mod tests {
|
||||
call_id: "".to_owned(),
|
||||
scope: CallScope::Room,
|
||||
}),
|
||||
device_id: "OTHER_DEVICE".to_owned(),
|
||||
device_id: owned_device_id!("OTHER_DEVICE"),
|
||||
expires: Duration::from_secs(3600),
|
||||
foci_active: vec![Focus::Livekit(LivekitFocus {
|
||||
alias: "room2".to_owned(),
|
||||
@ -526,7 +526,7 @@ mod tests {
|
||||
call_id: "".to_owned(),
|
||||
scope: CallScope::Room,
|
||||
}),
|
||||
device_id: "THIS_DEVICE".to_owned(),
|
||||
device_id: owned_device_id!("THIS_DEVICE"),
|
||||
foci_preferred: [Focus::Livekit(LivekitFocus {
|
||||
alias: "room1".to_owned(),
|
||||
service_url: "https://livekit1.com".to_owned(),
|
||||
|
@ -5,7 +5,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use as_variant::as_variant;
|
||||
use ruma_common::MilliSecondsSinceUnixEpoch;
|
||||
use ruma_common::{DeviceId, MilliSecondsSinceUnixEpoch, OwnedDeviceId};
|
||||
use ruma_macros::StringEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::warn;
|
||||
@ -41,7 +41,7 @@ impl<'a> MembershipData<'a> {
|
||||
}
|
||||
|
||||
/// The device id of this membership.
|
||||
pub fn device_id(&self) -> &String {
|
||||
pub fn device_id(&self) -> &DeviceId {
|
||||
match self {
|
||||
MembershipData::Legacy(data) => &data.device_id,
|
||||
MembershipData::Session(data) => &data.device_id,
|
||||
@ -121,7 +121,7 @@ pub struct LegacyMembershipData {
|
||||
/// The device id of this membership.
|
||||
///
|
||||
/// The same user can join with their phone/computer.
|
||||
pub device_id: String,
|
||||
pub device_id: OwnedDeviceId,
|
||||
|
||||
/// The duration in milliseconds relative to the time this membership joined
|
||||
/// during which the membership is valid.
|
||||
@ -190,7 +190,7 @@ pub struct LegacyMembershipDataInit {
|
||||
/// The device id of this membership.
|
||||
///
|
||||
/// The same user can join with their phone/computer.
|
||||
pub device_id: String,
|
||||
pub device_id: OwnedDeviceId,
|
||||
|
||||
/// The duration in milliseconds relative to the time this membership joined
|
||||
/// during which the membership is valid.
|
||||
@ -236,7 +236,7 @@ pub struct SessionMembershipData {
|
||||
/// The device id of this membership.
|
||||
///
|
||||
/// The same user can join with their phone/computer.
|
||||
pub device_id: String,
|
||||
pub device_id: OwnedDeviceId,
|
||||
|
||||
/// A list of the foci that this membership proposes to use.
|
||||
pub foci_preferred: Vec<Focus>,
|
||||
|
@ -16,11 +16,11 @@ pub struct CallMemberStateKey {
|
||||
|
||||
impl CallMemberStateKey {
|
||||
/// Constructs a new CallMemberStateKey there are three possible formats:
|
||||
/// - "_{UserId}_{DeviceId}" example: "_@test:user.org_DEVICE". `device_id`: Some`, `underscore:
|
||||
/// - `_{UserId}_{DeviceId}` example: `_@test:user.org_DEVICE`. `device_id: Some`, `underscore:
|
||||
/// true`
|
||||
/// - "{UserId}_{DeviceId}" example: "@test:user.org_DEVICE". `device_id`: Some`, `underscore:
|
||||
/// - `{UserId}_{DeviceId}` example: `@test:user.org_DEVICE`. `device_id: Some`, `underscore:
|
||||
/// false`
|
||||
/// - "{UserId}" example example: "@test:user.org". `device_id`: None`, underscore is ignored:
|
||||
/// - `{UserId}` example: `@test:user.org`. `device_id: None`, underscore is ignored:
|
||||
/// `underscore: false|true`
|
||||
///
|
||||
/// Dependent on the parameters the correct CallMemberStateKey will be constructed.
|
||||
|
@ -174,12 +174,20 @@ fn try_from_multipart_mixed_response<T: AsRef<[u8]>>(
|
||||
let mut full_boundary = Vec::with_capacity(boundary.len() + 4);
|
||||
full_boundary.extend_from_slice(b"\r\n--");
|
||||
full_boundary.extend_from_slice(boundary);
|
||||
let full_boundary_no_crlf = full_boundary.strip_prefix(b"\r\n").unwrap();
|
||||
|
||||
let mut boundaries = memchr::memmem::find_iter(body, &full_boundary);
|
||||
|
||||
let metadata_start = boundaries.next().ok_or_else(|| {
|
||||
MultipartMixedDeserializationError::MissingBodyParts { expected: 2, found: 0 }
|
||||
})? + full_boundary.len();
|
||||
let metadata_start = if body.starts_with(full_boundary_no_crlf) {
|
||||
// If there is no preamble before the first boundary, it may omit the
|
||||
// preceding CRLF.
|
||||
full_boundary_no_crlf.len()
|
||||
} else {
|
||||
boundaries.next().ok_or_else(|| MultipartMixedDeserializationError::MissingBodyParts {
|
||||
expected: 2,
|
||||
found: 0,
|
||||
})? + full_boundary.len()
|
||||
};
|
||||
let metadata_end = boundaries.next().ok_or_else(|| {
|
||||
MultipartMixedDeserializationError::MissingBodyParts { expected: 2, found: 0 }
|
||||
})?;
|
||||
@ -417,6 +425,15 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
try_from_multipart_mixed_response(response).unwrap_err();
|
||||
|
||||
// Boundary without CRLF with preamble.
|
||||
let body = "foo--abcdef\r\n\r\n{}\r\n--abcdef\r\n\r\nsome plain text\r\n--abcdef--";
|
||||
let response = http::Response::builder()
|
||||
.header(http::header::CONTENT_TYPE, "multipart/mixed; boundary=abcdef")
|
||||
.body(body)
|
||||
.unwrap();
|
||||
|
||||
try_from_multipart_mixed_response(response).unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -483,6 +500,36 @@ mod tests {
|
||||
assert_eq!(file_content.content_type.unwrap(), "text/plain");
|
||||
assert_eq!(file_content.content_disposition, None);
|
||||
|
||||
// No leading CRLF (and no preamble)
|
||||
let body = "--abcdef\r\n\r\n{}\r\n--abcdef\r\n\r\nsome plain text\r\n--abcdef--";
|
||||
let response = http::Response::builder()
|
||||
.header(http::header::CONTENT_TYPE, "multipart/mixed; boundary=abcdef")
|
||||
.body(body)
|
||||
.unwrap();
|
||||
|
||||
let (_metadata, content) = try_from_multipart_mixed_response(response).unwrap();
|
||||
|
||||
assert_matches!(content, FileOrLocation::File(file_content));
|
||||
assert_eq!(file_content.file, b"some plain text");
|
||||
assert_eq!(file_content.content_type, None);
|
||||
assert_eq!(file_content.content_disposition, None);
|
||||
|
||||
// Boundary text in preamble, but no leading CRLF, so it should be
|
||||
// ignored.
|
||||
let body =
|
||||
"foo--abcdef\r\n--abcdef\r\n\r\n{}\r\n--abcdef\r\n\r\nsome plain text\r\n--abcdef--";
|
||||
let response = http::Response::builder()
|
||||
.header(http::header::CONTENT_TYPE, "multipart/mixed; boundary=abcdef")
|
||||
.body(body)
|
||||
.unwrap();
|
||||
|
||||
let (_metadata, content) = try_from_multipart_mixed_response(response).unwrap();
|
||||
|
||||
assert_matches!(content, FileOrLocation::File(file_content));
|
||||
assert_eq!(file_content.file, b"some plain text");
|
||||
assert_eq!(file_content.content_type, None);
|
||||
assert_eq!(file_content.content_disposition, None);
|
||||
|
||||
// No body part headers.
|
||||
let body = "\r\n--abcdef\r\n\r\n{}\r\n--abcdef\r\n\r\nsome plain text\r\n--abcdef--";
|
||||
let response = http::Response::builder()
|
||||
|
Loading…
x
Reference in New Issue
Block a user