-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
S3Client.getObject does not work for binary data #105
Comments
Hi @KOConchobhair, Thanks for raising this topic 🙇🏻 First, let me ask you, as a library user, do you have any preference? From my side, I don't have a clear path in mind, but some of the thoughts from the top of my mind are:
That said, let me invoke @oleiade, because as the main contributor of the project, he might have some thoughts to share. |
hmm, it seems that the problem is worse than simply passing the
it always returns
The Typescript types for the But it seems the k6 http module is returning an I don't know if this is the root cause but it appears only |
okay, i think I see what's going on here. Even with the types fixed (I got a PR for that going here: DefinitelyTyped/DefinitelyTyped#69781) the k6 script itself is javascript so its a little confusing how to access the value for
|
Hey @KOConchobhair, Thanks for spending time on this, and for bringing all the details! 🙇🏻 Really appreciated!
I guess this might be related with 👉🏻 grafana/k6#3677 (comment) In any case, regarding your contributions:
Thanks! 🙏🏻 |
Fixes grafana#45
Okay, a PR for this issue is ready for review: #107 I've got a second PR for general cleanup/unit test fix ready for review as well: #106
Regarding the types, yeah I suppose I could move the changes there. Although while I don't claim to understand the release process, this fix seems like a bug to me in the currently released v0.51.0 version of k6. Why would we have to wait until v0.52.0 to fix an existing issue with the types? It would seem DefinitelyTyped can handle an update prior to to the next version. |
For context, I believe this is connected to #45; for which I unfortunately didn't find a satisfying solution at the time. Regarding the type definitions, we try to keep changes aligned there with the k6 releases indeed. However, in this specific case, I believe we could probably go ahead and amend the k6 v0.51 definitions directly. |
Hey folks 👋🏻 First and foremost, thanks for raising this and proactively contributing to the resolution @KOConchobhair 🙇🏻 I've been considering our options there, and although k6 initially adopted this approach in its Although we don't support most of them, the S3 Thus, my preference would be to add an That way, we can also start supporting more of the underlying API call request parameters as we need them in the future. What do you folks think? For reference, I've tried implementing it on the side to test the idea, and I quite like the look and feel... implementationasync getObject(bucketName: string, objectKey: string, additionalHeaders = {}): Promise<S3Object> {
// Prepare request
const method = 'GET'
const signedRequest = this.signature.sign(
{
method: method,
endpoint: this.endpoint,
path: encodeURI(`/${bucketName}/${objectKey}`),
headers: {
...additionalHeaders
},
},
{}
)
let responseType: ResponseType = 'text'
if ('Accept' in additionalHeaders &&
additionalHeaders['Accept'] !== undefined &&
additionalHeaders['Accept'] === "application/octet-stream") {
responseType = "binary"
}
const res = await http.asyncRequest(method, signedRequest.url, null, {
headers: signedRequest.headers,
responseType: responseType as ResponseType,
})
this._handle_error('GetObject', res)
return new S3Object(
objectKey,
Date.parse(res.headers['Last-Modified']),
res.headers['ETag'],
parseInt(res.headers['Content-Length']),
// The X-Amz-Storage-Class header is only set if the storage class is
// not the default 'STANDARD' one.
(res.headers['X-Amz-Storage-Class'] ?? 'STANDARD') as StorageClass,
res.body
)
} Usage// Let's redownload it, verify it's correct, and delete it
const downloadedFileContent = await s3.getObject(
testBucketName,
testFileKey,
{ 'Accept': 'application/octet-stream' })
console.log(`downloadedFileContent.byteLength: ${downloadedFileContent.data.byteLength}`)
console.log(downloadedFileContent.data instanceof ArrayBuffer)
if (downloadedFileContent.byteLength !== testFileContent.byteLength) {
exec.test.abort("Downloaded file size does not match the original file size")
} |
Fixes grafana#45
On top of #45, the
S3Client
cannot be used to download a binary file from S3!as I'm sure you are aware, if you have
discardResponseBodies=false
there’s a
Params.responseType
that you can pass to a call to k6'shttp
likeand that controls whether
res.body
is astring
or anArrayBuffer
.however since the
S3Client
code does not pass in aresponseType
in this codek6-jslib-aws/src/internal/s3.ts
Lines 185 to 187 in f6b5dce
then that means it defaults to
responseType: 'text'
and that meansWe need a way to either pass thru or hard-code a
responseType: 'binary'
for the k6http
client call ingetObject
.Do you have a preference on how that might be implemented?
The text was updated successfully, but these errors were encountered: