mirror of
https://github.com/hzrd149/blossom.git
synced 2026-10-05 15:38:22 +00:00
Add BUD-13 path-based upload endpoint
This commit is contained in:
@@ -22,13 +22,14 @@ BUDs or **Blossom Upgrade Documents** are short documents that outline an additi
|
||||
- [BUD-03: User Server List](./buds/03.md)
|
||||
- [BUD-04: Mirroring blobs](./buds/04.md)
|
||||
- [BUD-05: Media optimization](./buds/05.md)
|
||||
- [BUD-06: Upload requirements](./buds/06.md) _(moved to [BUD-02](./buds/02.md#head-upload---upload-requirements-optional))_
|
||||
- [BUD-06: Upload requirements](./buds/06.md)
|
||||
- [BUD-07: Payment required](./buds/07.md)
|
||||
- [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: Nostr Authorization](./buds/11.md)
|
||||
- [BUD-12: Blob management endpoints](./buds/12.md)
|
||||
- [BUD-13: Path-based blob upload](./buds/13.md)
|
||||
|
||||
## Endpoints
|
||||
|
||||
@@ -36,8 +37,8 @@ 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)
|
||||
- `HEAD /upload` [BUD-02](./buds/02.md#head-upload---upload-requirements-optional)
|
||||
- `PUT /<sha256>` [BUD-13](./buds/13.md#put-sha256---upload-blob)
|
||||
- `HEAD /upload` [BUD-06](./buds/06.md#head-upload---upload-requirements-optional)
|
||||
- `GET /list/<pubkey>` [BUD-12](./buds/12.md#get-listpubkey---list-blobs-unrecommended) _(unrecommended)_
|
||||
- `DELETE /<sha256>` [BUD-12](./buds/12.md#delete-sha256---delete-blob)
|
||||
- `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob)
|
||||
|
||||
+1
-71
@@ -6,7 +6,7 @@
|
||||
|
||||
_All pubkeys MUST be in hex format_
|
||||
|
||||
Defines the `HEAD /upload` and `PUT /upload` endpoints.
|
||||
Defines the `PUT /upload` endpoint.
|
||||
|
||||
The `/list/<pubkey>` and `DELETE /<sha256>` endpoints are defined in [BUD-12](./12.md).
|
||||
|
||||
@@ -71,73 +71,3 @@ If included, `X-Reason` MUST be treated as a human readable diagnostic message o
|
||||
### File extension normalization (Optional)
|
||||
|
||||
When storing blobs, servers MAY normalise the file extension to a standard format (e.g. `.pdf`, `.png`, etc.) based on the MIME type of the blob. This can be especially useful when the `GET /<sha256>` endpoint is redirected to an external URL (see the [proxying and redirection section from BUD-01](./01.md#proxying-and-redirection-optional)), as external servers may rely on the file extension to serve the blob correctly.
|
||||
|
||||
## HEAD /upload - Upload requirements (Optional)
|
||||
|
||||
Servers MAY implement `HEAD /upload` as an optimization step before `PUT /upload`.
|
||||
Clients can use it to avoid uploading blobs that would be rejected, and servers can use it to evaluate whether an upload attempt would be accepted based on the supplied metadata and current server policy.
|
||||
|
||||
This pre-flight request is only an optimization. Clients MAY skip it entirely, and the result is not a guarantee of the eventual `PUT /upload` outcome because server state may change between requests.
|
||||
|
||||
Clients that want to check whether a blob already exists on the server SHOULD use [`HEAD /<sha256>` from BUD-01](./01.md#head-sha256---has-blob).
|
||||
|
||||
The `HEAD /upload` endpoint MUST use the `X-SHA-256`, `X-Content-Type` and `X-Content-Length` headers sent by client to get the sha256 hash, MIME type and size of the blob that will be uploaded, returning an HTTP status code and an optional custom header `X-Reason` to indicate a human readable message about the upload requirements. Because `HEAD` responses do not include a message body, clients MUST determine the result from the status code and response headers alone.
|
||||
|
||||
### Headers
|
||||
|
||||
- `X-SHA-256`: A lowercase hex-encoded sha256 string that represents the blob's hash.
|
||||
- `X-Content-Length`: An integer that represents the blob size in bytes.
|
||||
- `X-Content-Type`: A string that specifies the blob's MIME type, like `application/pdf` or `image/png`.
|
||||
|
||||
### Status codes
|
||||
|
||||
Servers SHOULD use the following status codes for `HEAD /upload` responses:
|
||||
|
||||
| Status Code | Meaning |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `200 OK` | Based on the supplied headers and current server policy, the upload would be accepted and the client MAY proceed with `PUT /upload`. |
|
||||
| `400 Bad Request` | The request headers are malformed. |
|
||||
| `401 Unauthorized` | Authorization is required and missing or invalid. See [BUD-11](./11.md#endpoint-authorization-requirements). |
|
||||
| `402 Payment Required` | Payment is required before the upload can proceed. See [BUD-07](./07.md). |
|
||||
| `403 Forbidden` | The request is understood but not allowed by server policy. |
|
||||
| `411 Length Required` | A required `X-Content-Length` header is missing. |
|
||||
| `413 Content Too Large` | The blob would exceed server size limits. |
|
||||
| `415 Unsupported Media Type` | The blob type is not supported. |
|
||||
| `429 Too Many Requests` | The client has exceeded a rate limit or quota. |
|
||||
| `503 Service Unavailable` | The upload service is temporarily unavailable. |
|
||||
|
||||
If included, `X-Reason` MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow.
|
||||
|
||||
Clients that do not implement this optimization may still perform `PUT /upload` directly, and servers MUST handle that correctly.
|
||||
|
||||
After receiving `200 OK` from `HEAD /upload`, clients MUST still be prepared for `PUT /upload` to return either `200 OK` or `201 Created`, depending on whether the blob already existed when the upload was processed.
|
||||
|
||||
### Examples
|
||||
|
||||
Example request from the client:
|
||||
|
||||
```http
|
||||
X-Content-Type: application/pdf
|
||||
X-Content-Length: 184292
|
||||
X-SHA-256: 88a74d0b866c8ba79251a11fe5ac807839226870e77355f02eaf68b156522576
|
||||
```
|
||||
|
||||
Example response from the server if the upload may proceed:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
```
|
||||
|
||||
If the upload cannot proceed, the server SHOULD return one of the status codes defined above. The server MAY include `X-Reason` with a human readable error message.
|
||||
|
||||
Some examples of error messages:
|
||||
|
||||
```http
|
||||
HTTP/1.1 400 Bad Request
|
||||
X-Reason: Invalid X-SHA-256 header format. Expected a string.
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 413 Content Too Large
|
||||
X-Reason: File too large. Max allowed size is 100MB.
|
||||
```
|
||||
|
||||
+71
-1
@@ -4,6 +4,76 @@
|
||||
|
||||
`draft` `optional`
|
||||
|
||||
The `HEAD /upload` endpoint definition has been merged into [BUD-02](./02.md#head-upload---upload-requirements-optional) so it lives next to `PUT /upload`.
|
||||
Defines the `HEAD /upload` endpoint.
|
||||
|
||||
This optional preflight endpoint remains intended as an optimization so clients and servers can avoid uploading blobs that would be rejected or that already exist.
|
||||
|
||||
## HEAD /upload - Upload requirements (Optional)
|
||||
|
||||
Servers MAY implement `HEAD /upload` as an optimization step before `PUT /upload` or `PUT /<sha256>`.
|
||||
Clients can use it to avoid uploading blobs that would be rejected, and servers can use it to evaluate whether an upload attempt would be accepted based on the supplied metadata and current server policy.
|
||||
|
||||
This pre-flight request is only an optimization. Clients MAY skip it entirely, and the result is not a guarantee of the eventual upload outcome because server state may change between requests.
|
||||
|
||||
Clients that want to check whether a blob already exists on the server SHOULD use [`HEAD /<sha256>` from BUD-01](./01.md#head-sha256---has-blob).
|
||||
|
||||
The `HEAD /upload` endpoint MUST use the `X-SHA-256`, `X-Content-Type` and `X-Content-Length` headers sent by client to get the sha256 hash, MIME type and size of the blob that will be uploaded, returning an HTTP status code and an optional custom header `X-Reason` to indicate a human readable message about the upload requirements. Because `HEAD` responses do not include a message body, clients MUST determine the result from the status code and response headers alone.
|
||||
|
||||
### Headers
|
||||
|
||||
- `X-SHA-256`: A lowercase hex-encoded sha256 string that represents the blob's hash.
|
||||
- `X-Content-Length`: An integer that represents the blob size in bytes.
|
||||
- `X-Content-Type`: A string that specifies the blob's MIME type, like `application/pdf` or `image/png`.
|
||||
|
||||
### Status codes
|
||||
|
||||
Servers SHOULD use the following status codes for `HEAD /upload` responses:
|
||||
|
||||
| Status Code | Meaning |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `200 OK` | Based on the supplied headers and current server policy, the upload would be accepted and the client MAY proceed with `PUT /upload` or `PUT /<sha256>`. |
|
||||
| `400 Bad Request` | The request headers are malformed. |
|
||||
| `401 Unauthorized` | Authorization is required and missing or invalid. See [BUD-11](./11.md#endpoint-authorization-requirements). |
|
||||
| `402 Payment Required` | Payment is required before the upload can proceed. See [BUD-07](./07.md). |
|
||||
| `403 Forbidden` | The request is understood but not allowed by server policy. |
|
||||
| `411 Length Required` | A required `X-Content-Length` header is missing. |
|
||||
| `413 Content Too Large` | The blob would exceed server size limits. |
|
||||
| `415 Unsupported Media Type` | The blob type is not supported. |
|
||||
| `429 Too Many Requests` | The client has exceeded a rate limit or quota. |
|
||||
| `503 Service Unavailable` | The upload service is temporarily unavailable. |
|
||||
|
||||
If included, `X-Reason` MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow.
|
||||
|
||||
Clients that do not implement this optimization may still perform `PUT /upload` or `PUT /<sha256>` directly, and servers MUST handle that correctly.
|
||||
|
||||
After receiving `200 OK` from `HEAD /upload`, clients MUST still be prepared for the upload request to return either `200 OK` or `201 Created`, depending on whether the blob already existed when the upload was processed.
|
||||
|
||||
### Examples
|
||||
|
||||
Example request from the client:
|
||||
|
||||
```http
|
||||
X-Content-Type: application/pdf
|
||||
X-Content-Length: 184292
|
||||
X-SHA-256: 88a74d0b866c8ba79251a11fe5ac807839226870e77355f02eaf68b156522576
|
||||
```
|
||||
|
||||
Example response from the server if the upload may proceed:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
```
|
||||
|
||||
If the upload cannot proceed, the server SHOULD return one of the status codes defined above. The server MAY include `X-Reason` with a human readable error message.
|
||||
|
||||
Some examples of error messages:
|
||||
|
||||
```http
|
||||
HTTP/1.1 400 Bad Request
|
||||
X-Reason: Invalid X-SHA-256 header format. Expected a string.
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 413 Content Too Large
|
||||
X-Reason: File too large. Max allowed size is 100MB.
|
||||
```
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ Some servers MAY require payment for uploads, downloads, or any other endpoint.
|
||||
|
||||
Some endpoints a server may require payment for:
|
||||
|
||||
- [`HEAD /upload`](./02.md#head-upload---upload-requirements-optional) to signal that payment is required for the `PUT` request ( if that optional endpoint is supported )
|
||||
- [`PUT /upload`](./02.md#put-upload---upload-blob) to require payment for uploads
|
||||
- [`HEAD /upload`](./06.md#head-upload---upload-requirements-optional) to signal that payment is required for the `PUT /<sha256>` request ( if that optional endpoint is supported )
|
||||
- [`PUT /<sha256>`](./13.md#put-sha256---upload-blob) to require payment for uploads
|
||||
- [`HEAD /<sha256>`](./01.md#head-sha256---has-blob) to signal that payment is required for the `GET` request
|
||||
- [`GET /<sha256>`](./01.md#get-sha256---get-blob) to require payment for downloads ( maybe charge by MB downloaded? )
|
||||
- [`HEAD /media`](./05.md) and [`PUT /media`](./05.md) to require payment for media optimizations ( if the optional `HEAD /media`-style preflight is supported )
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@
|
||||
|
||||
`draft` `optional`
|
||||
|
||||
Describes how a server could return nostr [NIP-94 File Metadata](https://github.com/nostr-protocol/nips/blob/master/94.md) tags from the `/upload` and `/mirror` endpoints
|
||||
Describes how a server could return nostr [NIP-94 File Metadata](https://github.com/nostr-protocol/nips/blob/master/94.md) tags from the `PUT /<sha256>` and `/mirror` endpoints
|
||||
|
||||
### Returning tags
|
||||
|
||||
As described in [BUD-02](./02.md#blob-descriptor) servers MAY add any additional fields to a blob descriptor
|
||||
|
||||
Servers MAY return an additional `nip94` field in the [blob descriptor](./02.md#blob-descriptor) from the `/upload` or `/mirror` endpoints
|
||||
Servers MAY return an additional `nip94` field in the [blob descriptor](./02.md#blob-descriptor) from the `PUT /<sha256>` or `/mirror` endpoints
|
||||
|
||||
The `nip94` field should contain a JSON array with KV pairs as defined in [NIP-94](https://github.com/nostr-protocol/nips/blob/master/94.md)
|
||||
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ The table below defines, for each endpoint, the required `t` tag action, the imp
|
||||
| -------------------- | ------------ | ---------------------------- | ------------------- |
|
||||
| `GET /<sha256>` | `get` | `<sha256>` from the URL | optional |
|
||||
| `HEAD /<sha256>` | `get` | `<sha256>` from the URL | optional |
|
||||
| `PUT /upload` | `upload` | `X-SHA-256` request header | required |
|
||||
| `PUT /<sha256>` | `upload` | `<sha256>` from the URL | required |
|
||||
| `HEAD /upload` | `upload` | `X-SHA-256` request header | required |
|
||||
| `DELETE /<sha256>` | `delete` | `<sha256>` from the URL | required |
|
||||
| `GET /list/<pubkey>` | `list` | — | not applicable |
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
# BUD-13
|
||||
|
||||
## Path-based blob upload
|
||||
|
||||
`draft` `optional`
|
||||
|
||||
_All pubkeys MUST be in hex format_
|
||||
|
||||
This document supersedes the `PUT /upload` endpoint definition from [BUD-02](./02.md).
|
||||
|
||||
Servers that implement this document MAY continue to support the `PUT /upload` endpoint from [BUD-02](./02.md) for compatibility.
|
||||
|
||||
Defines the `PUT /<sha256>` endpoint.
|
||||
|
||||
The [Blob Descriptor](./02.md#blob-descriptor) type is defined in [BUD-02](./02.md).
|
||||
|
||||
## PUT /sha256 - Upload Blob
|
||||
|
||||
The `PUT /<sha256>` endpoint MUST accept binary data in the request body.
|
||||
The `<sha256>` path segment MUST be a lowercase hex-encoded sha256 hash of the request body.
|
||||
|
||||
The server MUST NOT modify the blob in any way and MUST compute the sha256 hash over the exact bytes received. This requirement ensures that users can re-upload blobs to other servers without discrepancies.
|
||||
|
||||
Clients SHOULD include `Content-Type` and `Content-Length` headers specifying the MIME type and size of the data.
|
||||
|
||||
If the computed sha256 of the request body does not match the `<sha256>` path segment, the server MUST reject the request with `409 Conflict` and MUST NOT persist the blob.
|
||||
|
||||
If the blob was newly stored, the endpoint MUST respond with `201 Created` and a [Blob Descriptor](./02.md#blob-descriptor) in the response body.
|
||||
If the blob already exists, the endpoint MUST respond with `200 OK` and a [Blob Descriptor](./02.md#blob-descriptor) in the response body.
|
||||
|
||||
Servers MUST handle uploads correctly regardless of whether the client performed a `HEAD /upload` request first.
|
||||
|
||||
### Status codes
|
||||
|
||||
Servers SHOULD use the following status codes for `PUT /<sha256>` responses:
|
||||
|
||||
| Status Code | Meaning |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `200 OK` | The blob already exists and the server is returning the existing [Blob Descriptor](./02.md#blob-descriptor). |
|
||||
| `201 Created` | The blob was stored successfully and the server is returning its [Blob Descriptor](./02.md#blob-descriptor). |
|
||||
| `400 Bad Request` | The sha256 path, request headers, or body are malformed. |
|
||||
| `401 Unauthorized` | Authorization is required and missing or invalid. See [BUD-11](./11.md#endpoint-authorization-requirements). |
|
||||
| `402 Payment Required` | Payment is required before the upload can proceed. See [BUD-07](./07.md). |
|
||||
| `403 Forbidden` | The request is understood but not allowed by server policy. |
|
||||
| `409 Conflict` | The sha256 from the URL does not match the request body. |
|
||||
| `411 Length Required` | A required `Content-Length` header is missing. |
|
||||
| `413 Content Too Large` | The blob exceeds server size limits. |
|
||||
| `415 Unsupported Media Type` | The blob type is not supported. |
|
||||
| `429 Too Many Requests` | The client has exceeded a rate limit or quota. |
|
||||
|
||||
If included, `X-Reason` MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow.
|
||||
|
||||
### File extension normalization (Optional)
|
||||
|
||||
When storing blobs, servers MAY normalise the file extension to a standard format (e.g. `.pdf`, `.png`, etc.) based on the MIME type of the blob. This can be especially useful when the `GET /<sha256>` endpoint is redirected to an external URL (see the [proxying and redirection section from BUD-01](./01.md#proxying-and-redirection-optional)), as external servers may rely on the file extension to serve the blob correctly.
|
||||
|
||||
## Pre-flight upload acceptance checks
|
||||
|
||||
Clients MAY use [`HEAD /upload` from BUD-06](./06.md#head-upload---upload-requirements-optional) as an optimization step before `PUT /<sha256>`.
|
||||
|
||||
Servers that implement `PUT /<sha256>` SHOULD preserve the existing `HEAD /upload` semantics from [BUD-06](./06.md#head-upload---upload-requirements-optional) so clients can continue checking whether an upload would be accepted before sending the request body.
|
||||
|
||||
This pre-flight request is only an optimization. Clients MAY skip it entirely, and the result is not a guarantee of the eventual `PUT /<sha256>` outcome because server state may change between requests.
|
||||
|
||||
Clients that want to check whether a blob already exists on the server SHOULD use [`HEAD /<sha256>` from BUD-01](./01.md#head-sha256---has-blob).
|
||||
|
||||
## HTTP 100 Continue (Optional)
|
||||
|
||||
Clients MAY use the HTTP `Expect: 100-continue` mechanism with `PUT /<sha256>` to allow a server or intermediary to reject an upload before the request body is sent.
|
||||
|
||||
Servers MAY support this optimization, but clients MUST NOT rely on it because support varies across server frameworks, reverse proxies, and intermediaries.
|
||||
|
||||
Clients that need a portable and explicit pre-flight mechanism SHOULD use `HEAD /upload`.
|
||||
@@ -68,7 +68,7 @@ The server SHOULD set the `Content-Type` header appropriately:
|
||||
|
||||
When generating HLS playlists for Blossom:
|
||||
|
||||
1. Upload each media segment as a separate blob using [BUD-02](../buds/02.md#put-upload---upload-blob) `PUT /upload`
|
||||
1. Upload each media segment as a separate blob using [BUD-13](../buds/13.md#put-sha256---upload-blob) `PUT /<sha256>`
|
||||
2. Upload each variant playlist as a separate blob
|
||||
3. Upload the master playlist as a separate blob
|
||||
4. In all playlists, use relative paths containing only the SHA256 hash (and optional file extension) of the referenced blob
|
||||
|
||||
Reference in New Issue
Block a user