Skip to content

Return user metadata in GetObjectAttributes API#6070

Open
maeldonn wants to merge 10 commits intofeature/CLDSRV-817/get-object-attributesfrom
feature/CLDSRV-844/user-metadata
Open

Return user metadata in GetObjectAttributes API#6070
maeldonn wants to merge 10 commits intofeature/CLDSRV-817/get-object-attributesfrom
feature/CLDSRV-844/user-metadata

Conversation

@maeldonn
Copy link

@maeldonn maeldonn commented Feb 4, 2026

Issue: CLDSRV-817

@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from 2e7333e to 2b69771 Compare February 4, 2026 10:04
@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 90.19608% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.20%. Comparing base (e118699) to head (595b908).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
lib/api/bucketGet.js 61.53% 5 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

Files with missing lines Coverage Δ
...i/apiUtils/authorization/prepareRequestContexts.js 95.58% <100.00%> (+0.23%) ⬆️
lib/api/apiUtils/object/extractUserMetadata.js 100.00% <100.00%> (ø)
lib/api/apiUtils/object/parseAttributesHeader.js 100.00% <100.00%> (ø)
lib/api/metadataSearch.js 76.38% <100.00%> (ø)
lib/api/objectGetAttributes.js 97.29% <100.00%> (+0.28%) ⬆️
lib/routes/veeam/list.js 97.50% <ø> (ø)
lib/utilities/serverAccessLogger.js 81.85% <ø> (ø)
lib/api/bucketGet.js 92.81% <61.53%> (+0.26%) ⬆️
@@                             Coverage Diff                              @@
##           feature/CLDSRV-817/get-object-attributes    #6070      +/-   ##
============================================================================
+ Coverage                                     84.17%   84.20%   +0.03%     
============================================================================
  Files                                           206      207       +1     
  Lines                                         13233    13253      +20     
============================================================================
+ Hits                                          11139    11160      +21     
+ Misses                                         2094     2093       -1     
Flag Coverage Δ
file-ft-tests 67.90% <82.35%> (+0.11%) ⬆️
kmip-ft-tests 28.12% <13.72%> (-0.01%) ⬇️
mongo-v0-ft-tests 69.11% <84.31%> (+0.11%) ⬆️
mongo-v1-ft-tests 69.22% <84.31%> (+0.11%) ⬆️
multiple-backend 35.17% <39.21%> (+0.04%) ⬆️
sur-tests 36.48% <23.52%> (+0.83%) ⬆️
sur-tests-inflights 37.52% <23.52%> (+0.01%) ⬆️
unit 69.89% <88.23%> (+0.05%) ⬆️
utapi-v2-tests 34.43% <39.21%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch 4 times, most recently from 95b17ef to ab4f29a Compare February 4, 2026 14:38
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 64cd8a1 to 4a72a6d Compare February 4, 2026 14:41
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from ab4f29a to fc3441c Compare February 4, 2026 14:41
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 4a72a6d to 92bd9be Compare February 4, 2026 14:47
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch 2 times, most recently from 4b757aa to 78dd47a Compare February 4, 2026 15:50
@maeldonn maeldonn requested review from a team, SylvainSenechal and benzekrimaha February 4, 2026 16:35
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from 78dd47a to 1a3d966 Compare February 9, 2026 14:41
@DarkIsDude DarkIsDude removed their request for review February 10, 2026 09:44
headers[headerName]
?.split(',')
.map(attr => attr.trim())
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait so it means even if the attribute is not in supportedAttribute, it will be returned as lower cased ?
Shouldn't this be a filter instead ?

I mean, ok I guess the overall function works because later there is the attributes.some() and has() thing, but could it be clearer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyways, maybe the funciton is good enough as it is, but if you're able to make it a bit clearer it's nice, cause it's doing multiple thing that aren't completely obvious from the function name, it looks like it's gonna do some generic parsing, then ends up doing lowercasing and having a special case for x-amz-meta. Maybe renaming function name and intermediates variables help

Copy link
Author

@maeldonn maeldonn Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not a supported attribute:

  1. It's user metadata so it's ok
  2. It's something else -> will throw an exception

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems uselessly innefficient: we traverse the list 3 times to do the same thing...

  • trim() can be done in the same iteration, no need to the extra strings/list allocation
  • isn't user metadata already mandated (by spec) to be lower case? do we do the same lower case conversion in other APIs? if not, not need to be more accommodating here
  • if an attribute is in the supportedAttributes, there is no point making another check for the prefix (and rechecking later it is a supported attribute, if there is no prefix)
Suggested change
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
const attributes =
headers[headerName]?.split(',').map(attr => {
const res = attr.trim())
if (!supportedAttributes.has(res) && !res.startsWith('x-amz-meta-')) {
throw errorInstances.InvalidArgument.customizeDescription('Invalid attribute name specified.');
}
return res;
});

Copy link
Contributor

@SylvainSenechal SylvainSenechal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments to address, 2 tests to add

headers[headerName]
?.split(',')
.map(attr => attr.trim())
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems uselessly innefficient: we traverse the list 3 times to do the same thing...

  • trim() can be done in the same iteration, no need to the extra strings/list allocation
  • isn't user metadata already mandated (by spec) to be lower case? do we do the same lower case conversion in other APIs? if not, not need to be more accommodating here
  • if an attribute is in the supportedAttributes, there is no point making another check for the prefix (and rechecking later it is a supported attribute, if there is no prefix)
Suggested change
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
const attributes =
headers[headerName]?.split(',').map(attr => {
const res = attr.trim())
if (!supportedAttributes.has(res) && !res.startsWith('x-amz-meta-')) {
throw errorInstances.InvalidArgument.customizeDescription('Invalid attribute name specified.');
}
return res;
});

let optionalAttributes;
try {
const headerName = 'x-amz-optional-object-attributes';
optionalAttributes = parseAttributesHeaders(request.headers, headerName, new Set(['RestoreStatus']));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Set should not be allocated on every call, should be a constant

* @param {string[]} attributes - requested attributes
* @returns {object} - object containing requested user metadata key-value pairs
*/
function extractUserMetadata(objMD, attributes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is already this logic in ListObjectv2, must be factorized...

}

const attributes = parseAttributesHeaders(headers);
const attributes = parseAttributesHeaders(headers, 'x-amz-object-attributes', supportedGetObjectAttributes, true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this true here makes it hard to understand what is happening, and it can just as well be done here (it does not add any value to have a conditional behavior inside the parseAttributesHeaders function):

Suggested change
const attributes = parseAttributesHeaders(headers, 'x-amz-object-attributes', supportedGetObjectAttributes, true);
const attributes = parseAttributesHeaders(headers, 'x-amz-object-attributes', supportedGetObjectAttributes);
if (attributes.length === 0) {
throw ....
}

@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 4868753 to c762cd8 Compare February 12, 2026 10:11
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from e040894 to 63d9d12 Compare February 12, 2026 13:59
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from c762cd8 to bef8034 Compare February 12, 2026 15:00
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch 2 times, most recently from 704c58d to 34f10d2 Compare February 12, 2026 17:07
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 3ebd2ab to e118699 Compare February 13, 2026 14:21
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from 34f10d2 to 74c8a30 Compare February 13, 2026 14:22
@delthas delthas removed their request for review February 16, 2026 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants