From 51d3ff5db00a04690a1453f419dea4c4d8d3945d Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Sat, 18 May 2024 07:19:01 -0500 Subject: [PATCH 1/9] Add requirement for sha256 on upload --- buds/bud-01.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/buds/bud-01.md b/buds/bud-01.md index 672a874..0e022e5 100644 --- a/buds/bud-01.md +++ b/buds/bud-01.md @@ -1,6 +1,8 @@ -# BUD-01 +BUD-01 +====== -## Core endpoint outline +Core endpoint outline +--------------------- `draft` `mandatory` @@ -28,17 +30,17 @@ Example event: ```json { - "id": "a2d97d0c8b19d6d91b8bd3c36feeb69f176861f9443ba575cbabf9941d4200bf", - "pubkey": "2db760eae90b5764f3503e0c5660a1a74be9ded5eb8b493e81f65c28a088e9fe", + "id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb", + "pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e", "kind": 24242, "content": "Upload bitcoin.pdf", "created_at": 1708773959, "tags": [ ["t", "upload"], - ["size", "184292"], + ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"], ["expiration", "1708858680"] ], - "sig": "1442c68d5a661d821e9a4b91999b433a1d11557eeb6255496c6875c00d02497deb03dcb54597f210582cd62b621df21b080a0eadbd66ae703264b5929b160d05" + "sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f" } ``` @@ -149,23 +151,23 @@ Servers MAY reject an upload for any reason and should respond with the appropri Servers MUST accept an authorization event when uploading blobs and should perform additional checks 1. The `t` tag MUST be set to `upload` -2. A `size` tag MUST be present and set to the total size of the uploaded blob in bytes +2. The `x` tag MUST be present and set to the sha256 hash of the blob Example Authorization event: ```json { - "id": "65c72db0c3b82ffcb395589d01f3e2849c28753e9e7156ceb88e5dd937ca845f", - "pubkey": "6ea2ab6f206844b1fe48bd8a7eb22ed6e4114a5b2a5252700a729a88142b2bc3", + "id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb", + "pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e", "kind": 24242, "content": "Upload bitcoin.pdf", "created_at": 1708773959, "tags": [ ["t", "upload"], - ["size", "184292"], + ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"], ["expiration", "1708858680"] ], - "sig": "df099ecaeadb7ebcd7ec8247eb57eb6720d39f64a024be3ef1ed9b5d51087b0e866bd08fd317d5167f9bdb9cdae4e593539b86678c4d922db17d0463e0f9e0e3" + "sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f" } ``` From 08ef9cb7d0584f04ada836e43ae5d21495346917 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Wed, 22 May 2024 09:06:50 -0500 Subject: [PATCH 2/9] move files --- README.md | 8 ++++---- buds/{bud-01.md => 01.md} | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename buds/{bud-01.md => 01.md} (100%) diff --git a/README.md b/README.md index e532dc6..4f4d17d 100644 --- a/README.md +++ b/README.md @@ -15,19 +15,19 @@ Blossom Servers expose four endpoints for managing blobs - `GET /` (optional file `.ext`) - `HEAD /` (optional file `.ext`) - `PUT /upload` - - `Authentication`: Signed [nostr event](./buds/bud-01.md#upload-authorization-required) + - `Authentication`: Signed [nostr event](./buds/01.md#upload-authorization-required) - Return a blob descriptor - `GET /list/` - Returns an array of blob descriptors - - `Authentication` _(optional)_: Signed [nostr event](./buds/bud-01.md#list-authorization-optional) + - `Authentication` _(optional)_: Signed [nostr event](./buds/01.md#list-authorization-optional) - `DELETE /` - - `Authentication`: Signed [nostr event](./buds/bud-01.md#delete-authorization-required) + - `Authentication`: Signed [nostr event](./buds/01.md#delete-authorization-required) ## Protocol specification (BUDs) BUDs stand for **Blossom Upgrade Documents**. -See the [BUDs](./buds) folder and specifically [BUD-01](./buds/bud-01.md) for a detailed explanation of the endpoints +See the [BUDs](./buds) folder and specifically [BUD-01](./buds/01.md) for a detailed explanation of the endpoints ## License diff --git a/buds/bud-01.md b/buds/01.md similarity index 100% rename from buds/bud-01.md rename to buds/01.md From dc86bf301af9c55ee9ce34cd55683f8b7766d2c6 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Wed, 22 May 2024 09:20:10 -0500 Subject: [PATCH 3/9] split upload, list, and delete endpoints into bud-02 --- README.md | 14 ++++--- buds/01.md | 120 ++++------------------------------------------------- buds/02.md | 112 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 117 deletions(-) create mode 100644 buds/02.md diff --git a/README.md b/README.md index 4f4d17d..4879df7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # 🌸 Blossom - Blobs stored simply on mediaservers +Blossom uses [nostr](https://github.com/nostr-protocol/nostr) public / private keys for identities. Users are expected to sign authorization events to prove their identity when interacting with servers + ## What is it? Blossom is a spec for a set of HTTP endpoints that allow users to store blobs of data on publicly accessible servers @@ -12,22 +14,22 @@ Blobs are packs of binary data addressed by their sha256 hash Blossom Servers expose four endpoints for managing blobs -- `GET /` (optional file `.ext`) -- `HEAD /` (optional file `.ext`) -- `PUT /upload` +- `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-2](./buds/02.md#put-upload---upload-blob) - `Authentication`: Signed [nostr event](./buds/01.md#upload-authorization-required) - Return a blob descriptor -- `GET /list/` +- `GET /list/` [BUD-02](./buds/02.md#get-listpubkey---list-blobs) - Returns an array of blob descriptors - `Authentication` _(optional)_: Signed [nostr event](./buds/01.md#list-authorization-optional) -- `DELETE /` +- `DELETE /` [BUD-2](./buds/02.md#delete-sha256---delete-blob) - `Authentication`: Signed [nostr event](./buds/01.md#delete-authorization-required) ## Protocol specification (BUDs) BUDs stand for **Blossom Upgrade Documents**. -See the [BUDs](./buds) folder and specifically [BUD-01](./buds/01.md) for a detailed explanation of the endpoints +See the [BUDs](./buds) folder and specifically [BUD-01](./buds/01.md) and [BUD-02](./buds/02.md) for a detailed explanation of the endpoints ## License diff --git a/buds/01.md b/buds/01.md index 0e022e5..0ff59c4 100644 --- a/buds/01.md +++ b/buds/01.md @@ -1,13 +1,11 @@ BUD-01 ====== -Core endpoint outline +Server requirements and blob reterival --------------------- `draft` `mandatory` -Blossom uses [nostr](https://github.com/nostr-protocol/nostr) public / private keys for identities. Users are expected to sign authorization events to prove their identity when interacting with servers - _All pubkeys MUST be in hex format_ ## Cross origin headers @@ -74,14 +72,15 @@ Servers may include additional fields in the descriptor like `magnet`, `infohash ## Endpoints -All endpoints MUST be served from the root path (eg. `https://cdn.example.com/upload`, etc). This allows clients to talk to servers interchangeably when uploading or fetching blobs +All endpoints MUST be served from the root path (eg. `https://cdn.example.com/upload`, etc). This allows clients to talk to servers interchangeably when uploading or reteriving blobs -Servers MUST repond with `Content-Type: application/json` and a JSON object containing `message` for all error responses +## Error Responses -The `message` field MUST be human readable and should explain the reason for the error. Optionally servers may include other fields for the client with more information about the error. +For HTTP `4xx` and `5xx` status codes servers MUST repond with `Content-Type: application/json` and a JSON object containing `message` -### Example Error response +The `message` field MUST be human readable and should explain the reason for the error. Optionally servers may include other fields for the client with more information about the error +Example Error response: ``` HTTP/2 401 content-type: application/json; charset=utf-8 @@ -94,7 +93,7 @@ access-control-allow-methods: get, put, delete {"message":"Missing Auth event"} ``` -### GET /sha256 - Get Blob +## GET /sha256 - Get Blob The `GET /` endpoint MUST return the contents of the blob with the `Content-Type` header set to the appropriate MIME type @@ -103,7 +102,7 @@ The endpoint MUST accept an optional file extension in the URL. ie. `.pdf`, `.pn If the endpoints returns a 301 or 302 redirect it MUST redirect to a URL containing the same sha256 hash as requested blob. This ensures that if a user was to copy or reuse the redirect URL it would still contain the original sha256 hash -#### Get Authorization (optional) +### Get Authorization (optional) The server may optionally require authorization when fetching blobs from the `GET /` endpoint @@ -130,109 +129,8 @@ Example Authorization event: } ``` -### HEAD /sha256 - Has Blob +## HEAD /sha256 - Has Blob The `HEAD /` endpoint MUST respond with either a `200` or `404` status code The endpoint MUST accept an optional file extension in the URL similar to the `GET /` endpoint. ie. `.pdf`, `.png`, etc - -### PUT /upload - Upload Blob - -The `PUT /upload` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` header to get the MIME type of the data - -The endpoint MUST NOT modify the blob in any way and should return the exact same sha256 that was uploaded. This is critical to allow users to re-upload their blobs to new servers - -The endpoint MUST return a [Blob Descriptor](./README.md#blob-descriptor) if the upload was successful or an error object if 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 - -#### Upload Authorization (required) - -Servers MUST accept an authorization event when uploading blobs and should perform additional checks - -1. The `t` tag MUST be set to `upload` -2. The `x` tag MUST be present and set to the sha256 hash of the blob - -Example Authorization event: - -```json -{ - "id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb", - "pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e", - "kind": 24242, - "content": "Upload bitcoin.pdf", - "created_at": 1708773959, - "tags": [ - ["t", "upload"], - ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"], - ["expiration", "1708858680"] - ], - "sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f" -} -``` - -### GET /list/pubkey - List Blobs - -The `/list/` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that where uploaded by the specified pubkey - -The endpoint MUST support a `since` and `until` query parameter to limit the returned blobs by thier `uploaded` date - -Servers may reject a list for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection - -#### List Authorization (optional) - -The server may optionally require Authorization when listing blobs uploaded by the pubkey - -In this case the server must perform additional checks on the authorization event - -1. The `t` tag must be set to `list` - -Example Authorization event: - -```json -{ - "id": "cbb1cab9566355bfdf04e1f1fc1e655fe903ecc193e8a750092ee53beec2a0e8", - "pubkey": "a5fc3654296e6de3cda6ba3e8eba7224fac8b150fd035d66b4c3c1dc2888b8fc", - "kind": 24242, - "content": "List Blobs", - "created_at": 1708772350, - "tags": [ - ["t", "list"], - ["expiration", "1708858680"] - ], - "sig": "ff9c716f8de0f633738036472be553ce4b58dc71d423a0ef403f95f64ef28582ef82129b41d4d0ef64d2338eb4aeeb66dbc03f8b3a3ed405054ea8ecb14fa36c" -} -``` - -### DELETE /sha256 - Delete Blob - -Servers MUST accept `DELETE` requests to the `/` endpoint - -Servers may reject a delete request for any reason and should respond with the aproperate HTTP `4xx` status code and an error message explaining the reason for the rejection - -#### Delete Authorization (required) - -Servers MUST accept an authorization event when deleting blobs - -Servers should perform additional checks on the authorization event - -1. The `t` tag must be set to `delete` -2. A `x` tag must be present and set to the sha256 hash of the blob being deleted - -Example Authorization event: - -```json -{ - "id": "a92868bd8ea740706d931f5d205308eaa0e6698e5f8026a990e78ee34ce47fe8", - "pubkey": "ae0063dd2c81ec469f2291ac029a19f39268bfc40aea7ab4136d7a858c3a06de", - "kind": 24242, - "content": "Delete bitcoin.pdf", - "created_at": 1708774469, - "tags": [ - ["t", "delete"], - ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553 "], - ["expiration", "1708858680"] - ], - "sig": "2ba9af680505583e3eb289a1624a08661a2f6fa2e5566a5ee0036333d517f965e0ffba7f5f7a57c2de37e00a2e85fd7999076468e52bdbcfad8abb76b37a94b0" -} -``` diff --git a/buds/02.md b/buds/02.md new file mode 100644 index 0000000..2501903 --- /dev/null +++ b/buds/02.md @@ -0,0 +1,112 @@ +BUD-02 +====== + +Blob upload and management +--------------------- + +`draft` `optional` + +_All pubkeys MUST be in hex format_ + +Defines the `/upload`, `/list` and `DELETE /` enpoints + +## PUT /upload - Upload Blob + +The `PUT /upload` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` and `Content-Length` headers to get the MIME type and size of the data + +The endpoint MUST NOT modify the blob in any way and should return the exact same sha256 that was uploaded. This is critical to allow users to re-upload their blobs to new servers + +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 + +### Upload Authorization (required) + +Servers MUST accept an authorization event when uploading blobs and should perform additional checks + +1. The `t` tag MUST be set to `upload` +2. The `x` tag MUST be present and set to the sha256 hash of the blob + +Example Authorization event: + +```json +{ + "id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb", + "pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e", + "kind": 24242, + "content": "Upload bitcoin.pdf", + "created_at": 1708773959, + "tags": [ + ["t", "upload"], + ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"], + ["expiration", "1708858680"] + ], + "sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f" +} +``` + +## GET /list/pubkey - List Blobs + +The `/list/` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that where uploaded by the specified pubkey + +The endpoint MUST support a `since` and `until` query parameter to limit the returned blobs by thier `uploaded` date + +Servers may reject a list for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection + +### List Authorization (optional) + +The server may optionally require Authorization when listing blobs uploaded by the pubkey + +In this case the server must perform additional checks on the authorization event + +1. The `t` tag must be set to `list` + +Example Authorization event: + +```json +{ + "id": "cbb1cab9566355bfdf04e1f1fc1e655fe903ecc193e8a750092ee53beec2a0e8", + "pubkey": "a5fc3654296e6de3cda6ba3e8eba7224fac8b150fd035d66b4c3c1dc2888b8fc", + "kind": 24242, + "content": "List Blobs", + "created_at": 1708772350, + "tags": [ + ["t", "list"], + ["expiration", "1708858680"] + ], + "sig": "ff9c716f8de0f633738036472be553ce4b58dc71d423a0ef403f95f64ef28582ef82129b41d4d0ef64d2338eb4aeeb66dbc03f8b3a3ed405054ea8ecb14fa36c" +} +``` + +## DELETE /sha256 - Delete Blob + +Servers MUST accept `DELETE` requests to the `/` endpoint + +Servers may reject a delete request for any reason and should respond with the aproperate HTTP `4xx` status code and an error message explaining the reason for the rejection + +### Delete Authorization (required) + +Servers MUST accept an authorization event when deleting blobs + +Servers should perform additional checks on the authorization event + +1. The `t` tag must be set to `delete` +2. A `x` tag must be present and set to the sha256 hash of the blob being deleted + +Example Authorization event: + +```json +{ + "id": "a92868bd8ea740706d931f5d205308eaa0e6698e5f8026a990e78ee34ce47fe8", + "pubkey": "ae0063dd2c81ec469f2291ac029a19f39268bfc40aea7ab4136d7a858c3a06de", + "kind": 24242, + "content": "Delete bitcoin.pdf", + "created_at": 1708774469, + "tags": [ + ["t", "delete"], + ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553 "], + ["expiration", "1708858680"] + ], + "sig": "2ba9af680505583e3eb289a1624a08661a2f6fa2e5566a5ee0036333d517f965e0ffba7f5f7a57c2de37e00a2e85fd7999076468e52bdbcfad8abb76b37a94b0" +} +``` From 6ed1d28d7fecbdc9efdfa93559edf1e4d5ad21ab Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Wed, 22 May 2024 09:37:36 -0500 Subject: [PATCH 4/9] move blob descriptor to bud-02 --- buds/01.md | 12 ------------ buds/02.md | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/buds/01.md b/buds/01.md index 0ff59c4..813de13 100644 --- a/buds/01.md +++ b/buds/01.md @@ -58,18 +58,6 @@ Example HTTP Authorization header: Authorization: Nostr eyJpZCI6IjhlY2JkY2RkNTMyOTIwMDEwNTUyNGExNDI4NzkxMzg4MWIzOWQxNDA5ZDhiOTBjY2RiNGI0M2Y4ZjBmYzlkMGMiLCJwdWJrZXkiOiI5ZjBjYzE3MDIzYjJjZjUwOWUwZjFkMzA1NzkzZDIwZTdjNzIyNzY5MjhmZDliZjg1NTM2ODg3YWM1NzBhMjgwIiwiY3JlYXRlZF9hdCI6MTcwODc3MTIyNywia2luZCI6MjQyNDIsInRhZ3MiOltbInQiLCJnZXQiXSxbImV4cGlyYXRpb24iLCIxNzA4ODU3NTQwIl1dLCJjb250ZW50IjoiR2V0IEJsb2JzIiwic2lnIjoiMDJmMGQyYWIyM2IwNDQ0NjI4NGIwNzFhOTVjOThjNjE2YjVlOGM3NWFmMDY2N2Y5NmNlMmIzMWM1M2UwN2I0MjFmOGVmYWRhYzZkOTBiYTc1NTFlMzA4NWJhN2M0ZjU2NzRmZWJkMTVlYjQ4NTFjZTM5MGI4MzI4MjJiNDcwZDIifQ== ``` -## Blob Descriptor - -A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, and `uploaded` fields - -- `url` A public facing url this blob can retrieved from -- `sha256` The sha256 hash of the blob -- `size` The size of the blob in bytes -- `type` (optional) The MIME type of the blob -- `uploaded` The unix timestamp of when the blob was uploaded to the server - -Servers may include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support - ## Endpoints All endpoints MUST be served from the root path (eg. `https://cdn.example.com/upload`, etc). This allows clients to talk to servers interchangeably when uploading or reteriving blobs diff --git a/buds/02.md b/buds/02.md index 2501903..993b9c2 100644 --- a/buds/02.md +++ b/buds/02.md @@ -10,6 +10,18 @@ _All pubkeys MUST be in hex format_ Defines the `/upload`, `/list` and `DELETE /` enpoints +## Blob Descriptor + +A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, and `uploaded` fields + +- `url` A public facing url this blob can retrieved from +- `sha256` The sha256 hash of the blob +- `size` The size of the blob in bytes +- `type` (optional) The MIME type of the blob +- `uploaded` The unix timestamp of when the blob was uploaded to the server + +Servers may include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support + ## PUT /upload - Upload Blob The `PUT /upload` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` and `Content-Length` headers to get the MIME type and size of the data From 5c001b4abfe27f16cd7a84037f80851f2010d221 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Fri, 24 May 2024 10:30:04 -0500 Subject: [PATCH 5/9] Restrict get authorization event to a single blob or server --- buds/01.md | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/buds/01.md b/buds/01.md index 813de13..60b0e71 100644 --- a/buds/01.md +++ b/buds/01.md @@ -46,7 +46,7 @@ Servers must perform the following checks in order to validate the event 1. The `kind` must be `24242` 2. `created_at` must be in the past -3. The `expiration` tag must be set to a Unix timespamp in the future +3. The `expiration` tag must be set to a Unix timestamp in the future 4. The `t` tag must have a verb matching the intended action of the endpoint 5. Additional checks for specific endpoints. `/upload`, `/delete`, etc @@ -92,28 +92,48 @@ This ensures that if a user was to copy or reuse the redirect URL it would still ### Get Authorization (optional) -The server may optionally require authorization when fetching blobs from the `GET /` endpoint +The server may optionally require authorization when reteriving blobs from the `GET /` endpoint In this case the server MUST perform additional checks on the authorization event -1. The `t` tag must be set to `get` +1. A `t` tag MUST be present and set to `get` +2. The event MUST contain either a `server` tag containing the full URL to the server or MUST contain an `x` tag with the sha256 of the blob being retrieved If the client did not send an `Authorization` header the server must respond with the appropriate HTTP status code `401` (Unauthorized) -Example Authorization event: +Example event for retreiving a single blob: ```json { - "id": "3a2c0a58f88f86ab81ce7d111df57096e8cd9f41a75731a021e06e07c6df9d0e", - "pubkey": "96ddb0e7c4a5786a842094fee014d4c6cbb1f1627a8d75ef6fb601baeb6c5054", + "id": "06d4842b9d7f8bf72440471704de4efa9ef8f0348e366d097405573994f66294", + "pubkey": "ec0d11351457798907a3900fe465bfdc3b081be6efeb3d68c4d67774c0bc1f9a", "kind": 24242, - "content": "Get Blobs", + "content": "Get bitcoin.pdf", "created_at": 1708771927, "tags": [ ["t", "get"], - ["expiration", "1708857340"] + ["expiration", "1708857340"], + ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"] ], - "sig": "2f279b2ac0a5d5f7551f5612b69a111e038ab6b31233a78bfc98f63bd5e38ae8cb5929cf7427f0b7b2dd5eff29e769df23d93926326b0d059dc475701a41d6d3" + "sig": "22ecb5116ba143e4c3d6dc4b53d549aed6970ec455f6d25d145e0ad1fd7c0e26c465b2e92d5fdf699c7050fa43e6a41f087ef167208d4f06425f61548168fd7f" +} +``` + +Example event for retreiving multiple blobs from single server: + +```json +{ + "id": "d9484f18533d5e36f000f902a45b15a7eecf5fbfcb046789756d57ea87115dc5", + "pubkey": "b5f07faa8d3529f03bd898a23dfb3257bab8d8f5490777c46076ff9647e205dc", + "kind": 24242, + "content": "Get blobs from example.com", + "created_at": 1708771927, + "tags": [ + ["t", "get"], + ["expiration", "1708857340"], + ["server", "https://cdn.example.com/"] + ], + "sig": "e402ade78e1714d40cd6bd3091bc5f4ada8e904e90301b5a2b9b5f0b6e95ce908d4f22b15e9fb86f8268a2131f8adbb3d1f0e7e7afd1ab0f4f08acb15822a999" } ``` From f47e567147fbc26e71ec1340fd26a4f3b859f66f Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Thu, 30 May 2024 17:50:16 -0500 Subject: [PATCH 6/9] mirror blobs --- buds/04.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 buds/04.md diff --git a/buds/04.md b/buds/04.md new file mode 100644 index 0000000..0ff2b11 --- /dev/null +++ b/buds/04.md @@ -0,0 +1,29 @@ +BUD-04 +====== + +Efficiently mirroring blobs +--------------------- + +`draft` `optional` + +If a server supports the `/upload` endpoint defined in [BUD-02](./02.md) it MAY also support an optional `url` query parameter in the URL ( eg. `/upload?url=https://cdn.satellite.earth/b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf` ) + +If the `url` query parameter is specified the server MUST ignore the body and `Content-Type` of the request and download the raw binary blob data from the URL + +The server MUST verify the sha256 hash of the downloaded blob matches the `x` tag in the upload [authorization event](./02.md#upload-authorization-required) + +The server should re-use the `Content-Type` header returned from the URL to know the mime type of the blob. if none is returned it may use the file extension in the URL + +The endpoint MUST return a [Blob Descriptor](#blob-descriptor) if the mirroring was successful or an error object if it was not + +If no `url` query parameter is specified the server MUST follow the rules layed out in [BUD-02](./02.md) + +## Example Flow + +1. Client requests lists of blobs from Server A +1. Client signs an upload auth event for X +1. Client makes request `https://cdn.server-b.com/upload?url=https://cdn.server-a.com/.png` with authorization header +1. Server B receives request +1. Server B downloads blob from Server A using url query parameter +1. Server B verifies downloaded blob hash matches `x` tag in authorization header +1. Server B returns [Blob Descriptor](./02.md#blob-descriptor) From 0476b37945d84a1b584807ce9aefee9e7e42f02c Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Fri, 31 May 2024 10:50:16 -0500 Subject: [PATCH 7/9] change to /mirror endpoint --- buds/04.md | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/buds/04.md b/buds/04.md index 0ff2b11..c4e1d8d 100644 --- a/buds/04.md +++ b/buds/04.md @@ -1,29 +1,39 @@ BUD-04 ====== -Efficiently mirroring blobs +Mirroring blobs --------------------- `draft` `optional` -If a server supports the `/upload` endpoint defined in [BUD-02](./02.md) it MAY also support an optional `url` query parameter in the URL ( eg. `/upload?url=https://cdn.satellite.earth/b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf` ) +Defines the `/mirror` endpoint -If the `url` query parameter is specified the server MUST ignore the body and `Content-Type` of the request and download the raw binary blob data from the URL +## PUT /mirror - Mirror Blob -The server MUST verify the sha256 hash of the downloaded blob matches the `x` tag in the upload [authorization event](./02.md#upload-authorization-required) +A server may expose a `PUT /mirror` endpoint to allow users to copy a blob from a URL instead of uploading it -The server should re-use the `Content-Type` header returned from the URL to know the mime type of the blob. if none is returned it may use the file extension in the URL +Clients MUST pass the URL of the remote blob as a stringified JSON object in the request body + +```json +// request body +{ "url": "https://cdn.satellite.earth/b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf" } +``` + +Clients MUST set the `Authorization` header to an upload authorization event defined in [BUD-02](./02.md#upload-authorization-required) + +The `/mirror` endpoint MUST download the blob from the specified URL and verify the sha256 hash matches the `x` tag in the upload authorization event The endpoint MUST return a [Blob Descriptor](#blob-descriptor) if the mirroring was successful or an error object if it was not -If no `url` query parameter is specified the server MUST follow the rules layed out in [BUD-02](./02.md) +Servers should re-use the `Content-Type` header returned from the URL to discover the mime type of the blob. if none is returned it may use the file extension in the URL + +Servers MAY reject a mirror 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 Flow -1. Client requests lists of blobs from Server A -1. Client signs an upload auth event for X -1. Client makes request `https://cdn.server-b.com/upload?url=https://cdn.server-a.com/.png` with authorization header -1. Server B receives request -1. Server B downloads blob from Server A using url query parameter -1. Server B verifies downloaded blob hash matches `x` tag in authorization header +1. Client signs authorization event and uploads blob to Server A +1. Server A returns blob descriptor with `url` +1. Client sends the `url` to Server B `/mirror` using the original authorization event +1. Server B downloads blob from Server A using the url +1. Server B verifies downloaded blob hash matches `x` tag in authorization event 1. Server B returns [Blob Descriptor](./02.md#blob-descriptor) From 8d2b6b1da15b01ec69e1ce4ab70ffef9051efa84 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Fri, 31 May 2024 14:27:26 -0500 Subject: [PATCH 8/9] add mirror to readme --- README.md | 2 ++ buds/01.md | 2 +- buds/02.md | 2 +- buds/04.md | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4879df7..ee195af 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ Blossom Servers expose four endpoints for managing blobs - `Authentication` _(optional)_: Signed [nostr event](./buds/01.md#list-authorization-optional) - `DELETE /` [BUD-2](./buds/02.md#delete-sha256---delete-blob) - `Authentication`: Signed [nostr event](./buds/01.md#delete-authorization-required) +- `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob) + - `Authentication`: Signed [nostr event](./buds/01.md#upload-authorization-required) ## Protocol specification (BUDs) diff --git a/buds/01.md b/buds/01.md index 813de13..813f8c0 100644 --- a/buds/01.md +++ b/buds/01.md @@ -2,7 +2,7 @@ BUD-01 ====== Server requirements and blob reterival ---------------------- +-------------------------------------- `draft` `mandatory` diff --git a/buds/02.md b/buds/02.md index 993b9c2..e645943 100644 --- a/buds/02.md +++ b/buds/02.md @@ -2,7 +2,7 @@ BUD-02 ====== Blob upload and management ---------------------- +-------------------------- `draft` `optional` diff --git a/buds/04.md b/buds/04.md index c4e1d8d..0b0191b 100644 --- a/buds/04.md +++ b/buds/04.md @@ -2,7 +2,7 @@ BUD-04 ====== Mirroring blobs ---------------------- +--------------- `draft` `optional` From 5800e150d2e4c9f28e37f6882637a9ec437b96d8 Mon Sep 17 00:00:00 2001 From: hzrd149 <8001706+hzrd149@users.noreply.github.com> Date: Wed, 5 Jun 2024 21:21:13 -0500 Subject: [PATCH 9/9] typo fix --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ee195af..5bbee22 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,15 @@ Blossom Servers expose four 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-2](./buds/02.md#put-upload---upload-blob) - - `Authentication`: Signed [nostr event](./buds/01.md#upload-authorization-required) + - `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required) - Return a blob descriptor - `GET /list/` [BUD-02](./buds/02.md#get-listpubkey---list-blobs) - Returns an array of blob descriptors - - `Authentication` _(optional)_: Signed [nostr event](./buds/01.md#list-authorization-optional) -- `DELETE /` [BUD-2](./buds/02.md#delete-sha256---delete-blob) - - `Authentication`: Signed [nostr event](./buds/01.md#delete-authorization-required) + - `Authentication` _(optional)_: Signed [nostr event](./buds/02.md#list-authorization-optional) +- `DELETE /` [BUD-02](./buds/02.md#delete-sha256---delete-blob) + - `Authentication`: Signed [nostr event](./buds/02.md#delete-authorization-required) - `PUT /mirror` [BUD-04](./buds/04.md#put-mirror---mirror-blob) - - `Authentication`: Signed [nostr event](./buds/01.md#upload-authorization-required) + - `Authentication`: Signed [nostr event](./buds/02.md#upload-authorization-required) ## Protocol specification (BUDs)