MCPcopy Create free account
hub / github.com/daodst/chat / getRemoteFile

Method getRemoteFile

mediaapi/routing/download.go:514–567  ·  view source on GitHub ↗

getRemoteFile fetches the remote file and caches it locally A hash map of active remote requests to a struct containing a sync.Cond is used to only download remote files once, regardless of how many download requests are received. Note: The named errorResponse return variable is used in a deferred b

(
	ctx context.Context,
	client *gomatrixserverlib.Client,
	cfg *config.MediaAPI,
	db storage.Database,
	activeRemoteRequests *types.ActiveRemoteRequests,
	activeThumbnailGeneration *types.ActiveThumbnailGeneration,
)

Source from the content-addressed store, hash-verified

512// regardless of how many download requests are received.
513// Note: The named errorResponse return variable is used in a deferred broadcast of the metadata and error response to waiting goroutines.
514func (r *downloadRequest) getRemoteFile(
515 ctx context.Context,
516 client *gomatrixserverlib.Client,
517 cfg *config.MediaAPI,
518 db storage.Database,
519 activeRemoteRequests *types.ActiveRemoteRequests,
520 activeThumbnailGeneration *types.ActiveThumbnailGeneration,
521) (errorResponse error) {
522 // Note: getMediaMetadataFromActiveRequest uses mutexes and conditions from activeRemoteRequests
523 mediaMetadata, resErr := r.getMediaMetadataFromActiveRequest(activeRemoteRequests)
524 if resErr != nil {
525 return resErr
526 } else if mediaMetadata != nil {
527 // If we got metadata from an active request, we can respond from the local file
528 r.MediaMetadata = mediaMetadata
529 } else {
530 // Note: This is an active request that MUST broadcastMediaMetadata to wake up waiting goroutines!
531 // Note: broadcastMediaMetadata uses mutexes and conditions from activeRemoteRequests
532 defer func() {
533 // Note: errorResponse is the named return variable so we wrap this in a closure to re-evaluate the arguments at defer-time
534 if err := recover(); err != nil {
535 r.broadcastMediaMetadata(activeRemoteRequests, errors.New("paniced"))
536 panic(err)
537 }
538 r.broadcastMediaMetadata(activeRemoteRequests, errorResponse)
539 }()
540
541 // check if we have a record of the media in our database
542 mediaMetadata, err := db.GetMediaMetadata(
543 ctx, r.MediaMetadata.MediaID, r.MediaMetadata.Origin,
544 )
545 if err != nil {
546 return fmt.Errorf("db.GetMediaMetadata: %w", err)
547 }
548
549 if mediaMetadata == nil {
550 // If we do not have a record, we need to fetch the remote file first and then respond from the local file
551 err := r.fetchRemoteFileAndStoreMetadata(
552 ctx, client,
553 cfg.AbsBasePath, cfg.MaxFileSizeBytes, db,
554 cfg.ThumbnailSizes, activeThumbnailGeneration,
555 cfg.MaxThumbnailGenerators,
556 )
557 if err != nil {
558 r.Logger.WithError(err).Errorf("r.fetchRemoteFileAndStoreMetadata: failed to fetch remote file")
559 return err
560 }
561 } else {
562 // If we have a record, we can respond from the local file
563 r.MediaMetadata = mediaMetadata
564 }
565 }
566 return nil
567}
568
569func (r *downloadRequest) getMediaMetadataFromActiveRequest(activeRemoteRequests *types.ActiveRemoteRequests) (*types.MediaMetadata, error) {
570 // Check if there is an active remote request for the file

Callers 1

doDownloadMethod · 0.95

Tested by

no test coverage detected