Skip to content

Commit ef4cb79

Browse files
committed
fix(sdk): Upload encrypted media with application/octet-stream mime type
This is apparently the right way to do it, both because some HS expect only this mimetype and also so we don't leak the mime type of the encrypted media.
1 parent 9fbb9cb commit ef4cb79

File tree

6 files changed

+54
-28
lines changed

6 files changed

+54
-28
lines changed

crates/matrix-sdk/src/encryption/futures.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,14 @@ use crate::{config::RequestConfig, Client, Media, Result, TransmissionProgress};
3131
#[allow(missing_debug_implementations)]
3232
pub struct UploadEncryptedFile<'a, R: ?Sized> {
3333
client: &'a Client,
34-
content_type: &'a mime::Mime,
3534
reader: &'a mut R,
3635
send_progress: SharedObservable<TransmissionProgress>,
3736
request_config: Option<RequestConfig>,
3837
}
3938

4039
impl<'a, R: ?Sized> UploadEncryptedFile<'a, R> {
41-
pub(crate) fn new(client: &'a Client, content_type: &'a mime::Mime, reader: &'a mut R) -> Self {
42-
Self {
43-
client,
44-
content_type,
45-
reader,
46-
send_progress: Default::default(),
47-
request_config: None,
48-
}
40+
pub(crate) fn new(client: &'a Client, reader: &'a mut R) -> Self {
41+
Self { client, reader, send_progress: Default::default(), request_config: None }
4942
}
5043

5144
/// Replace the default `SharedObservable` used for tracking upload
@@ -87,7 +80,7 @@ where
8780
boxed_into_future!(extra_bounds: 'a);
8881

8982
fn into_future(self) -> Self::IntoFuture {
90-
let Self { client, content_type, reader, send_progress, request_config } = self;
83+
let Self { client, reader, send_progress, request_config } = self;
9184
Box::pin(async move {
9285
let mut encryptor = matrix_sdk_base::crypto::AttachmentEncryptor::new(reader);
9386

@@ -101,7 +94,7 @@ where
10194

10295
let response = client
10396
.media()
104-
.upload(content_type, buf, request_config)
97+
.upload(&mime::APPLICATION_OCTET_STREAM, buf, request_config)
10598
.with_send_progress_observable(send_progress)
10699
.await?;
107100

crates/matrix-sdk/src/encryption/mod.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -435,24 +435,22 @@ impl Client {
435435
/// # let client = Client::new(homeserver).await?;
436436
/// # let room = client.get_room(&room_id!("!test:example.com")).unwrap();
437437
/// let mut reader = std::io::Cursor::new(b"Hello, world!");
438-
/// let encrypted_file = client.upload_encrypted_file(&mime::TEXT_PLAIN, &mut reader).await?;
438+
/// let encrypted_file = client.upload_encrypted_file(&mut reader).await?;
439439
///
440440
/// room.send(CustomEventContent { encrypted_file }).await?;
441441
/// # anyhow::Ok(()) };
442442
/// ```
443443
pub fn upload_encrypted_file<'a, R: Read + ?Sized + 'a>(
444444
&'a self,
445-
content_type: &'a mime::Mime,
446445
reader: &'a mut R,
447446
) -> UploadEncryptedFile<'a, R> {
448-
UploadEncryptedFile::new(self, content_type, reader)
447+
UploadEncryptedFile::new(self, reader)
449448
}
450449

451450
/// Encrypt and upload the file and thumbnails, and return the source
452451
/// information.
453452
pub(crate) async fn upload_encrypted_media_and_thumbnail(
454453
&self,
455-
content_type: &mime::Mime,
456454
data: &[u8],
457455
thumbnail: Option<Thumbnail>,
458456
send_progress: SharedObservable<TransmissionProgress>,
@@ -461,7 +459,7 @@ impl Client {
461459

462460
let upload_attachment = async {
463461
let mut cursor = Cursor::new(data);
464-
self.upload_encrypted_file(content_type, &mut cursor)
462+
self.upload_encrypted_file(&mut cursor)
465463
.with_send_progress_observable(send_progress)
466464
.await
467465
};
@@ -482,11 +480,11 @@ impl Client {
482480
return Ok(None);
483481
};
484482

485-
let (data, content_type, thumbnail_info) = thumbnail.into_parts();
483+
let (data, _, thumbnail_info) = thumbnail.into_parts();
486484
let mut cursor = Cursor::new(data);
487485

488486
let file = self
489-
.upload_encrypted_file(&content_type, &mut cursor)
487+
.upload_encrypted_file(&mut cursor)
490488
.with_send_progress_observable(send_progress)
491489
.await?;
492490

crates/matrix-sdk/src/room/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2101,7 +2101,7 @@ impl Room {
21012101
#[cfg(feature = "e2e-encryption")]
21022102
let (media_source, thumbnail) = if self.latest_encryption_state().await?.is_encrypted() {
21032103
self.client
2104-
.upload_encrypted_media_and_thumbnail(content_type, &data, thumbnail, send_progress)
2104+
.upload_encrypted_media_and_thumbnail(&data, thumbnail, send_progress)
21052105
.await?
21062106
} else {
21072107
self.client

crates/matrix-sdk/src/room/shared_room_history.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ pub async fn share_room_history(room: &Room, user_id: OwnedUserId) -> Result<()>
5353

5454
// 2. Upload to the server as an encrypted file
5555
let json = serde_json::to_vec(&bundle)?;
56-
let upload =
57-
client.upload_encrypted_file(&mime::APPLICATION_JSON, &mut (json.as_slice())).await?;
56+
let upload = client.upload_encrypted_file(&mut (json.as_slice())).await?;
5857

5958
info!(
6059
media_url = ?upload.url,

crates/matrix-sdk/src/send_queue/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -705,12 +705,6 @@ impl RoomSendQueue {
705705
trace!(%relates_to, "uploading media related to event");
706706

707707
let fut = async move {
708-
let mime = Mime::from_str(&content_type).map_err(|_| {
709-
crate::Error::SendQueueWedgeError(Box::new(
710-
QueueWedgeError::InvalidMimeType { mime_type: content_type.clone() },
711-
))
712-
})?;
713-
714708
let data = room
715709
.client()
716710
.event_cache_store()
@@ -722,13 +716,19 @@ impl RoomSendQueue {
722716
QueueWedgeError::MissingMediaContent,
723717
)))?;
724718

719+
let mime = Mime::from_str(&content_type).map_err(|_| {
720+
crate::Error::SendQueueWedgeError(Box::new(
721+
QueueWedgeError::InvalidMimeType { mime_type: content_type.clone() },
722+
))
723+
})?;
724+
725725
#[cfg(feature = "e2e-encryption")]
726726
let media_source = if room.latest_encryption_state().await?.is_encrypted() {
727727
trace!("upload will be encrypted (encrypted room)");
728728
let mut cursor = std::io::Cursor::new(data);
729729
let encrypted_file = room
730730
.client()
731-
.upload_encrypted_file(&mime, &mut cursor)
731+
.upload_encrypted_file(&mut cursor)
732732
.with_request_config(RequestConfig::short_retry())
733733
.await?;
734734
MediaSource::Encrypted(Box::new(encrypted_file))

crates/matrix-sdk/tests/integration/room/attachment/mod.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,42 @@ async fn test_room_attachment_send() {
5858
assert_eq!(expected_event_id, response.event_id);
5959
}
6060

61+
#[cfg(feature = "e2e-encryption")]
62+
#[async_test]
63+
async fn test_room_attachment_send_in_encrypted_room_has_binary_mime_type() {
64+
let mock = MatrixMockServer::new().await;
65+
66+
let expected_event_id = event_id!("$h29iv0s8:example.com");
67+
68+
mock.mock_room_send().ok(expected_event_id).mock_once().mount().await;
69+
70+
mock.mock_upload()
71+
.expect_mime_type("application/octet-stream")
72+
.ok(mxc_uri!("mxc://example.com/AQwafuaFswefuhsfAFAgsw"))
73+
.up_to_n_times(2)
74+
.mount()
75+
.await;
76+
77+
// Needed for the message to be sent in an encrypted room
78+
mock.mock_get_members().ok(Vec::new()).mock_once().mount().await;
79+
80+
let client = mock.client_builder().build().await;
81+
let room = mock.sync_joined_room(&client, &DEFAULT_TEST_ROOM_ID).await;
82+
mock.mock_room_state_encryption().encrypted().mount().await;
83+
84+
let response = room
85+
.send_attachment(
86+
"image",
87+
&mime::IMAGE_JPEG,
88+
b"Hello world".to_vec(),
89+
AttachmentConfig::new(),
90+
)
91+
.await
92+
.expect("Failed to send attachment");
93+
94+
assert_eq!(expected_event_id, response.event_id);
95+
}
96+
6197
#[async_test]
6298
async fn test_room_attachment_send_info() {
6399
let mock = MatrixMockServer::new().await;

0 commit comments

Comments
 (0)