Open kouta-kun opened 1 year ago
Something like this can be used as a monkeypatch workaround:
// https://github.com/aws/aws-sdk-js-v3/issues/6607 workaround due to HeadBucket not returning region at this moment
const cmd_ = new HeadBucketCommand({
Bucket: bucketName,
});
const command = cmd_ as unknown as {
deserialize: DeserializeFunction;
region: string | undefined;
};
const oldDeser = command.deserialize;
command.deserialize = (output, context) => {
command.region = output.headers["x-amz-bucket-region"];
return oldDeser(output, context);
};
const cmd = cmd_ as HeadBucketCommand & { region: string | undefined };
await new S3Client({
region: "us-east-1",
}).send(cmd);
if (cmd.region === undefined) {
console.error("No bucket region found!");
throw new Error("No bucket region found");
} else {
console.error(bucketName, "is in", cmd.region);
}
Hi @kouta-kun ,
The response is missing the metadata header because even though it is sent back, the S3 API model doesnt not model a response at all for this operation. You can check the model file and see that the generated type is the generic smithy response object. This generic type includes only httpStatusCode
, requestId
, extendedRequestId
and cfId
.
If you didn't know, each SDK client is code generated from its respective service API model. That means that if the model is lacking a definition for something, the data wont get deserialized / serialized.
You can however you can create your own middleware step, and pipe the header into the response manually:
const client = new S3Client({ region: 'us-east-1' });
client.middlewareStack.add( (next) => async (args) => {
const result = await next(args);
result.output.$metadata.region = result.response.headers['x-amz-bucket-region']
return result;
},
{
step: 'finalize',
name: "myMiddleware",
override: true
}
);
// rest of your code
printing the response of headBucket will result in:
{
'$metadata': {
httpStatusCode: 200,
requestId: 'REDACTED',
extendedRequestId: 'REDACTED',
cfId: undefined,
attempts: 1,
totalRetryDelay: 0,
region: 'us-east-1'
}
}
So while the API behaves as documented, unfortunately the API model from which the SDK is generated from is lacking the desired output shape.
I have raised an internal PR to get this sorted out, but S3 is a really large and distributed team so finding an owner that can review this internally might prove challenging.
Please keep monitoring this ticket for further updates. Thanks again, Ran~
P97036807
Describe the issue
The AWS-SDK documentation recommends using HeadBucket instead of GetBucketLocation for determining Bucket region:
However, the header that contains this piece of information is not contained in the
$metadata
attribute of the HeadBucketCommandOutput object. According to Generic documentation, this information is returned in thex-amz-bucket-region
header, which does not seem to be part of the RequestMetadata (does not show in a debugger either).Links
https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadBucket.html https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/command/GetBucketLocationCommand/