3636 ThumbnailInfo ,
3737 respond_404 ,
3838 respond_with_file ,
39+ respond_with_multipart_responder ,
3940 respond_with_responder ,
4041)
41- from synapse .media .media_storage import MediaStorage
42+ from synapse .media .media_storage import FileResponder , MediaStorage
43+ from synapse .storage .databases .main .media_repository import LocalMedia
4244
4345if TYPE_CHECKING :
4446 from synapse .media .media_repository import MediaRepository
@@ -271,6 +273,7 @@ async def respond_local_thumbnail(
271273 method : str ,
272274 m_type : str ,
273275 max_timeout_ms : int ,
276+ for_federation : bool ,
274277 ) -> None :
275278 media_info = await self .media_repo .get_local_media_info (
276279 request , media_id , max_timeout_ms
@@ -290,6 +293,8 @@ async def respond_local_thumbnail(
290293 media_id ,
291294 url_cache = bool (media_info .url_cache ),
292295 server_name = None ,
296+ for_federation = for_federation ,
297+ media_info = media_info ,
293298 )
294299
295300 async def select_or_generate_local_thumbnail (
@@ -301,6 +306,7 @@ async def select_or_generate_local_thumbnail(
301306 desired_method : str ,
302307 desired_type : str ,
303308 max_timeout_ms : int ,
309+ for_federation : bool ,
304310 ) -> None :
305311 media_info = await self .media_repo .get_local_media_info (
306312 request , media_id , max_timeout_ms
@@ -326,10 +332,16 @@ async def select_or_generate_local_thumbnail(
326332
327333 responder = await self .media_storage .fetch_media (file_info )
328334 if responder :
329- await respond_with_responder (
330- request , responder , info .type , info .length
331- )
332- return
335+ if for_federation :
336+ await respond_with_multipart_responder (
337+ self .hs .get_clock (), request , responder , media_info
338+ )
339+ return
340+ else :
341+ await respond_with_responder (
342+ request , responder , info .type , info .length
343+ )
344+ return
333345
334346 logger .debug ("We don't have a thumbnail of that size. Generating" )
335347
@@ -344,7 +356,15 @@ async def select_or_generate_local_thumbnail(
344356 )
345357
346358 if file_path :
347- await respond_with_file (request , desired_type , file_path )
359+ if for_federation :
360+ await respond_with_multipart_responder (
361+ self .hs .get_clock (),
362+ request ,
363+ FileResponder (open (file_path , "rb" )),
364+ media_info ,
365+ )
366+ else :
367+ await respond_with_file (request , desired_type , file_path )
348368 else :
349369 logger .warning ("Failed to generate thumbnail" )
350370 raise SynapseError (400 , "Failed to generate thumbnail." )
@@ -360,9 +380,10 @@ async def select_or_generate_remote_thumbnail(
360380 desired_type : str ,
361381 max_timeout_ms : int ,
362382 ip_address : str ,
383+ use_federation : bool ,
363384 ) -> None :
364385 media_info = await self .media_repo .get_remote_media_info (
365- server_name , media_id , max_timeout_ms , ip_address
386+ server_name , media_id , max_timeout_ms , ip_address , use_federation
366387 )
367388 if not media_info :
368389 respond_404 (request )
@@ -424,12 +445,13 @@ async def respond_remote_thumbnail(
424445 m_type : str ,
425446 max_timeout_ms : int ,
426447 ip_address : str ,
448+ use_federation : bool ,
427449 ) -> None :
428450 # TODO: Don't download the whole remote file
429451 # We should proxy the thumbnail from the remote server instead of
430452 # downloading the remote file and generating our own thumbnails.
431453 media_info = await self .media_repo .get_remote_media_info (
432- server_name , media_id , max_timeout_ms , ip_address
454+ server_name , media_id , max_timeout_ms , ip_address , use_federation
433455 )
434456 if not media_info :
435457 return
@@ -448,6 +470,7 @@ async def respond_remote_thumbnail(
448470 media_info .filesystem_id ,
449471 url_cache = False ,
450472 server_name = server_name ,
473+ for_federation = False ,
451474 )
452475
453476 async def _select_and_respond_with_thumbnail (
@@ -461,7 +484,9 @@ async def _select_and_respond_with_thumbnail(
461484 media_id : str ,
462485 file_id : str ,
463486 url_cache : bool ,
487+ for_federation : bool ,
464488 server_name : Optional [str ] = None ,
489+ media_info : Optional [LocalMedia ] = None ,
465490 ) -> None :
466491 """
467492 Respond to a request with an appropriate thumbnail from the previously generated thumbnails.
@@ -476,6 +501,8 @@ async def _select_and_respond_with_thumbnail(
476501 file_id: The ID of the media that a thumbnail is being requested for.
477502 url_cache: True if this is from a URL cache.
478503 server_name: The server name, if this is a remote thumbnail.
504+ for_federation: whether the request is from the federation /thumbnail request
505+ media_info: metadata about the media being requested.
479506 """
480507 logger .debug (
481508 "_select_and_respond_with_thumbnail: media_id=%s desired=%sx%s (%s) thumbnail_infos=%s" ,
@@ -511,13 +538,20 @@ async def _select_and_respond_with_thumbnail(
511538
512539 responder = await self .media_storage .fetch_media (file_info )
513540 if responder :
514- await respond_with_responder (
515- request ,
516- responder ,
517- file_info .thumbnail .type ,
518- file_info .thumbnail .length ,
519- )
520- return
541+ if for_federation :
542+ assert media_info is not None
543+ await respond_with_multipart_responder (
544+ self .hs .get_clock (), request , responder , media_info
545+ )
546+ return
547+ else :
548+ await respond_with_responder (
549+ request ,
550+ responder ,
551+ file_info .thumbnail .type ,
552+ file_info .thumbnail .length ,
553+ )
554+ return
521555
522556 # If we can't find the thumbnail we regenerate it. This can happen
523557 # if e.g. we've deleted the thumbnails but still have the original
@@ -558,12 +592,18 @@ async def _select_and_respond_with_thumbnail(
558592 )
559593
560594 responder = await self .media_storage .fetch_media (file_info )
561- await respond_with_responder (
562- request ,
563- responder ,
564- file_info .thumbnail .type ,
565- file_info .thumbnail .length ,
566- )
595+ if for_federation :
596+ assert media_info is not None
597+ await respond_with_multipart_responder (
598+ self .hs .get_clock (), request , responder , media_info
599+ )
600+ else :
601+ await respond_with_responder (
602+ request ,
603+ responder ,
604+ file_info .thumbnail .type ,
605+ file_info .thumbnail .length ,
606+ )
567607 else :
568608 # This might be because:
569609 # 1. We can't create thumbnails for the given media (corrupted or
0 commit comments