cloudydeno/deno-aws_api

Backblaze B2 does not function

fucksophie opened this issue · 3 comments

code:

const s3 = new ApiFactory({
  credentials: {
    awsAccessKeyId: Deno.env.get("S3_ACCESS_KEY_ID")!,
    awsSecretKey: Deno.env.get("S3_SECRET_KEY")!,
  },
  fixedEndpoint: "https://s3.us-west-004.backblazeb2.com",
  region: "us-west-004",
}).makeNew(S3);

  await s3.createBucket({
    Bucket: s3Bucket,
  });

error:

header 'x-amz-content-sha256' must be included in signature [Request ID: 6df5c7d7d56e595d

sha256 is not sent alongside requests to b2 (b2 requires sha256's)

Hello, thanks for the report. This sounds like a difference between the Backblaze and AWS API implementations.

In reviewing my code, I believe that the header is being sent properly, but is not included in the signature. I suppose AWS is fine with that since the request overall is still signed.

I believe that I just need to swap these two blocks of signing code, so that x-amz-content-sha256 is computed before the request headers are observed.

let canonicalHeaders = "";
let signedHeaders = "";
for (const key of [...headers.keys()].sort()) {
if (unsignableHeaders.has(key.toLowerCase())) continue;
canonicalHeaders += `${key.toLowerCase()}:${headers.get(key)}\n`;
signedHeaders += `${key.toLowerCase()};`;
}
signedHeaders = signedHeaders.substring(0, signedHeaders.length - 1);
// TODO: support for unsigned bodies (for streaming)
const body = request.body
? new Uint8Array(await request.arrayBuffer())
: null;
const payloadHash = sha256(body ?? new Uint8Array()).hex();
if (service === 's3') {
headers.set("x-amz-content-sha256", payloadHash);
}

I'll test the change with AWS for regressions when preparing a PR.
I do not have a Backblaze account handy to verify any fixes, so once I attach a PR, I'd love to get a yes-or-no on whether it resolves the stated problem.

Ok, here's an importable module from the associated PR which should resolve this signing issue: https://raw.githubusercontent.com/cloudydeno/deno-aws_api/666991bff325933f28954bc4878fca6aff2f89a1/lib/client/mod.ts

I've lightly tested with real S3 and don't see any regressions there

Works perfectly. Thanks!!