mirror of
https://github.com/hzrd149/blossom.git
synced 2026-01-26 15:18:51 +00:00
Compare commits
1 Commits
local-cach
...
update-aut
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fbc2e05da |
16
README.md
16
README.md
@@ -1,6 +1,6 @@
|
||||
# 🌸 Blossom - Blobs stored simply on mediaservers
|
||||
|
||||
Blossom uses [nostr](https://github.com/nostr-protocol/nostr) public / private keys for identities. Users are expected to sign authorization events to prove their identity when interacting with servers
|
||||
Blossom uses [nostr](https://github.com/nostr-protocol/nostr) public / private keys for users identities.
|
||||
|
||||
## What is it?
|
||||
|
||||
@@ -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-09: Blob Report](./buds/09.md)
|
||||
- [BUD-10: Blossom URI Schema](./buds/10.md)
|
||||
- [BUD-11: Local Blob Cache](./buds/11.md)
|
||||
- [BUD-11: Nostr Authorization](./buds/11.md)
|
||||
|
||||
## Endpoints
|
||||
|
||||
@@ -36,26 +36,26 @@ Blossom Servers expose a few endpoints for managing blobs
|
||||
- `GET /<sha256>` (optional file `.ext`) [BUD-01](./buds/01.md#get-sha256---get-blob)
|
||||
- `HEAD /<sha256>` (optional file `.ext`) [BUD-01](./buds/01.md#head-sha256---has-blob)
|
||||
- `PUT /upload` [BUD-02](./buds/02.md#put-upload---upload-blob)
|
||||
- `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required)
|
||||
- `Authentication`: Signed [nostr event](./buds/11.md) (see [BUD-02](./buds/02.md#upload-authorization))
|
||||
- Return a blob descriptor
|
||||
- `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)_
|
||||
- Returns an array of blob descriptors
|
||||
- `Authentication` _(optional)_: Signed [nostr event](./buds/02.md#list-authorization-optional)
|
||||
- `Authentication` _(optional)_: Signed [nostr event](./buds/11.md) (see [BUD-02](./buds/02.md#list-authorization))
|
||||
- `DELETE /<sha256>` [BUD-02](./buds/02.md#delete-sha256---delete-blob)
|
||||
- `Authentication`: Signed [nostr event](./buds/02.md#delete-authorization-required)
|
||||
- `Authentication`: Signed [nostr event](./buds/11.md) (see [BUD-02](./buds/02.md#delete-authorization))
|
||||
- `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob)
|
||||
- `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required)
|
||||
- `Authentication`: Signed [nostr event](./buds/11.md) (see [BUD-02](./buds/02.md#upload-authorization))
|
||||
- `HEAD /media` [BUD-05](./buds/05.md#head-media)
|
||||
- `PUT /media` [BUD-05](./buds/05.md#put-media)
|
||||
- `Authentication`: Signed [nostr event](./buds/05.md#upload-authorization)
|
||||
- `Authentication`: Signed [nostr event](./buds/11.md) (see [BUD-05](./buds/05.md#upload-authorization))
|
||||
- `PUT /report` [BUD-09](./buds/09.md)
|
||||
|
||||
## Event kinds
|
||||
|
||||
| kind | description | BUD |
|
||||
| ------- | ------------------- | ------------------ |
|
||||
| `24242` | Authorization event | [01](./buds/01.md) |
|
||||
| `24242` | Authorization token | [11](./buds/11.md) |
|
||||
| `10063` | User Server List | [03](./buds/03.md) |
|
||||
|
||||
## License
|
||||
|
||||
59
buds/01.md
59
buds/01.md
@@ -20,55 +20,6 @@ The header `Access-Control-Max-Age: 86400` MAY be set to cache the results of a
|
||||
|
||||
Every time a server sends an error response (HTTP status codes >=400), it may include a human-readable header `X-Reason` that can be displayed to the user.
|
||||
|
||||
## Authorization events
|
||||
|
||||
Authorization events are used to identify the users to the server
|
||||
|
||||
Authorization events must be generic and must NOT be scoped to specific servers. This allows pubkeys to sign a single event and interact the same way with multiple servers.
|
||||
|
||||
Events MUST be kind `24242` and have a `t` tag with a verb of `get`, `upload`, `list`, or `delete`
|
||||
|
||||
Events MUST have the `content` set to a human readable string explaining to the user what the events intended use is. For example `Upload Blob`, `Delete dog-picture.png`, `List Images`, etc
|
||||
|
||||
All events MUST have a [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) `expiration` tag set to a unix timestamp at which the event should be considered expired.
|
||||
|
||||
Authorization events MAY have multiple `x` tags for endpoints that require a sha256 hash.
|
||||
|
||||
Example event:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb",
|
||||
"pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e",
|
||||
"kind": 24242,
|
||||
"content": "Upload bitcoin.pdf",
|
||||
"created_at": 1708773959,
|
||||
"tags": [
|
||||
["t", "upload"],
|
||||
// Authorization events MAY have multiple "x" tags.
|
||||
["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
|
||||
["expiration", "1708858680"]
|
||||
],
|
||||
"sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f"
|
||||
}
|
||||
```
|
||||
|
||||
Servers must perform the following checks in order to validate the event
|
||||
|
||||
1. The `kind` must be `24242`
|
||||
2. `created_at` must be in the past
|
||||
3. The `expiration` tag must be set to a Unix timestamp in the future
|
||||
4. The `t` tag must have a verb matching the intended action of the endpoint
|
||||
5. Additional checks for specific endpoints. `/upload`, `/delete`, etc
|
||||
|
||||
Using the `Authorization` HTTP header, the kind `24242` event MUST be base64 encoded and use the Authorization scheme Nostr
|
||||
|
||||
Example HTTP Authorization header:
|
||||
|
||||
```
|
||||
Authorization: Nostr eyJpZCI6IjhlY2JkY2RkNTMyOTIwMDEwNTUyNGExNDI4NzkxMzg4MWIzOWQxNDA5ZDhiOTBjY2RiNGI0M2Y4ZjBmYzlkMGMiLCJwdWJrZXkiOiI5ZjBjYzE3MDIzYjJjZjUwOWUwZjFkMzA1NzkzZDIwZTdjNzIyNzY5MjhmZDliZjg1NTM2ODg3YWM1NzBhMjgwIiwiY3JlYXRlZF9hdCI6MTcwODc3MTIyNywia2luZCI6MjQyNDIsInRhZ3MiOltbInQiLCJnZXQiXSxbImV4cGlyYXRpb24iLCIxNzA4ODU3NTQwIl1dLCJjb250ZW50IjoiR2V0IEJsb2JzIiwic2lnIjoiMDJmMGQyYWIyM2IwNDQ0NjI4NGIwNzFhOTVjOThjNjE2YjVlOGM3NWFmMDY2N2Y5NmNlMmIzMWM1M2UwN2I0MjFmOGVmYWRhYzZkOTBiYTc1NTFlMzA4NWJhN2M0ZjU2NzRmZWJkMTVlYjQ4NTFjZTM5MGI4MzI4MjJiNDcwZDIifQ==
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
All endpoints MUST be served from the root of the domain (eg. the `/upload` endpoint MUST be accessible from `https://cdn.example.com/upload`, etc). This allows clients to talk to servers interchangeably when uploading or retrieving blobs
|
||||
@@ -103,14 +54,14 @@ include a file extension in the URL that reflects the blob type (e.g. `.bin`, `.
|
||||
|
||||
The server may optionally require authorization when retrieving blobs from the `GET /<sha256>` endpoint
|
||||
|
||||
In this case, the server MUST perform additional checks on the authorization event
|
||||
In this case, the server MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then perform the following additional checks:
|
||||
|
||||
1. A `t` tag MUST be present and set to `get`
|
||||
2. The event MUST contain either a `server` tag containing the full URL to the server or MUST contain at least one `x` tag matching the sha256 hash of the blob being retrieved
|
||||
2. The authorization token MUST contain either a `server` tag (limiting the token to specific servers) or MUST contain at least one `x` tag matching the sha256 hash of the blob being retrieved (scoping the token to specific blob hashes). see [BUD-11](./11.md#tag-scoping).
|
||||
|
||||
If the client did not send an `Authorization` header the server must respond with the appropriate HTTP status code `401` (Unauthorized)
|
||||
|
||||
Example event for retrieving a single blob:
|
||||
Example authorization token for retrieving a single blob:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -128,7 +79,7 @@ Example event for retrieving a single blob:
|
||||
}
|
||||
```
|
||||
|
||||
Example event for retrieving multiple blobs from single server:
|
||||
Example authorization token for retrieving multiple blobs from single server:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -140,7 +91,7 @@ Example event for retrieving multiple blobs from single server:
|
||||
"tags": [
|
||||
["t", "get"],
|
||||
["expiration", "1708857340"],
|
||||
["server", "https://cdn.example.com/"]
|
||||
["server", "cdn.example.com"]
|
||||
],
|
||||
"sig": "e402ade78e1714d40cd6bd3091bc5f4ada8e904e90301b5a2b9b5f0b6e95ce908d4f22b15e9fb86f8268a2131f8adbb3d1f0e7e7afd1ab0f4f08acb15822a999"
|
||||
}
|
||||
|
||||
28
buds/02.md
28
buds/02.md
@@ -53,12 +53,12 @@ servers may rely on the file extension to serve the blob correctly.
|
||||
|
||||
### Upload Authorization (Optional)
|
||||
|
||||
Servers MAY accept an authorization event when uploading blobs and SHOULD perform additional checks
|
||||
Servers MAY require an authorization token when uploading blobs. The server MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then perform the following additional checks:
|
||||
|
||||
1. The `t` tag MUST be set to `upload`
|
||||
2. The authorization event MUST contain at least one `x` tag matching the sha256 hash of the body of the request
|
||||
2. The authorization token MUST contain at least one `x` tag matching the sha256 hash of the body of the request. The `x` tag scopes the token to specific blob hashes (see [BUD-11](./11.md#tag-scoping)).
|
||||
|
||||
Example Authorization event:
|
||||
Example authorization token:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -88,15 +88,13 @@ The endpoint MAY support `since` and `until` query parameters to filter the list
|
||||
|
||||
Servers MAY reject a list request for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
||||
|
||||
### List Authorization (optional)
|
||||
### List Authorization
|
||||
|
||||
The server MAY optionally require Authorization when listing blobs uploaded by the pubkey
|
||||
|
||||
In this case the server MUST perform additional checks on the authorization event
|
||||
The server MAY require a `list` authorization token when listing blobs uploaded by the pubkey. If a server requires authorization it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then it MUST perform the following additional checks:
|
||||
|
||||
1. The `t` tag MUST be set to `list`
|
||||
|
||||
Example Authorization event:
|
||||
Example authorization token:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -119,20 +117,16 @@ Servers MUST accept `DELETE` requests to the `/<sha256>` endpoint
|
||||
|
||||
Servers MAY reject a delete request for any reason and SHOULD respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
||||
|
||||
### Delete Authorization (required)
|
||||
### Delete Authorization
|
||||
|
||||
Servers MUST accept an authorization event when deleting blobs
|
||||
|
||||
Servers SHOULD perform additional checks on the authorization event
|
||||
Servers MAY require a `delete` authorization token when deleting blobs. If a server requires authorization it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then MUST perform the following additional checks:
|
||||
|
||||
1. The `t` tag MUST be set to `delete`
|
||||
2. The authorization event MUST contain at least one `x` tag matching the sha256 hash of the blob being deleted
|
||||
2. MUST contain at least one `x` tag matching the sha256 hash of the blob being deleted.
|
||||
|
||||
When multiple `x` tags are present on the authorization event the server MUST only delete the blob listed in the URL.
|
||||
**Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to delete multiple blobs.**
|
||||
|
||||
**Multiple `x` tags MUST NOT be interpreted as the user requesting a bulk delete.**
|
||||
|
||||
Example Authorization event:
|
||||
Example authorization token:
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
21
buds/04.md
21
buds/04.md
@@ -19,12 +19,6 @@ Clients MUST pass the URL of the remote blob as a stringified JSON object in the
|
||||
}
|
||||
```
|
||||
|
||||
Clients MAY set the `Authorization` header to an upload authorization event defined in [BUD-02](./02.md#upload-authorization-optional). When using authorization, the event MUST be of type "upload".
|
||||
|
||||
The `/mirror` endpoint MUST download the blob from the specified URL and verify that there is at least one `x` tag in the authorization event matching the sha256 hash of the download blob
|
||||
|
||||
**Multiple `x` tags in the authorization event MUST NOT be interpreted as the user requesting to mirror multiple blobs.**
|
||||
|
||||
The endpoint MUST return a [Blob Descriptor](#blob-descriptor) and a `2xx` status code if the mirroring was successful
|
||||
or a `4xx` status code and error message if it was not.
|
||||
|
||||
@@ -36,11 +30,20 @@ Servers MAY use the `Content-Length` header to determine the size of the blob.
|
||||
|
||||
Servers MAY reject a mirror request for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection.
|
||||
|
||||
### Upload Authorization
|
||||
|
||||
Servers MAY require an `upload` authorization token when mirroring blobs. The server MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then MUST perform the following additional checks:
|
||||
|
||||
1. The `t` tag MUST be set to `upload`
|
||||
2. The authorization token MUST contain at least one `x` tag matching the sha256 hash of the downloaded blob. The `x` tag scopes the token to specific blob hashes (see [BUD-11](./11.md#tag-scoping)).
|
||||
|
||||
**Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to mirror multiple blobs.**
|
||||
|
||||
## Example Flow
|
||||
|
||||
1. Client signs an `upload` authorization event and uploads blob to Server A
|
||||
1. Client signs an `upload` authorization token and uploads blob to Server A
|
||||
1. Server A returns a [Blob Descriptor](./02.md#blob-descriptor) with the `url`
|
||||
1. Client sends the `url` to Server B `/mirror` using the original `upload` authorization event
|
||||
1. Client sends the `url` to Server B `/mirror` using the original `upload` authorization token
|
||||
1. Server B downloads the blob from Server A using the `url`
|
||||
1. Server B verifies the downloaded blob hash matches the `x` tag in the authorization event
|
||||
1. Server B verifies the downloaded blob hash matches the `x` tag in the authorization token
|
||||
1. Server B returns a [Blob Descriptor](./02.md#blob-descriptor)
|
||||
|
||||
@@ -18,12 +18,10 @@ Servers MAY reject media uploads for any reason and should respond with the appr
|
||||
|
||||
### Upload Authorization
|
||||
|
||||
Servers MAY require a `media` [authorization event](./02.md#upload-authorization-required) to identify the uploader
|
||||
|
||||
If a server requires a `media` authorization event it MUST perform the following checks
|
||||
Servers MAY require a `media` authorization token to identify the uploader. If a server requires a `media` authorization token it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then MUST perform the following additional checks:
|
||||
|
||||
1. The `t` tag MUST be set to `media`
|
||||
2. MUST contain at least one `x` tag matching the sha256 hash of the body of the request
|
||||
2. The authorization token MUST contain at least one `x` tag matching the sha256 hash of the body of the request.
|
||||
|
||||
## HEAD /media
|
||||
|
||||
@@ -45,4 +43,4 @@ Clients MAY let a user selected a "trusted processing" server for uploading imag
|
||||
|
||||
Once a server has been selected, the client uploads the original media to the `/media` endpoint of the trusted server and get the optimized blob back
|
||||
|
||||
Then the client can ask the user to sign another `upload` authorization event for the new optimized blob and call the `/mirror` endpoint on other servers to distribute the blob
|
||||
Then the client can ask the user to sign another `upload` authorization token for the new optimized blob and call the `/mirror` endpoint on other servers to distribute the blob
|
||||
|
||||
@@ -18,7 +18,7 @@ The `HEAD /upload` endpoint MUST use the `X-SHA-256`, `X-Content-Type` and `X-Co
|
||||
|
||||
### Upload Authorization
|
||||
|
||||
The `HEAD /upload` endpoint MAY accept an `upload` authorization event using the `Authorization` header similar to what is used in the [`PUT /upload`](./02.md#upload-authorization-required) endpoint
|
||||
The `HEAD /upload` endpoint MAY accept an `upload` authorization token using the `Authorization` header similar to what is used in the [`PUT /upload`](./02.md#upload-authorization) endpoint
|
||||
|
||||
If the server requires authorization to upload it may respond with the `401` status code, or if authorization was provided and is invalid or not permitted it may respond with `403` status code
|
||||
|
||||
|
||||
132
buds/11.md
132
buds/11.md
@@ -1,107 +1,77 @@
|
||||
# BUD-11
|
||||
|
||||
## Local Blob Cache
|
||||
## Nostr Authorization
|
||||
|
||||
`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.
|
||||
Defines the authorization token format used by blossom servers to identify users. Authorization tokens are optional and servers MAY require them for various endpoints.
|
||||
|
||||
## Server Address
|
||||
## Authorization tokens
|
||||
|
||||
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.
|
||||
Authorization tokens are signed nostr events proving to a server that the user (`pubkey`) has permitted an application to take an action on their behalf.
|
||||
|
||||
## Health Check Endpoint
|
||||
The authorization token MUST be a nostr event of kind `24242` and have a `t` tag with a verb of `get`, `upload`, `list`, `delete`, or `media`
|
||||
|
||||
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.
|
||||
Authorization tokens MUST have the `content` set to a human readable string explaining intended use. For example `Upload Blob`, `Delete old blobs`, `List Images`, etc
|
||||
|
||||
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).
|
||||
All authorization tokens MUST have a [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) `expiration` tag set to a unix timestamp at which the token should be considered expired.
|
||||
|
||||
This endpoint enables simple health checks:
|
||||
## Tag scoping
|
||||
|
||||
```bash
|
||||
curl -I http://127.0.0.1:24242/
|
||||
Authorization tokens MAY include `server` and `x` tags to scope the token to specific servers or blob hashes.
|
||||
|
||||
- **`server` tag**: Limits the token to specific servers by domain name. If no `server` tags are present, the token is valid for all servers. Multiple `server` tags may be present to allow the token to be used on multiple servers. The value MUST be a domain name only (e.g., `cdn.example.com`), not a full URL.
|
||||
|
||||
- **`x` tag**: Scopes the token to specific blob hashes (similar to how `server` scopes to servers). Multiple `x` tags may be present for endpoints that require a sha256 hash. When `x` tags are present, the token is only valid for operations on the specified blob hashes.
|
||||
|
||||
Example authorization token:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb",
|
||||
"pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e",
|
||||
"kind": 24242,
|
||||
"content": "Upload bitcoin.pdf",
|
||||
"created_at": 1708773959,
|
||||
"tags": [
|
||||
["t", "upload"],
|
||||
// Authorization tokens MAY have multiple "x" tags.
|
||||
["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"],
|
||||
["expiration", "1708858680"]
|
||||
],
|
||||
"sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f"
|
||||
}
|
||||
```
|
||||
|
||||
## Access Control
|
||||
## Base validation
|
||||
|
||||
The server SHOULD NOT require any authentication for blob downloads or uploads. All requests MUST be served without requiring an `Authorization` header.
|
||||
Servers must perform the following checks in order to validate the authorization token
|
||||
|
||||
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.
|
||||
1. The `kind` must be `24242`
|
||||
2. `created_at` must be in the past
|
||||
3. The `expiration` tag must be set to a Unix timestamp in the future
|
||||
4. The `t` tag must have a verb matching the intended action of the endpoint
|
||||
5. If `server` tags are present, the server MUST verify that its domain name is present in at least one `server` tag. If no `server` tags are present, the token is valid for all servers.
|
||||
|
||||
## Blob Retrieval
|
||||
## HTTP Authorization header
|
||||
|
||||
The server MUST implement the `GET /<sha256>` and `HEAD /<sha256>` endpoints as defined in [BUD-01](./01.md#get-sha256---get-blob):
|
||||
Using the `Authorization` HTTP header, the authorization token (kind `24242`) MUST be base64 encoded and use the Authorization scheme Nostr
|
||||
|
||||
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
|
||||
Example HTTP Authorization header:
|
||||
|
||||
```
|
||||
GET /b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf?xs=cdn.example.com&as=ec4425ff5e9446080d2f70440188e3ca5d6da8713db7bdeef73d0ed54d9093f0
|
||||
Authorization: Nostr eyJpZCI6IjhlY2JkY2RkNTMyOTIwMDEwNTUyNGExNDI4NzkxMzg4MWIzOWQxNDA5ZDhiOTBjY2RiNGI0M2Y4ZjBmYzlkMGMiLCJwdWJrZXkiOiI5ZjBjYzE3MDIzYjJjZjUwOWUwZjFkMzA1NzkzZDIwZTdjNzIyNzY5MjhmZDliZjg1NTM2ODg3YWM1NzBhMjgwIiwiY3JlYXRlZF9hdCI6MTcwODc3MTIyNywia2luZCI6MjQyNDIsInRhZ3MiOltbInQiLCJnZXQiXSxbImV4cGlyYXRpb24iLCIxNzA4ODU3NTQwIl1dLCJjb250ZW50IjoiR2V0IEJsb2JzIiwic2lnIjoiMDJmMGQyYWIyM2IwNDQ0NjI4NGIwNzFhOTVjOThjNjE2YjVlOGM3NWFmMDY2N2Y5NmNlMmIzMWM1M2UwN2I0MjFmOGVmYWRhYzZkOTBiYTc1NTFlMzA4NWJhN2M0ZjU2NzRmZWJkMTVlYjQ4NTFjZTM5MGI4MzI4MjJiNDcwZDIifQ==
|
||||
```
|
||||
|
||||
### Proxy Behavior
|
||||
## Endpoint-specific requirements (example)
|
||||
|
||||
When the server receives a request with proxy hints and the blob is not in the local cache:
|
||||
Individual endpoints may extend the base validation with additional requirements. The following are examples of how endpoints use authorization tokens:
|
||||
|
||||
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`
|
||||
- **`/upload`** ([BUD-02](./02.md#upload-authorization)): May requires at least one `x` tag matching the sha256 hash of the blob being uploaded
|
||||
- **`DELETE /<sha256>`** ([BUD-02](./02.md#delete-authorization)): May requires at least one `x` tag matching the sha256 hash of the blob being deleted
|
||||
- **`PUT /media`** ([BUD-05](./05.md#upload-authorization)): May requires at least one `x` tag matching the sha256 hash of the media being uploaded
|
||||
- **`GET /<sha256>`** ([BUD-01](./01.md#get-authorization)): May require either a `server` tag or at least one `x` tag matching the sha256 hash of the blob being retrieved
|
||||
- **`GET /list/<pubkey>`** ([BUD-02](./02.md#list-authorization)): May require a `server` tag limiting the token to specific servers
|
||||
- **`PUT /mirror`** ([BUD-04](./04.md#put-mirror---mirror-blob)): May requires at least one `x` tag matching the sha256 hash of the blob being mirrored
|
||||
|
||||
See the respective BUD documents for the exact requirements for each endpoint. All endpoints that accept authorization tokens MUST perform the base validation checks defined above before performing any endpoint-specific checks.
|
||||
|
||||
Reference in New Issue
Block a user