Skip to content
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

Backblaze B2 does not function #32

Closed
fucksophie opened this issue Apr 21, 2022 · 3 comments · Fixed by #35
Closed

Backblaze B2 does not function #32

fucksophie opened this issue Apr 21, 2022 · 3 comments · Fixed by #35

Comments

@fucksophie
Copy link

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)

@danopia
Copy link
Member

danopia commented May 5, 2022

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.

@danopia
Copy link
Member

danopia commented May 5, 2022

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

@fucksophie
Copy link
Author

Works perfectly. Thanks!!

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 a pull request may close this issue.

2 participants