mirror of
https://github.com/hzrd149/blossom.git
synced 2026-02-05 02:54:30 +00:00
Compare commits
9 Commits
local-cach
...
chunked-bl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e4c3a0349 | ||
|
|
d05228aae1 | ||
|
|
1d855e1633 | ||
|
|
51c93670aa | ||
|
|
e39afe2149 | ||
|
|
4d82f98b3c | ||
|
|
8fc2e3dc31 | ||
|
|
a23d784673 | ||
|
|
33714b6c0c |
@@ -27,7 +27,7 @@ BUDs or **Blossom Upgrade Documents** are short documents that outline an additi
|
|||||||
- [BUD-08: Nostr File Metadata Tags](./buds/08.md)
|
- [BUD-08: Nostr File Metadata Tags](./buds/08.md)
|
||||||
- [BUD-09: Blob Report](./buds/09.md)
|
- [BUD-09: Blob Report](./buds/09.md)
|
||||||
- [BUD-10: Blossom URI Schema](./buds/10.md)
|
- [BUD-10: Blossom URI Schema](./buds/10.md)
|
||||||
- [BUD-11: Local Blob Cache](./buds/11.md)
|
- [BUD-12: Chunked blobs](./buds/12.md)
|
||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ Blossom Servers expose a few endpoints for managing blobs
|
|||||||
- `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required)
|
- `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required)
|
||||||
- Return a blob descriptor
|
- Return a blob descriptor
|
||||||
- `HEAD /upload` [BUD-06](./buds/06.md#head-upload---upload-requirements)
|
- `HEAD /upload` [BUD-06](./buds/06.md#head-upload---upload-requirements)
|
||||||
- `GET /list/<pubkey>` [BUD-02](./buds/02.md#get-listpubkey---list-blobs-unrecommended) _(optional, unrecommended)_
|
- `GET /list/<pubkey>` [BUD-02](./buds/02.md#get-listpubkey---list-blobs)
|
||||||
- Returns an array of blob descriptors
|
- Returns an array of blob descriptors
|
||||||
- `Authentication` _(optional)_: Signed [nostr event](./buds/02.md#list-authorization-optional)
|
- `Authentication` _(optional)_: Signed [nostr event](./buds/02.md#list-authorization-optional)
|
||||||
- `DELETE /<sha256>` [BUD-02](./buds/02.md#delete-sha256---delete-blob)
|
- `DELETE /<sha256>` [BUD-02](./buds/02.md#delete-sha256---delete-blob)
|
||||||
@@ -57,6 +57,7 @@ Blossom Servers expose a few endpoints for managing blobs
|
|||||||
| ------- | ------------------- | ------------------ |
|
| ------- | ------------------- | ------------------ |
|
||||||
| `24242` | Authorization event | [01](./buds/01.md) |
|
| `24242` | Authorization event | [01](./buds/01.md) |
|
||||||
| `10063` | User Server List | [03](./buds/03.md) |
|
| `10063` | User Server List | [03](./buds/03.md) |
|
||||||
|
| `2001` | Merkle tree | [12](./buds/12.md) |
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -76,9 +76,7 @@ Example Authorization event:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## GET /list/pubkey - List Blobs (Unrecommended)
|
## GET /list/pubkey - List Blobs (Optional)
|
||||||
|
|
||||||
**Note:** The `/list` endpoint is optional and unrecommended. It is not necessary for all servers to implement the `/list` endpoint. Servers MAY implement this endpoint, but are not required to do so.
|
|
||||||
|
|
||||||
The `/list/<pubkey>` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that were uploaded by the specified pubkey
|
The `/list/<pubkey>` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that were uploaded by the specified pubkey
|
||||||
|
|
||||||
|
|||||||
@@ -204,4 +204,3 @@ blossom:b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf?xs=
|
|||||||
```
|
```
|
||||||
blossom:a7b3c2d1e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1.png?xs=cdn.example.com&xs=media.nostr.build&as=781208004e09102d7da3b7345e64fd193cd1bc3fce8fdae6008d77f9cabcd036&as=b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e&sz=2547831
|
blossom:a7b3c2d1e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1.png?xs=cdn.example.com&xs=media.nostr.build&as=781208004e09102d7da3b7345e64fd193cd1bc3fce8fdae6008d77f9cabcd036&as=b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e&sz=2547831
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
107
buds/11.md
107
buds/11.md
@@ -1,107 +0,0 @@
|
|||||||
# BUD-11
|
|
||||||
|
|
||||||
## Local Blob Cache
|
|
||||||
|
|
||||||
`draft` `optional`
|
|
||||||
|
|
||||||
This document defines the specification for a local blob cache server that can be hosted on `127.0.0.1:24242` to provide fast, local access to cached blobs or proxy requests to other public Blossom servers.
|
|
||||||
|
|
||||||
## Server Address
|
|
||||||
|
|
||||||
A local blob cache server MUST be accessible on `http://127.0.0.1:24242`. The port `24242` is chosen to align with the Nostr event kind used for Blossom authorization events.
|
|
||||||
|
|
||||||
## Health Check Endpoint
|
|
||||||
|
|
||||||
The server MUST respond with a 2xx HTTP status code (typically `200 OK`) on the `HEAD /` endpoint to allow local applications to easily detect if the cache server is available.
|
|
||||||
|
|
||||||
The `HEAD /` endpoint MUST return a 2xx HTTP status code. The response MUST NOT include a response body per [RFC 7231](https://www.rfc-editor.org/rfc/rfc7231#section-4.3.2).
|
|
||||||
|
|
||||||
This endpoint enables simple health checks:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -I http://127.0.0.1:24242/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Access Control
|
|
||||||
|
|
||||||
The server SHOULD NOT require any authentication for blob downloads or uploads. All requests MUST be served without requiring an `Authorization` header.
|
|
||||||
|
|
||||||
If an implementation needs to add access control, it SHOULD restrict access based on IP address to ensure requests only come from `127.0.0.1`. This ensures that local applications can freely access cached blobs without the overhead of signing authorization events.
|
|
||||||
|
|
||||||
## Blob Retrieval
|
|
||||||
|
|
||||||
The server MUST implement the `GET /<sha256>` and `HEAD /<sha256>` endpoints as defined in [BUD-01](./01.md#get-sha256---get-blob):
|
|
||||||
|
|
||||||
1. The server MUST accept optional file extensions in the URL (e.g., `/<sha256>.pdf`)
|
|
||||||
2. The server MUST set appropriate `Content-Type` headers or default to `application/octet-stream`
|
|
||||||
|
|
||||||
## Range Requests
|
|
||||||
|
|
||||||
To better support mobile devices, video files, or low bandwidth connections, implementations SHOULD support range requests ([RFC 7233 section 3](https://www.rfc-editor.org/rfc/rfc7233#section-3)) on the `GET /<sha256>` endpoint and signal support using the `accept-ranges: bytes` and `content-length` headers on the `HEAD /<sha256>` endpoint.
|
|
||||||
|
|
||||||
See [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests) for more details.
|
|
||||||
|
|
||||||
## Proxy Hints
|
|
||||||
|
|
||||||
The server SHOULD accept [BUD-10](./10.md) query parameters `xs` (server) and `as` (author) hints on the `GET /<sha256>` endpoint to enable proxying blob requests to other Blossom servers when the blob is not available in the local cache.
|
|
||||||
|
|
||||||
### Query Parameter Format
|
|
||||||
|
|
||||||
When a blob is not found in the local cache, the server MAY use the following query parameters to attempt retrieval from other Blossom servers:
|
|
||||||
|
|
||||||
- `xs=<server>` - One or more server hints where the blob may be available
|
|
||||||
- `as=<pubkey>` - One or more author pubkeys whose server lists may contain the blob
|
|
||||||
|
|
||||||
### Example Request
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf?xs=cdn.example.com&as=ec4425ff5e9446080d2f70440188e3ca5d6da8713db7bdeef73d0ed54d9093f0
|
|
||||||
```
|
|
||||||
|
|
||||||
### Proxy Behavior
|
|
||||||
|
|
||||||
When the server receives a request with proxy hints and the blob is not in the local cache:
|
|
||||||
|
|
||||||
1. The server SHOULD attempt to retrieve the blob from the servers specified in the `xs` parameters
|
|
||||||
2. If `xs` hints fail, the server MAY attempt to retrieve the blob using the `as` parameters by:
|
|
||||||
- Fetching the author's [BUD-03](./03.md) server list (`kind:10063`)
|
|
||||||
- Attempting to retrieve the blob from servers in the author's list
|
|
||||||
3. If the blob is successfully retrieved, the server SHOULD:
|
|
||||||
- Cache the blob locally for future requests
|
|
||||||
- Return the blob to the client with appropriate headers
|
|
||||||
4. If the blob cannot be retrieved from any hint, the server MUST return a `404 Not Found` response
|
|
||||||
|
|
||||||
This proxy functionality allows the local cache server to act as a transparent proxy, automatically fetching and caching blobs from remote Blossom servers when needed.
|
|
||||||
|
|
||||||
## CORS Headers
|
|
||||||
|
|
||||||
The server MUST set the `Access-Control-Allow-Origin: *` header on all responses to ensure compatibility with web applications, as specified in [BUD-01](./01.md#cross-origin-headers).
|
|
||||||
|
|
||||||
## Use Cases
|
|
||||||
|
|
||||||
A local blob cache server enables several use cases:
|
|
||||||
|
|
||||||
- **Fast Local Access**: Applications can check the local cache first before making network requests to remote Blossom servers
|
|
||||||
- **Offline Access**: Previously cached blobs remain accessible even when network connectivity is unavailable
|
|
||||||
- **Bandwidth Savings**: Reduces redundant downloads of frequently accessed blobs
|
|
||||||
- **Development**: Provides a simple local server for testing Blossom applications without requiring remote server access
|
|
||||||
|
|
||||||
## Implementation Notes
|
|
||||||
|
|
||||||
- The server SHOULD implement efficient blob storage, such as using the sha256 hash as the filename or storage key
|
|
||||||
- The server SHOULD implement cache eviction policies (e.g., LRU, size-based limits) to manage storage
|
|
||||||
- The server SHOULD validate that downloaded blobs match their sha256 hash before caching
|
|
||||||
- The server MAY implement the `HEAD /<sha256>` endpoint to allow clients to check blob availability without downloading
|
|
||||||
|
|
||||||
## Example Implementation Flow
|
|
||||||
|
|
||||||
1. Client requests blob: `GET http://127.0.0.1:24242/<sha256>`
|
|
||||||
2. Server checks local cache
|
|
||||||
3. If found: Return blob immediately
|
|
||||||
4. If not found and proxy hints provided:
|
|
||||||
- Attempt to fetch from `xs` server hints
|
|
||||||
- If that fails, attempt to fetch using `as` author hints
|
|
||||||
- Cache the blob if successfully retrieved
|
|
||||||
- Return the blob to the client
|
|
||||||
5. If not found and no proxy hints: Return `404 Not Found`
|
|
||||||
|
|
||||||
68
buds/12.md
Normal file
68
buds/12.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# BUD-12
|
||||||
|
|
||||||
|
## Chunked blobs
|
||||||
|
|
||||||
|
`draft` `optional`
|
||||||
|
|
||||||
|
Breaking large blobs into smaller chunks for distribution
|
||||||
|
|
||||||
|
### Chunking
|
||||||
|
|
||||||
|
The client MAY break large blobs into any number or size of chunks. although its recommended to use the size `1Mb` or `4Mb` for small and large chunks
|
||||||
|
|
||||||
|
Clients MUST NOT pad the remaining chunk, If clients need privacy they should use random chunk sizes and optionally encrypt the large blob
|
||||||
|
|
||||||
|
### Publishing
|
||||||
|
|
||||||
|
Clients should publish a `2001` kind event after chunking the file in order to store the list of chunks
|
||||||
|
|
||||||
|
The events MUST contain an ordered list of `chunk` tags with the sha256 hashes of the chunks
|
||||||
|
|
||||||
|
The `content` field MUST be a human readable description of the chunked file
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tags": [
|
||||||
|
[ "chunk", "7e668b56a58c7891e0cf263ea3f093b75eebade23d663a45aa9920f347b3d671"],
|
||||||
|
[ "chunk", "9b9c44a91396f19fd8700986eb0586dff2dcccf96c75bc2caefef302bcd78da1"],
|
||||||
|
[ "chunk", "7a281548f1223664b855b10b08e59e84389ccabeb742517f6cd75eda2724a798"],
|
||||||
|
[ "chunk", "fadeccee86b123088bbc452df10e8fbc99d4c2f22a70ef7a35605ec8e439c345"],
|
||||||
|
[ "chunk", "5d62398419e6d136771541f3d2215e0ce31b1be45e99dbc64b43a4b734b447ca"],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Metadata
|
||||||
|
|
||||||
|
The `2001` event MAY include additional metadata tags to help other clients know the filename, mime type or servers to download from
|
||||||
|
|
||||||
|
Metadata tags:
|
||||||
|
- `name` Filename
|
||||||
|
- `mime` Mime type of file
|
||||||
|
- `size` Total size in bytes of the file
|
||||||
|
- `server` (multiple) Recommended servers to download chunks from
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
Example `2001` event
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pubkey": "5328e6c743a50271745e16476590ba7ea3dc591c65f3a5e2b03430814c1dabc0",
|
||||||
|
"created_at": 1731405194,
|
||||||
|
"kind": 2001,
|
||||||
|
"content": "Large zip archive of documents",
|
||||||
|
"tags": [
|
||||||
|
[ "chunk", "7e668b56a58c7891e0cf263ea3f093b75eebade23d663a45aa9920f347b3d671"],
|
||||||
|
[ "chunk", "9b9c44a91396f19fd8700986eb0586dff2dcccf96c75bc2caefef302bcd78da1"],
|
||||||
|
[ "chunk", "7a281548f1223664b855b10b08e59e84389ccabeb742517f6cd75eda2724a798"],
|
||||||
|
[ "chunk", "fadeccee86b123088bbc452df10e8fbc99d4c2f22a70ef7a35605ec8e439c345"],
|
||||||
|
[ "chunk", "5d62398419e6d136771541f3d2215e0ce31b1be45e99dbc64b43a4b734b447ca"],
|
||||||
|
[ "name", "example.mp4" ],
|
||||||
|
[ "mime", "video/mp4" ],
|
||||||
|
[ "size", "4823449" ],
|
||||||
|
[ "server", "https://cdn.example.com" ],
|
||||||
|
[ "server", "https://nostr.download" ]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Reference in New Issue
Block a user