createInterceptDownload.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import { createObjectId } from '../grid/createObjectId';
  2. export const createInterceptDownload = bucket =>
  3. function interceptDownload(http, file, versionName) {
  4. const { gridFsFileId } = file.versions[versionName].meta || {};
  5. if (gridFsFileId) {
  6. // opens the download stream using a given gfs id
  7. // see: http://mongodb.github.io/node-mongodb-native/3.2/api/GridFSBucket.html#openDownloadStream
  8. const gfsId = createObjectId({ gridFsFileId });
  9. const readStream = bucket.openDownloadStream(gfsId);
  10. readStream.on('data', data => {
  11. http.response.write(data);
  12. });
  13. readStream.on('end', () => {
  14. http.response.end(); // don't pass parameters to end() or it will be attached to the file's binary stream
  15. });
  16. readStream.on('error', () => {
  17. // not found probably
  18. // eslint-disable-next-line no-param-reassign
  19. http.response.statusCode = 404;
  20. http.response.end('not found');
  21. });
  22. http.response.setHeader('Cache-Control', this.cacheControl);
  23. http.response.setHeader(
  24. 'Content-Disposition',
  25. getContentDisposition(file.name, http?.params?.query?.download),
  26. );
  27. }
  28. return Boolean(gridFsFileId); // Serve file from either GridFS or FS if it wasn't uploaded yet
  29. };
  30. /**
  31. * Will initiate download, if links are called with ?download="true" queryparam.
  32. **/
  33. const getContentDisposition = (name, downloadFlag) => {
  34. const dispositionType = downloadFlag === 'true' ? 'attachment;' : 'inline;';
  35. const encodedName = encodeURIComponent(name);
  36. const dispositionName = `filename="${encodedName}"; filename=*UTF-8"${encodedName}";`;
  37. const dispositionEncoding = 'charset=utf-8';
  38. return `${dispositionType} ${dispositionName} ${dispositionEncoding}`;
  39. };