Return S3 signed URLs for assets and cached-assets
needed for https://github.com/huggingface/datasets-server/pull/2224.

- [x] sign cached-assets URLs: #2298
- [x] invalidate the CloudFront cache when an asset is deleted? It has a 1h TTL, so: it will disappear at some point anyway
- [x] for /first-rows: sign assets URLs. It's a bigger change because the response is not generated on the fly.
  - option 1: we could let it unchanged, but documenting that it requires the client to sign the assets URLs, which means that the images and audio in `/first-rows` could only be accessed by the Hub, since it requires knowing the private key. And this option would require adding code in moon-landing.
  - option 2a: we could get all the URLs in the response using a regex, then sign them and replace in the JSON. It would be simpler than parsing the JSON completely (the asset URLs can be nested)
  - option 2b: we could traverse the `split-first-rows-from-*` content object, find the assets URLs (starts with `https://datasets-server.huggingface.co/assets/`), and sign them. Question: maybe we should ensure it's a URL we created, ie: in an image or audio feature column, to avoid people creating this kind of URLs in a string column (low probability, and low impact anyway).
  - option 2c: we visit the `"features"` field in `split-first-rows-from-*` content objects, find the Audio and Image features (they can be nested), then visit the `"rows"` and sign the sources.   <- **implementing this option** in https://github.com/huggingface/datasets-server/pull/2315 + https://github.com/huggingface/datasets-server/pull/2365

Return S3 signed URLs for assets and cached-assets: needed for https://github.com/huggingface/datasets-server/pull/2224.

- [x] sign cached-assets URLs: #2298
- [x] invalidate the CloudFront cache when an asset is deleted? It has a 1h TTL, so: it will disappear at some point anyway
- [x] for /first-rows: sign assets URLs. It's a bigger change because the response is not generated on the fly.
  - option 1: we could let it unchanged, but documenting that it requires the client to sign the assets URLs, which means that the images and audio in `/first-rows` could only be accessed by the Hub, since it requires knowing the private key. And this option would require adding code in moon-landing.
  - option 2a: we could get all the URLs in the response using a regex, then sign them and replace in the JSON. It would be simpler than parsing the JSON completely (the asset URLs can be nested)
  - option 2b: we could traverse the `split-first-rows-from-*` content object, find the assets URLs (starts with `https://datasets-server.huggingface.co/assets/`), and sign them. Question: maybe we should ensure it's a URL we created, ie: in an image or audio feature column, to avoid people creating this kind of URLs in a string column (low probability, and low impact anyway).
  - option 2c: we visit the `"features"` field in `split-first-rows-from-*` content objects, find the Audio and Image features (they can be nested), then visit the `"rows"` and sign the sources.   <- **implementing this option** in https://github.com/huggingface/datasets-server/pull/2315 + https://github.com/huggingface/datasets-server/pull/2365
