S3Md5Middleware.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. const Crypto = require('node:crypto')
  2. /**
  3. * Creates an S3 client that uses MD5 checksums for DeleteObjects operations
  4. * https://github.com/aws/aws-sdk-js-v3/blob/main/supplemental-docs/MD5_FALLBACK.md
  5. */
  6. const md5Middleware = (next, context) => async args => {
  7. if (context.commandName !== 'DeleteObjectsCommand') {
  8. return next(args)
  9. }
  10. const headers = args.request.headers
  11. // Remove any checksum headers added by default middleware
  12. // This ensures our Content-MD5 is the primary integrity check
  13. Object.keys(headers).forEach(header => {
  14. const lowerHeader = header.toLowerCase()
  15. if (
  16. lowerHeader.startsWith('x-amz-checksum-') ||
  17. lowerHeader.startsWith('x-amz-sdk-checksum-')
  18. ) {
  19. delete headers[header]
  20. }
  21. })
  22. if (args.request.body) {
  23. const bodyContent = Buffer.from(args.request.body)
  24. headers['Content-MD5'] = Crypto.createHash('md5')
  25. .update(bodyContent)
  26. .digest('base64')
  27. }
  28. return await next(args)
  29. }
  30. function addMd5Middleware(client) {
  31. // Add the middleware relative to the flexible checksums middleware
  32. // This ensures it runs after default checksums might be added, but before signing
  33. client.middlewareStack.add(md5Middleware, {
  34. step: 'build',
  35. toMiddleware: 'flexibleChecksumsMiddleware',
  36. name: 'addMD5ChecksumForDeleteObjects',
  37. tags: ['MD5_FALLBACK'],
  38. })
  39. }
  40. module.exports = {
  41. addMd5Middleware,
  42. }