You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
2.1 KiB

  1. const fs = require('fs');
  2. const path = require('path');
  3. const crypto = require('crypto');
  4. const {
  5. debugLog,
  6. checkAndMakeDir,
  7. getTempFilename,
  8. deleteFile
  9. } = require('./utilities');
  10. module.exports = (options, fieldname, filename) => {
  11. const dir = path.normalize(options.tempFileDir);
  12. const tempFilePath = path.join(dir, getTempFilename());
  13. checkAndMakeDir({ createParentPath: true }, tempFilePath);
  14. debugLog(options, `Temporary file path is ${tempFilePath}`);
  15. const hash = crypto.createHash('md5');
  16. let fileSize = 0;
  17. let completed = false;
  18. debugLog(options, `Opening write stream for ${fieldname}->${filename}...`);
  19. const writeStream = fs.createWriteStream(tempFilePath);
  20. const writePromise = new Promise((resolve, reject) => {
  21. writeStream.on('finish', () => resolve());
  22. writeStream.on('error', (err) => {
  23. debugLog(options, `Error write temp file: ${err}`);
  24. reject(err);
  25. });
  26. });
  27. return {
  28. dataHandler: (data) => {
  29. if (completed === true) {
  30. debugLog(options, `Error: got ${fieldname}->${filename} data chunk for completed upload!`);
  31. return;
  32. }
  33. writeStream.write(data);
  34. hash.update(data);
  35. fileSize += data.length;
  36. debugLog(options, `Uploading ${fieldname}->${filename}, bytes:${fileSize}...`);
  37. },
  38. getFilePath: () => tempFilePath,
  39. getFileSize: () => fileSize,
  40. getHash: () => hash.digest('hex'),
  41. complete: () => {
  42. completed = true;
  43. debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`);
  44. if (writeStream !== false) writeStream.end();
  45. // Return empty buff since data was uploaded into a temp file.
  46. return Buffer.concat([]);
  47. },
  48. cleanup: () => {
  49. completed = true;
  50. debugLog(options, `Cleaning up temporary file ${tempFilePath}...`);
  51. writeStream.end();
  52. deleteFile(tempFilePath, err => (err
  53. ? debugLog(options, `Cleaning up temporary file ${tempFilePath} failed: ${err}`)
  54. : debugLog(options, `Cleaning up temporary file ${tempFilePath} done.`)
  55. ));
  56. },
  57. getWritePromise: () => writePromise
  58. };
  59. };