Supporting Cloudflare's R2 S3 compatible storage #4480
Replies: 4 comments 2 replies
-
Honestly the S3 configuration needs refactoring quite extensively, this PR got close… (#3277) it's incredibly hard to make changes as there are so many variations in use you always break someones setup 😬 |
Beta Was this translation helpful? Give feedback.
-
I've tried adding R2 as well, but I keep getting this message: <?xml version="1.0" encoding="UTF-8"?><Error><Code>InvalidArgument</Code><Message>Invalid Argument: Authorization</Message></Error> I checked the CloudFlare R2 Discord and it seems this is because they don't support S3 POST, too bad... |
Beta Was this translation helpful? Give feedback.
-
I needed this and made a quick fix which I'm posting here, in case someone else needs it 😄 The issue: Cloudflare R2 doesn't support POST uploads like S3 does (and which outline is using) // @ts-check
export default {
async fetch(request, env) {
const secret = "foobar"
const { pathname, origin, searchParams } = new URL(request.url)
// debug
if (pathname.startsWith("/_info")) {
return new Response("Hello world!")
}
// change attachment uploadUrl response
if (pathname === "/api/attachments.create") {
const resp = await fetch(request)
const json = await resp.json()
json.data.uploadUrl = origin + `/_upload?secret=${secret}`
return new Response(JSON.stringify(json, null, 2), {
headers: {
"content-type": "application/json; charset=utf-8",
},
})
}
// handle multipart form upload from outline
if (pathname === "/_upload") {
// Check if the secret matches
if (searchParams.get("secret") !== secret) {
return new Response("Unauthorized", { status: 400 })
}
const formData = await request.formData()
const file = formData.get("file")
const key = formData.get("key")
await env.OUTLINE_BUCKET.put(key, file.stream())
return new Response(`Put ${key} successfully!`)
}
return fetch(request)
},
} What the worker does:
Caveats:
sample name = "outline-proxy"
main = "src/index.js"
compatibility_date = "2023-03-28"
account_id = "foo"
route = "domain.com/*"
[[r2_buckets]]
binding = 'OUTLINE_BUCKET'
bucket_name = 'outline-bucket' |
Beta Was this translation helpful? Give feedback.
-
Here's a forked repository that has solved this problem. If you're interested, you can check it out at kencin@c722341. |
Beta Was this translation helpful? Give feedback.
-
R2 now supports public access which means you can talk to it via the open internet without needing to go through a cloudflare worker. But the bucket name gets appended to the s3 uri.... which isn't correct as far as R2 goes - the public uri is the "bucket" - you try making the bucket name nothing and you'll get some errors from outline saying it must be set.
Is there appetite for an extra param in the S3 settings to say "don't change the s3 public uri from what I've set" ?
I haven't tested this theory yet.... there may be other changes required too....
Beta Was this translation helpful? Give feedback.
All reactions