For it being allowed, the CEO commented as such here. I realise it's not the best reference but I'm not searching through ToS during lunch haha
https://news.ycombinator.com/item?id=20791605As for how to, something like this (Maybe don't use this specifically in production, it was cobbled together from examples as a proof of concept).
It may be missing caching, depending on if/how Cloudflare caches the output of Workers. It's been a moment since I've looked at this project but I'm pretty sure it was caching files that could be cached (using the etag bit on line 22).
https://gist.github.com/cohan/1b154156c9c3d3b269581c940339ce...
You configure what `R2` in my example refers to in wrangler.toml
[[r2_buckets]]
binding = 'R2' # <~ valid JavaScript variable name
bucket_name = 'mybucketname'
E: Random thought you probably don't actually need to do this anymore, R2 has public bucket and custom domain settings now. I needed this for the CORS headers, as that was being a pita at the time