From 5ef2889547dec88427bf17a3cf7869768b876b75 Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Wed, 4 Jun 2025 19:13:37 +0100 Subject: [PATCH 1/8] Make type mandatory in the blob descriptor --- buds/02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buds/02.md b/buds/02.md index 7264be9..e491892 100644 --- a/buds/02.md +++ b/buds/02.md @@ -15,7 +15,7 @@ A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, a - `url` A publicly accessible URL to the [BUD-01](./01.md#get-sha256---get-blob) `GET /` endpoint with a file extension - `sha256` The sha256 hash of the blob - `size` The size of the blob in bytes -- `type` (optional) The MIME type of the blob +- `type` The MIME type of the blob (falling back to `application/octet-stream` if unknown) - `uploaded` The unix timestamp of when the blob was uploaded to the server Servers MUST include a file extension in the URL in the `url` field to allow clients to easily embed the URL in social posts or other content From cacfa520dd9b26f3f7220625d00798da5062422e Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Wed, 4 Jun 2025 19:58:02 +0100 Subject: [PATCH 2/8] Clarify requirements around Content-Type and Content-Length - Specify that the server must return the MIME type in the Content-Type header for blob retrieval. - Clarify fallback behaviour for unknown MIME types to application/octet-stream. - Improve the description of how servers should infer MIME types and handle Content-Length for mirror requests. --- buds/01.md | 3 +++ buds/04.md | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/buds/01.md b/buds/01.md index c10a883..1b17cc5 100644 --- a/buds/01.md +++ b/buds/01.md @@ -79,6 +79,9 @@ The `GET /` endpoint MUST return the contents of the blob in the respons The endpoint MUST accept an optional file extension in the URL. ie. `.pdf`, `.png`, etc +Regardless of the file extension, the server MUST return the MIME type of the blob in the `Content-Type` +header. If the server does not know the MIME type of the blob, it MUST default to `application/octet-stream` + If the endpoint returns a `301` or `302` redirect it MUST redirect to a URL containing the same sha256 hash as the requested blob. This ensures that if a user was to copy or reuse the redirect URL it would still contain the original sha256 hash diff --git a/buds/04.md b/buds/04.md index dde6fc4..4f323c9 100644 --- a/buds/04.md +++ b/buds/04.md @@ -25,9 +25,14 @@ The `/mirror` endpoint MUST download the blob from the specified URL and verify **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 messageif it was not +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. -Servers SHOULD use the `Content-Type` header returned from the requested URL to infer the mime type of the blob. If the `Content-Type` header is not returned they SHOULD attempt to use the file extension in the URL or fallback to `application/octet-stream`. +Servers SHOULD use the `Content-Type` header returned from the requested URL to infer the mime type of the blob. If the +`Content-Type` header is not present they SHOULD attempt to detect the `Content-Type` from the blob contents and file +extension, falling back to `application/octet-stream` if they cannot determine the type. + +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. From 1a085ed7bf8d4ae86abc17cb9c737df6ff7c6f05 Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Wed, 4 Jun 2025 20:15:03 +0100 Subject: [PATCH 3/8] fix: clarify Content-Type handling for blob retrieval and mirroring --- buds/01.md | 9 +++++---- buds/04.md | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/buds/01.md b/buds/01.md index 1b17cc5..f45d497 100644 --- a/buds/01.md +++ b/buds/01.md @@ -79,8 +79,8 @@ The `GET /` endpoint MUST return the contents of the blob in the respons The endpoint MUST accept an optional file extension in the URL. ie. `.pdf`, `.png`, etc -Regardless of the file extension, the server MUST return the MIME type of the blob in the `Content-Type` -header. If the server does not know the MIME type of the blob, it MUST default to `application/octet-stream` +Regardless of the file extension, the server MUST return the MIME type of the blob in the `Content-Type` header. If the +server does not know the MIME type of the blob, it MUST default to `application/octet-stream` If the endpoint returns a `301` or `302` redirect it MUST redirect to a URL containing the same sha256 hash as the requested blob. This ensures that if a user was to copy or reuse the redirect URL it would still contain the original sha256 hash @@ -134,9 +134,10 @@ Example event for retrieving multiple blobs from single server: ## HEAD /sha256 - Has Blob -The `HEAD /` endpoint SHOULD be identical to the `GET /` endpoint except that it MUST NOT return the blob in the reponse body per [RFC 7231](https://www.rfc-editor.org/rfc/rfc7231#section-4.3.2) +The `HEAD /` endpoint SHOULD be identical to the `GET /` endpoint except that it MUST NOT return the +blob in the reponse body per [RFC 7231](https://www.rfc-editor.org/rfc/rfc7231#section-4.3.2) -The endpoint MUST respond with the same `Content-Type` and `Content-Length` headers as the `GET /` endpoint. +The endpoint MUST respond with the same `Content-Type` and `Content-Length` headerers as the `GET /` endpoint The endpoint MUST accept an optional file extension in the URL similar to the `GET /` endpoint. ie. `.pdf`, `.png`, etc diff --git a/buds/04.md b/buds/04.md index 4f323c9..6165ed4 100644 --- a/buds/04.md +++ b/buds/04.md @@ -28,9 +28,9 @@ The `/mirror` endpoint MUST download the blob from the specified URL and verify 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. -Servers SHOULD use the `Content-Type` header returned from the requested URL to infer the mime type of the blob. If the -`Content-Type` header is not present they SHOULD attempt to detect the `Content-Type` from the blob contents and file -extension, falling back to `application/octet-stream` if they cannot determine the type. +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` +from the blob contents and file extension, falling back to `application/octet-stream` if it cannot determine the type. Servers MAY use the `Content-Length` header to determine the size of the blob. From 611272e251cc25c408f79a2cb33e4425aba309bf Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Wed, 4 Jun 2025 21:37:13 +0100 Subject: [PATCH 4/8] Enhance proxying and redirection specification for blob retrieval --- buds/01.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/buds/01.md b/buds/01.md index f45d497..657b6ba 100644 --- a/buds/01.md +++ b/buds/01.md @@ -82,8 +82,22 @@ The endpoint MUST accept an optional file extension in the URL. ie. `.pdf`, `.pn Regardless of the file extension, the server MUST return the MIME type of the blob in the `Content-Type` header. If the server does not know the MIME type of the blob, it MUST default to `application/octet-stream` -If the endpoint returns a `301` or `302` redirect it MUST redirect to a URL containing the same sha256 hash as the requested blob. -This ensures that if a user was to copy or reuse the redirect URL it would still contain the original sha256 hash +### Proxying and Redirection (Optional) + +If the endpoint returns a redirection 3xx status code such as 307 or 308 ([RFC 9110 section +15.4](https://datatracker.ietf.org/doc/html/rfc9110#name-redirection-3xx)), it MUST redirect to a URL containing the +same sha256 hash as the requested blob. This ensures that if a user copies or reuses the redirect URL, it will still +contain the original sha56 hash. + +While the final blob may not be served from a Blossom server (e.g. CDN, IPFS, object storage, etc.), the destination +server MUST set the `Access-Control-Allow-Origin: *` header on the response to allow cross-origin requests, as well as +the `Content-Type` and `Content-Length` headers to ensure the blob can be correctly displayed by clients. Two ways to +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.). ### Get Authorization (optional) From b1a336fe750bb740552bc3d1cc7ce771e5849d41 Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Wed, 4 Jun 2025 21:38:51 +0100 Subject: [PATCH 5/8] Add optional file extension normalization during upload --- buds/02.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/buds/02.md b/buds/02.md index e491892..fa073b0 100644 --- a/buds/02.md +++ b/buds/02.md @@ -42,7 +42,15 @@ The endpoint MUST NOT modify the blob in any way and should return the exact sam The endpoint MUST return a [Blob Descriptor](#blob-descriptor) if the upload was successful or an error object if it was not -Servers MAY reject an upload for any reason and should respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection +Servers MAY reject an upload for any reason and should respond with the appropriate HTTP `4xx` status code and an error +message explaining the reason for the rejection + +### 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) From 658c608b119e11702127322531382fabd7959be3 Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Wed, 4 Jun 2025 21:46:07 +0100 Subject: [PATCH 6/8] fix: update authorization event reference link in mirroring documentation --- buds/04.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buds/04.md b/buds/04.md index 6165ed4..67b013b 100644 --- a/buds/04.md +++ b/buds/04.md @@ -19,7 +19,7 @@ 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-required). When using authorization, the event MUST be of type "upload". +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 From 85de0197f0e14c11fbe19958d7fbd4e7f8f10e26 Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Tue, 17 Jun 2025 23:18:13 +0100 Subject: [PATCH 7/8] fix: correct typo in Content-Length headers description in blob retrieval documentation --- buds/01.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buds/01.md b/buds/01.md index 657b6ba..4808b81 100644 --- a/buds/01.md +++ b/buds/01.md @@ -151,7 +151,7 @@ Example event for retrieving multiple blobs from single server: The `HEAD /` endpoint SHOULD be identical to the `GET /` endpoint except that it MUST NOT return the blob in the reponse body per [RFC 7231](https://www.rfc-editor.org/rfc/rfc7231#section-4.3.2) -The endpoint MUST respond with the same `Content-Type` and `Content-Length` headerers as the `GET /` endpoint +The endpoint MUST respond with the same `Content-Type` and `Content-Length` headers as the `GET /` endpoint. The endpoint MUST accept an optional file extension in the URL similar to the `GET /` endpoint. ie. `.pdf`, `.png`, etc From 39ce39aa4d5b02e2b57b745e19debfc412b1f154 Mon Sep 17 00:00:00 2001 From: Anthony Accioly <1591739+aaccioly@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:21:32 +0100 Subject: [PATCH 8/8] fix: correct grammar in bud/01 redirect requirements Co-authored-by: hzrd149 <8001706+hzrd149@users.noreply.github.com> --- buds/01.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buds/01.md b/buds/01.md index 4808b81..94243bf 100644 --- a/buds/01.md +++ b/buds/01.md @@ -86,8 +86,8 @@ server does not know the MIME type of the blob, it MUST default to `application/ If the endpoint returns a redirection 3xx status code such as 307 or 308 ([RFC 9110 section 15.4](https://datatracker.ietf.org/doc/html/rfc9110#name-redirection-3xx)), it MUST redirect to a URL containing the -same sha256 hash as the requested blob. This ensures that if a user copies or reuses the redirect URL, it will still -contain the original sha56 hash. +same sha256 hash as the requested blob. This ensures that if a user copies or reuses the redirect URL, it will +contain the original sha256 hash. While the final blob may not be served from a Blossom server (e.g. CDN, IPFS, object storage, etc.), the destination server MUST set the `Access-Control-Allow-Origin: *` header on the response to allow cross-origin requests, as well as