From 5d92ee621f6d97d5d46c4678ce9ded5199ff19d1 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Mon, 6 Apr 2026 11:18:28 -0500 Subject: [PATCH 1/7] Make HTTP great again Add specific status codes to endpoints for clarity --- buds/01.md | 38 +++++++++++++++++-- buds/02.md | 108 +++++++++++++++++++++++++++++++++++++++++++---------- buds/05.md | 42 +++++++++++++++++++-- buds/06.md | 66 +------------------------------- buds/07.md | 14 +++---- buds/11.md | 6 +-- buds/12.md | 60 +++++++++++++++++++++++++++++ 7 files changed, 232 insertions(+), 102 deletions(-) create mode 100644 buds/12.md diff --git a/buds/01.md b/buds/01.md index 77851fb..76fbe76 100644 --- a/buds/01.md +++ b/buds/01.md @@ -46,12 +46,26 @@ guarantee this are: 1. Proxying the blob through the Blossom server, allowing it to override headers such as `Content-Type`. 2. Manipulating the redirect URL to include a file extension that matches the blob type, such as `.pdf`, `.png`, etc. If -the server is unable to determine the MIME type of the blob, it MUST default to `application/octet-stream` and MAY -include a file extension in the URL that reflects the blob type (e.g. `.bin`, `.dat`, etc.). + the server is unable to determine the MIME type of the blob, it MUST default to `application/octet-stream` and MAY + include a file extension in the URL that reflects the blob type (e.g. `.bin`, `.dat`, etc.). -### Get Authorization (optional) +### Status codes -Servers MAY require authorization when retrieving blobs, as defined by [BUD-11](./11.md#endpoint-authorization-requirements). +Servers SHOULD use the following status codes for `GET /` responses: + +| Status Code | Meaning | +| --------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `200 OK` | The blob exists and is returned in the response body. | +| `206 Partial Content` | The blob exists and the server is fulfilling a valid `Range` request. | +| `307 Temporary Redirect` | The blob is temporarily available from another URL containing the same sha256. | +| `308 Permanent Redirect` | The blob is permanently available from another URL containing the same sha256. | +| `400 Bad Request` | The sha256 path, optional file extension, or request headers are malformed. | +| `401 Unauthorized` | Authorization is required and missing or invalid. See [BUD-11](./11.md#endpoint-authorization-requirements). | +| `403 Forbidden` | The request is understood but not allowed by server policy. | +| `404 Not Found` | The blob does not exist. | +| `416 Range Not Satisfiable` | The blob exists but the requested byte range is invalid or outside the blob size. | +| `429 Too Many Requests` | The client has exceeded a rate limit or quota. | +| `503 Service Unavailable` | The retrieval service is temporarily unavailable. | ## HEAD /sha256 - Has Blob @@ -62,6 +76,22 @@ The endpoint MUST respond with the same `Content-Type` and `Content-Length` head The endpoint MUST accept an optional file extension in the URL similar to the `GET /` endpoint. ie. `.pdf`, `.png`, etc +### Status codes + +Servers SHOULD use the following status codes for `HEAD /` responses: + +| Status Code | Meaning | +| ------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `200 OK` | The blob exists and the server returns the same metadata headers as `GET /` without a response body. | +| `307 Temporary Redirect` | The blob is temporarily available from another URL containing the same sha256. | +| `308 Permanent Redirect` | The blob is permanently available from another URL containing the same sha256. | +| `400 Bad Request` | The sha256 path, optional file extension, or request headers are malformed. | +| `401 Unauthorized` | Authorization is required and missing or invalid. See [BUD-11](./11.md#endpoint-authorization-requirements). | +| `403 Forbidden` | The request is understood but not allowed by server policy. | +| `404 Not Found` | The blob does not exist. | +| `429 Too Many Requests` | The client has exceeded a rate limit or quota. | +| `503 Service Unavailable` | The retrieval service is temporarily unavailable. | + ## Range requests To better support mobile devices, video files, or low bandwidth connections. servers should support range requests ([RFC 7233 section 3](https://www.rfc-editor.org/rfc/rfc7233#section-3)) on the `GET /` endpoint and signal support using the `accept-ranges: bytes` and `content-length` headers on the `HEAD /` endpoint diff --git a/buds/02.md b/buds/02.md index 549fc35..09f9947 100644 --- a/buds/02.md +++ b/buds/02.md @@ -1,12 +1,14 @@ # BUD-02 -## Blob upload and management +## Blob upload `draft` `optional` _All pubkeys MUST be in hex format_ -Defines the `/upload`, `/list` and `DELETE /` endpoints +Defines the `HEAD /upload` and `PUT /upload` endpoints. + +The `/list/` and `DELETE /` endpoints are defined in [BUD-12](./12.md). ## Blob Descriptor @@ -36,44 +38,110 @@ Example: ## PUT /upload - Upload Blob -The `PUT /upload` endpoint MUST accept binary data in the request body. +The `PUT /upload` endpoint MUST accept binary data in 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. Clients MAY provide an `X-SHA-256` header containing the lowercase hex-encoded sha256 of the request body. A server MAY use this value to enforce rejection policies or perform authorization checks prior to persisting the blob. -On success, the endpoint MUST respond with a `2xx` status code with a [Blob Descriptor](#blob-descriptor) in the response body. -On failure, the endpoint MUST return an appropriate `4xx` status code and an error message explaining the reason for the rejection. +If the blob was newly stored, the endpoint MUST respond with `201 Created` and a [Blob Descriptor](#blob-descriptor) in the response body. +If the blob already exists, the endpoint MUST respond with `200 OK` and a [Blob Descriptor](#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 /upload` responses: + +| Status Code | Meaning | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `200 OK` | The blob already exists and the server is returning the existing [Blob Descriptor](#blob-descriptor). | +| `201 Created` | The blob was stored successfully and the server is returning its [Blob Descriptor](#blob-descriptor). | +| `400 Bad Request` | The 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 provided `X-SHA-256` 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. | +| `507 Insufficient Storage` | The server cannot store the blob. | + +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 /` 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. -### Upload Authorization (Optional) +## HEAD /upload - Upload requirements (Optional) -Servers MAY require authorization when uploading blobs, as defined by [BUD-11](./11.md#endpoint-authorization-requirements). +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 avoid receiving blobs that are already stored or would fail validation. -## GET /list/pubkey - List Blobs (Unrecommended) +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. -**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 `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. -The `/list/` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that were uploaded by the specified pubkey +### Headers -The endpoint MUST support `cursor` and `limit` query parameters for cursor based pagination. The `cursor` parameter MUST be the `sha256` hash of the last blob in the previous page, or omitted to request the first page. The `limit` parameter specifies the maximum number of results to return. The returned array of blob descriptors MUST be sorted by the `uploaded` date in descending order and MUST NOT include the blob at the cursor +- `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`. -The endpoint MAY support `since` and `until` query parameters to filter the list of blobs by their `uploaded` date. These parameters are deprecated for pagination purposes as they do not preserve server resources +### Status codes -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 +Servers SHOULD use the following status codes for `HEAD /upload` responses: -### List Authorization +| Status Code | Meaning | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `200 OK` | The blob already exists on the server and the client MAY skip the `PUT /upload` request. | +| `204 No Content` | 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. | -Servers MAY require authorization when listing blobs as defined by [BUD-11](./11.md#endpoint-authorization-requirements). +If included, `X-Reason` MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow. -## DELETE /sha256 - Delete Blob +Clients that do not implement this optimization may still perform `PUT /upload` after receiving `200 OK`, and servers MUST handle that correctly. -Servers MUST accept `DELETE` requests to the `/` endpoint +### Examples -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 +Example request from the client: -### Delete Authorization +```http +X-Content-Type: application/pdf +X-Content-Length: 184292 +X-SHA-256: 88a74d0b866c8ba79251a11fe5ac807839226870e77355f02eaf68b156522576 +``` -Servers MAY require authorization when deleting blobs as defined by [BUD-11](./11.md#endpoint-authorization-requirements). **Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to delete multiple blobs.** +Example response from the server if the blob already exists: + +```http +HTTP/1.1 200 OK +``` + +Example response from the server if the upload may proceed: + +```http +HTTP/1.1 204 No Content +``` + +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. +``` diff --git a/buds/05.md b/buds/05.md index 4e3647f..e0bdc4b 100644 --- a/buds/05.md +++ b/buds/05.md @@ -13,8 +13,27 @@ The server SHOULD perform any optimizations or conversions it deems necessary in Clients SHOULD include `Content-Type` and `Content-Length` headers specifying the MIME type and size of the data. Clients MAY provide an `X-SHA-256` header containing the lowercase hex-encoded sha256 of the request body. A server MAY use this value to enforce rejection policies or perform authorization checks prior to persisting the blob. -On success, the endpoint MUST respond with a `2xx` status code with a [Blob Descriptor](#blob-descriptor) in the response body. -On failure, the endpoint MUST return an appropriate `4xx` status code and an error message explaining the reason for the rejection. +On success, the endpoint MUST respond with `200 OK` and a [Blob Descriptor](#blob-descriptor) in the response body. +On failure, the endpoint MUST return an appropriate `4xx` or `5xx` status code and an error message explaining the reason for the rejection. + +### PUT /media status codes + +Servers SHOULD use the following status codes for `PUT /media` responses: + +| Status Code | Meaning | +| ---------------------------- | -------------------------------------------------------------- | +| `200 OK` | The media was accepted, processed, and stored successfully. | +| `400 Bad Request` | The request headers or body are malformed. | +| `401 Unauthorized` | Authorization is required and missing or invalid. | +| `403 Forbidden` | The request is understood but not allowed by server policy. | +| `409 Conflict` | The provided `X-SHA-256` does not match the request body. | +| `411 Length Required` | A required `Content-Length` header is missing. | +| `413 Content Too Large` | The media exceeds server size limits. | +| `415 Unsupported Media Type` | The media type is not supported. | +| `422 Unprocessable Content` | The media is well-formed but cannot be processed successfully. | +| `429 Too Many Requests` | The client has exceeded a rate limit or quota. | +| `503 Service Unavailable` | The media processing service is temporarily unavailable. | +| `507 Insufficient Storage` | The server cannot store the processed media. | ### Upload Authorization @@ -22,7 +41,24 @@ Servers MAY require authorization when processing media as defined by [BUD-11](. ## HEAD /media -Servers MUST respond to `HEAD` requests on the `/media` endpoint in a similar way to the `HEAD /upload` endpoint defined in [BUD-06](./06.md) +Servers MAY implement `HEAD /media` as an optimization step before `PUT /media`. +Clients can use it to avoid uploading media that would be rejected, and servers can use it to reject requests before receiving the full body. + +The `HEAD /media` 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 media that will be uploaded, returning a HTTP status code and a custom header `X-Reason` to indicate some human readable message about the upload requirements. + +Servers SHOULD use the following status codes for `HEAD /media` responses: + +| Status Code | Meaning | +| ---------------------------- | ----------------------------------------------------------- | +| `200 OK` | The request is acceptable and the upload may proceed. | +| `400 Bad Request` | The request headers are malformed. | +| `401 Unauthorized` | Authorization is required and missing or invalid. | +| `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 media would exceed server size limits. | +| `415 Unsupported Media Type` | The media type is not supported. | +| `429 Too Many Requests` | The client has exceeded a rate limit or quota. | +| `503 Service Unavailable` | The media processing service is temporarily unavailable. | ## Limitations diff --git a/buds/06.md b/buds/06.md index 691c0e9..1e27685 100644 --- a/buds/06.md +++ b/buds/06.md @@ -4,68 +4,6 @@ `draft` `optional` -Defines how clients can verify if the upload can be completed before sending the blob to the server. This mechanism helps prevent unnecessary traffic to other endpoints by rejecting files based on their hash, size, MIME type or other server-specific requirements. +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`. -## HEAD /upload - Upload requirements - -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 a HTTP status code and a custom header `X-Reason` to indicate some human readable message about the upload requirements. - -### 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`. - -### Upload Authorization - -Servers MAY require authorization for this endpoint as defined by [BUD-11](./11.md#endpoint-authorization-requirements). - -### 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 can be done: - -```http -HTTP/1.1 200 OK -``` - -If the upload cannot proceed, the server MUST return an appropriate `4xx` HTTP status code and a custom header `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 401 Unauthorized -X-Reason: Authorization required for uploading video files. -``` - -```http -HTTP/1.1 403 Forbidden -X-Reason: SHA-256 hash banned. -``` - -```http -HTTP/1.1 411 Length Required -X-Reason: Missing X-Content-Length header. -``` - -```http -HTTP/1.1 413 Content Too Large -X-Reason: File too large. Max allowed size is 100MB. -``` - -```http -HTTP/1.1 415 Unsupported Media Type -X-Reason: Unsupported file type. -``` +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. diff --git a/buds/07.md b/buds/07.md index af8e278..e7a9eb9 100644 --- a/buds/07.md +++ b/buds/07.md @@ -1,8 +1,6 @@ -BUD-07 -====== +# BUD-07 -Paid upload and download ---------------- +## Paid upload and download `draft` `optional` @@ -14,11 +12,11 @@ Some servers MAY require payment for uploads, downloads, or any other endpoint. Some endpoints a server may require payment for: -- [`HEAD /upload`](./06.md) to signal that payment is required for the `PUT` request ( if [BUD-06](./06.md) is supported ) +- [`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 /`](./01.md#head-sha256---has-blob) to signal that payment is required for the `GET` request - [`GET /`](./01.md#get-sha256---get-blob) to require payment for downloads ( maybe charge by MB downloaded? ) -- [`HEAD /media`](./05.md) and [`PUT /upload`](./05.md) to require payment for media optimizations ( if [BUD-06](./06.md) is supported ) +- [`HEAD /media`](./05.md) and [`PUT /upload`](./05.md) to require payment for media optimizations ( if the optional `HEAD /upload`-style preflight is supported ) When payment is required, the server MUST include one or more `X-{payment_method}` header(s), each corresponding to a supported payment method. @@ -46,7 +44,7 @@ When using the X-Cashu header, the server MUST adhere to the [NUT-24](https://gi Example for cashu: -```http +```http HTTP/1.1 402 Payment Required X-Cashu: creqApWF0gaNhdGVub3N0cmFheKlucHJvZmlsZTFxeTI4d3VtbjhnaGo3dW45ZDNzaGp0bnl2OWtoMnVld2Q5aHN6OW1od2RlbjV0ZTB3ZmprY2N0ZTljdXJ4dmVuOWVlaHFjdHJ2NWhzenJ0aHdkZW41dGUwZGVoaHh0bnZkYWtxcWd5ZGFxeTdjdXJrNDM5eWtwdGt5c3Y3dWRoZGh1NjhzdWNtMjk1YWtxZWZkZWhrZjBkNDk1Y3d1bmw1YWeBgmFuYjE3YWloYjdhOTAxNzZhYQphdWNzYXRhbYF4Imh0dHBzOi8vbm9mZWVzLnRlc3RudXQuY2FzaHUuc3BhY2U ``` @@ -71,7 +69,7 @@ The client MUST provide the payment proof when re-trying the request using the s - For lightning the payment proof should be the preimage of the payment request according to [BOLT-11](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md). Schema: - + ```http X-{payment_method}: "" ``` diff --git a/buds/11.md b/buds/11.md index 0dd60fc..d144eab 100644 --- a/buds/11.md +++ b/buds/11.md @@ -14,7 +14,7 @@ All authorization tokens: - MUST have the `content` set to a human readable string explaining intended use to the user. For example `Upload Blob`, `Delete old blobs`, `List Images`, etc. -- 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. +- 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. - MUST have a `t` tag with a verb of `get`, `upload`, `list`, `delete`, or `media`. The value of the `t` tag MUST correspond to the action performed by the target endpoint, as defined in the section [Endpoint Authorization Requirements](#endpoint-authorization-requirements). @@ -70,8 +70,8 @@ To validate an authorization token, a server MUST perform the following checks: The table below defines, for each endpoint, the required `t` tag action, the implied blob hash (if any), and whether at least one matching `x` tag is required. -| Endpoint | Required `t` | Implied Blob Hash | `x` Tag Requirement | -|----------------------|--------------|-------------------------------|---------------------| +| Endpoint | Required `t` | Implied Blob Hash | `x` Tag Requirement | +| -------------------- | ------------ | ---------------------------- | ------------------- | | `GET /` | `get` | `` from the URL | optional | | `HEAD /` | `get` | `` from the URL | optional | | `PUT /upload` | `upload` | `X-SHA-256` request header | required | diff --git a/buds/12.md b/buds/12.md new file mode 100644 index 0000000..a8b9aaa --- /dev/null +++ b/buds/12.md @@ -0,0 +1,60 @@ +# BUD-12 + +## Blob management endpoints + +`draft` `optional` + +_All pubkeys MUST be in hex format_ + +Defines the `/list/` and `DELETE /` endpoints. + +The [Blob Descriptor](./02.md#blob-descriptor) type is defined in [BUD-02](./02.md). + +## GET /list/pubkey - List Blobs (Unrecommended) + +**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/` endpoint MUST return a JSON array of [Blob Descriptor](./02.md#blob-descriptor) objects that were uploaded by the specified pubkey. + +The endpoint MUST support `cursor` and `limit` query parameters for cursor based pagination. The `cursor` parameter MUST be the `sha256` hash of the last blob in the previous page, or omitted to request the first page. The `limit` parameter specifies the maximum number of results to return. The returned array of blob descriptors MUST be sorted by the `uploaded` date in descending order and MUST NOT include the blob at the cursor. + +The endpoint MAY support `since` and `until` query parameters to filter the list of blobs by their `uploaded` date. These parameters are deprecated for pagination purposes as they do not preserve server resources. + +### Status codes + +Servers SHOULD use the following status codes for `GET /list/` responses: + +| Status Code | Meaning | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `200 OK` | The list request succeeded and the response body contains an array of [Blob Descriptor](./02.md#blob-descriptor) objects. | +| `400 Bad Request` | The query parameters 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 listing blobs. See [BUD-07](./07.md). | +| `403 Forbidden` | The request is understood but not allowed by server policy. | +| `429 Too Many Requests` | The client has exceeded a rate limit or quota. | +| `503 Service Unavailable` | The listing 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. + +## DELETE /sha256 - Delete Blob + +Servers MUST accept `DELETE` requests to the `/` endpoint. + +### Status codes + +Servers SHOULD use the following status codes for `DELETE /` responses: + +| Status Code | Meaning | +| ------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `200 OK` | The blob was deleted successfully and the response may include a body. | +| `204 No Content` | The blob was deleted successfully and the response body is empty. | +| `401 Unauthorized` | Authorization is required and missing or invalid. See [BUD-11](./11.md#endpoint-authorization-requirements). | +| `402 Payment Required` | Payment is required before deleting the blob. See [BUD-07](./07.md). | +| `403 Forbidden` | The request is understood but not allowed by server policy. | +| `404 Not Found` | The blob does not exist or is not available for deletion. | +| `429 Too Many Requests` | The client has exceeded a rate limit or quota. | +| `503 Service Unavailable` | The deletion 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. + +Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to delete multiple blobs. From 183e1b313148b9b9d241ede41d10fc3a2b26f786 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Fri, 10 Apr 2026 12:34:48 -0500 Subject: [PATCH 2/7] Add HTTP status codes to BUD-04 --- README.md | 4 ++-- buds/02.md | 1 - buds/04.md | 26 +++++++++++++++++++++++--- buds/05.md | 1 - 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 23c4615..c08495a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ 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) +- [BUD-06: Upload requirements](./buds/06.md) _(moved to [BUD-02](./buds/02.md#head-upload---upload-requirements-optional))_ - [BUD-07: Payment required](./buds/07.md) - [BUD-08: Nostr File Metadata Tags](./buds/08.md) - [BUD-09: Blob Report](./buds/09.md) @@ -36,7 +36,7 @@ Blossom Servers expose a few endpoints for managing blobs - `GET /` (optional file `.ext`) [BUD-01](./buds/01.md#get-sha256---get-blob) - `HEAD /` (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-06](./buds/06.md#head-upload---upload-requirements) +- `HEAD /upload` [BUD-02](./buds/02.md#head-upload---upload-requirements-optional) - `GET /list/` [BUD-02](./buds/02.md#get-listpubkey---list-blobs-unrecommended) _(unrecommended)_ - `DELETE /` [BUD-02](./buds/02.md#delete-sha256---delete-blob) - `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob) diff --git a/buds/02.md b/buds/02.md index 09f9947..ffb00b5 100644 --- a/buds/02.md +++ b/buds/02.md @@ -65,7 +65,6 @@ Servers SHOULD use the following status codes for `PUT /upload` responses: | `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. | -| `507 Insufficient Storage` | The server cannot store the blob. | If included, `X-Reason` MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow. diff --git a/buds/04.md b/buds/04.md index 572a9bd..742c58f 100644 --- a/buds/04.md +++ b/buds/04.md @@ -19,8 +19,8 @@ Clients MUST pass the URL of the remote blob as a stringified JSON object in the } ``` -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. +If the blob was newly mirrored and stored, the endpoint MUST respond with `201 Created` and a [Blob Descriptor](#blob-descriptor) in the response body. +If the blob already exists, the endpoint MUST respond with `200 OK` and a [Blob Descriptor](#blob-descriptor) in the response body. The destination server SHOULD use the `Content-Type` header returned from the origin server to infer the mime type of the blob. If the `Content-Type` header is not present the destination server SHOULD attempt to detect the `Content-Type` @@ -28,7 +28,27 @@ from the blob contents and file extension, falling back to `application/octet-st 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. +Servers MAY reject a mirror request for any reason and MUST respond with the appropriate HTTP status code and an error message explaining the reason for the rejection. + +### Status codes + +Servers SHOULD use the following status codes for `PUT /mirror` 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 mirrored and stored successfully and the server is returning its [Blob Descriptor](./02.md#blob-descriptor). | +| `400 Bad Request` | The request body is malformed or the `url` is invalid. | +| `401 Unauthorized` | Authorization is required and missing or invalid. See [BUD-11](./11.md#endpoint-authorization-requirements). | +| `402 Payment Required` | Payment is required before mirroring can proceed. See [BUD-07](./07.md). | +| `403 Forbidden` | The request is understood but not allowed by server policy. | +| `409 Conflict` | The mirrored blob hash does not match the authorized `x` tag. | +| `413 Content Too Large` | The mirrored blob exceeds server size limits. | +| `415 Unsupported Media Type` | The mirrored blob type is not supported. | +| `429 Too Many Requests` | The client has exceeded a rate limit or quota. | +| `502 Bad Gateway` | The server could not fetch the blob from the origin URL or the origin response was unusable. | + +If included, `X-Reason` MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow. ### Upload Authorization diff --git a/buds/05.md b/buds/05.md index e0bdc4b..34fef20 100644 --- a/buds/05.md +++ b/buds/05.md @@ -33,7 +33,6 @@ Servers SHOULD use the following status codes for `PUT /media` responses: | `422 Unprocessable Content` | The media is well-formed but cannot be processed successfully. | | `429 Too Many Requests` | The client has exceeded a rate limit or quota. | | `503 Service Unavailable` | The media processing service is temporarily unavailable. | -| `507 Insufficient Storage` | The server cannot store the processed media. | ### Upload Authorization From aa222f6e20290c7f29c552c8c902824f227ad3f9 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Fri, 10 Apr 2026 12:36:30 -0500 Subject: [PATCH 3/7] Update readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c08495a..45272cb 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ BUDs or **Blossom Upgrade Documents** are short documents that outline an additi - [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) ## Endpoints @@ -37,8 +38,8 @@ Blossom Servers expose a few endpoints for managing blobs - `HEAD /` (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) -- `GET /list/` [BUD-02](./buds/02.md#get-listpubkey---list-blobs-unrecommended) _(unrecommended)_ -- `DELETE /` [BUD-02](./buds/02.md#delete-sha256---delete-blob) +- `GET /list/` [BUD-12](./buds/12.md#get-listpubkey---list-blobs-unrecommended) _(unrecommended)_ +- `DELETE /` [BUD-12](./buds/12.md#delete-sha256---delete-blob) - `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob) - `HEAD /media` [BUD-05](./buds/05.md#head-media) - `PUT /media` [BUD-05](./buds/05.md#put-media) From ea0f66b05c083c10b1289d5a5b49961b824b751d Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Fri, 10 Apr 2026 13:37:56 -0500 Subject: [PATCH 4/7] Add 201 status to /media --- buds/05.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/buds/05.md b/buds/05.md index 34fef20..a0d57b9 100644 --- a/buds/05.md +++ b/buds/05.md @@ -13,7 +13,7 @@ The server SHOULD perform any optimizations or conversions it deems necessary in Clients SHOULD include `Content-Type` and `Content-Length` headers specifying the MIME type and size of the data. Clients MAY provide an `X-SHA-256` header containing the lowercase hex-encoded sha256 of the request body. A server MAY use this value to enforce rejection policies or perform authorization checks prior to persisting the blob. -On success, the endpoint MUST respond with `200 OK` and a [Blob Descriptor](#blob-descriptor) in the response body. +On success, the endpoint MUST respond with either `200 OK` or `201 Created` and a [Blob Descriptor](#blob-descriptor) in the response body. Clients MUST treat both status codes as successful media creation. On failure, the endpoint MUST return an appropriate `4xx` or `5xx` status code and an error message explaining the reason for the rejection. ### PUT /media status codes @@ -23,6 +23,7 @@ Servers SHOULD use the following status codes for `PUT /media` responses: | Status Code | Meaning | | ---------------------------- | -------------------------------------------------------------- | | `200 OK` | The media was accepted, processed, and stored successfully. | +| `201 Created` | The media was accepted, processed, and stored successfully. | | `400 Bad Request` | The request headers or body are malformed. | | `401 Unauthorized` | Authorization is required and missing or invalid. | | `403 Forbidden` | The request is understood but not allowed by server policy. | @@ -43,7 +44,7 @@ Servers MAY require authorization when processing media as defined by [BUD-11](. Servers MAY implement `HEAD /media` as an optimization step before `PUT /media`. Clients can use it to avoid uploading media that would be rejected, and servers can use it to reject requests before receiving the full body. -The `HEAD /media` 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 media that will be uploaded, returning a HTTP status code and a custom header `X-Reason` to indicate some human readable message about the upload requirements. +The `HEAD /media` 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 media 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. Servers SHOULD use the following status codes for `HEAD /media` responses: @@ -59,6 +60,8 @@ Servers SHOULD use the following status codes for `HEAD /media` responses: | `429 Too Many Requests` | The client has exceeded a rate limit or quota. | | `503 Service Unavailable` | The media processing 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. + ## Limitations The goal of this endpoint is to provide a simple "trusted" optimization endpoint clients can use to optimize media for distribution. From d02c5fc7ddbc2448fa504ddb8d3cc6a65e903696 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Sat, 11 Apr 2026 11:34:11 -0500 Subject: [PATCH 5/7] Clarify HEAD /upload blob existence checks --- buds/02.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/buds/02.md b/buds/02.md index ffb00b5..4550368 100644 --- a/buds/02.md +++ b/buds/02.md @@ -75,10 +75,12 @@ When storing blobs, servers MAY normalise the file extension to a standard forma ## 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 avoid receiving blobs that are already stored or would fail validation. +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 /` 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 @@ -93,8 +95,7 @@ Servers SHOULD use the following status codes for `HEAD /upload` responses: | Status Code | Meaning | | ---------------------------- | ------------------------------------------------------------------------------------------------------------ | -| `200 OK` | The blob already exists on the server and the client MAY skip the `PUT /upload` request. | -| `204 No Content` | The upload would be accepted and the client MAY proceed with `PUT /upload`. | +| `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). | @@ -107,7 +108,9 @@ Servers SHOULD use the following status codes for `HEAD /upload` responses: 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` after receiving `200 OK`, and servers MUST handle that correctly. +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 @@ -119,16 +122,10 @@ X-Content-Length: 184292 X-SHA-256: 88a74d0b866c8ba79251a11fe5ac807839226870e77355f02eaf68b156522576 ``` -Example response from the server if the blob already exists: - -```http -HTTP/1.1 200 OK -``` - Example response from the server if the upload may proceed: ```http -HTTP/1.1 204 No Content +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. From c996e37aa67cd2c15e4becaca5cd12e7378aa95d Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Sat, 11 Apr 2026 11:46:50 -0500 Subject: [PATCH 6/7] Clarify HEAD /media responses --- buds/05.md | 13 ++++++++++--- buds/07.md | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/buds/05.md b/buds/05.md index a0d57b9..13d8a43 100644 --- a/buds/05.md +++ b/buds/05.md @@ -42,17 +42,20 @@ Servers MAY require authorization when processing media as defined by [BUD-11](. ## HEAD /media Servers MAY implement `HEAD /media` as an optimization step before `PUT /media`. -Clients can use it to avoid uploading media that would be rejected, and servers can use it to reject requests before receiving the full body. +Clients can use it to avoid uploading media that would be rejected, and servers can use it to evaluate whether a media-processing request would be accepted based on the supplied metadata and current server policy. -The `HEAD /media` 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 media 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. +This pre-flight request is only an optimization. Clients MAY skip it entirely, and the result is not a guarantee of the eventual `PUT /media` outcome because server state may change between requests. + +The `HEAD /media` 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 media 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. Servers SHOULD use the following status codes for `HEAD /media` responses: | Status Code | Meaning | | ---------------------------- | ----------------------------------------------------------- | -| `200 OK` | The request is acceptable and the upload may proceed. | +| `200 OK` | Based on the supplied headers and current server policy, the media-processing request would be accepted and the client MAY proceed with `PUT /media`. | | `400 Bad Request` | The request headers are malformed. | | `401 Unauthorized` | Authorization is required and missing or invalid. | +| `402 Payment Required` | Payment is required before the media-processing request 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 media would exceed server size limits. | @@ -62,6 +65,10 @@ Servers SHOULD use the following status codes for `HEAD /media` responses: 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 /media` directly, and servers MUST handle that correctly. + +After receiving `200 OK` from `HEAD /media`, clients MUST still be prepared for `PUT /media` to return either `200 OK` or `201 Created`, depending on how the media-processing result is handled by the server. + ## Limitations The goal of this endpoint is to provide a simple "trusted" optimization endpoint clients can use to optimize media for distribution. diff --git a/buds/07.md b/buds/07.md index e7a9eb9..81360e0 100644 --- a/buds/07.md +++ b/buds/07.md @@ -16,7 +16,7 @@ Some endpoints a server may require payment for: - [`PUT /upload`](./02.md#put-upload---upload-blob) to require payment for uploads - [`HEAD /`](./01.md#head-sha256---has-blob) to signal that payment is required for the `GET` request - [`GET /`](./01.md#get-sha256---get-blob) to require payment for downloads ( maybe charge by MB downloaded? ) -- [`HEAD /media`](./05.md) and [`PUT /upload`](./05.md) to require payment for media optimizations ( if the optional `HEAD /upload`-style preflight is supported ) +- [`HEAD /media`](./05.md) and [`PUT /media`](./05.md) to require payment for media optimizations ( if the optional `HEAD /media`-style preflight is supported ) When payment is required, the server MUST include one or more `X-{payment_method}` header(s), each corresponding to a supported payment method. From 94d04be9fc5905f4831d7a6e65a8f267e8e287f5 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Thu, 16 Apr 2026 10:36:39 -0500 Subject: [PATCH 7/7] Move HEAD /upload back into BUD-06 --- README.md | 4 +-- buds/02.md | 72 +----------------------------------------------------- buds/06.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++-- buds/07.md | 2 +- 4 files changed, 70 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 45272cb..14be927 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ 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) @@ -37,7 +37,7 @@ Blossom Servers expose a few endpoints for managing blobs - `GET /` (optional file `.ext`) [BUD-01](./buds/01.md#get-sha256---get-blob) - `HEAD /` (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) +- `HEAD /upload` [BUD-06](./buds/06.md) - `GET /list/` [BUD-12](./buds/12.md#get-listpubkey---list-blobs-unrecommended) _(unrecommended)_ - `DELETE /` [BUD-12](./buds/12.md#delete-sha256---delete-blob) - `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob) diff --git a/buds/02.md b/buds/02.md index 4550368..24766da 100644 --- a/buds/02.md +++ b/buds/02.md @@ -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/` and `DELETE /` 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 /` 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 /` 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. -``` diff --git a/buds/06.md b/buds/06.md index 1e27685..49fdce2 100644 --- a/buds/06.md +++ b/buds/06.md @@ -4,6 +4,70 @@ `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`. +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 optional preflight endpoint remains intended as an optimization so clients and servers can avoid uploading blobs that would be rejected or that already exist. +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 /` 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. +``` diff --git a/buds/07.md b/buds/07.md index 81360e0..05eba9e 100644 --- a/buds/07.md +++ b/buds/07.md @@ -12,7 +12,7 @@ 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 ) +- [`HEAD /upload`](./06.md) 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 /`](./01.md#head-sha256---has-blob) to signal that payment is required for the `GET` request - [`GET /`](./01.md#get-sha256---get-blob) to require payment for downloads ( maybe charge by MB downloaded? )