# BUD-01 ## Server requirements and blob retrieval `draft` `mandatory` _All pubkeys MUST be in hex format_ ## Cross origin headers Servers MUST set the `Access-Control-Allow-Origin: *` header on all responses to ensure compatibility with applications hosted on other domains. For [preflight](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests) (`OPTIONS`) requests, servers MUST also set, at minimum, the `Access-Control-Allow-Headers: Authorization, *` and `Access-Control-Allow-Methods: GET, HEAD, PUT, DELETE` headers. The header `Access-Control-Max-Age: 86400` MAY be set to cache the results of a preflight request for 24 hours. ## Error responses Every time a server sends an error response (HTTP status codes >=400), it may include a human-readable header `X-Reason` that can be displayed to the user. ## Endpoints All endpoints MUST be served from the root of the domain (eg. the `/upload` endpoint MUST be accessible from `https://cdn.example.com/upload`, etc). This allows clients to talk to servers interchangeably when uploading or retrieving blobs ## GET /sha256 - Get Blob The `GET /` endpoint MUST return the contents of the blob in the response body. the `Content-Type` header SHOULD beset to the appropriate MIME-type 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` ### 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 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 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) The server may optionally require authorization when retrieving blobs from the `GET /` endpoint In this case, the server MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then perform the following additional checks: 1. A `t` tag MUST be present and set to `get` 2. The authorization token MUST contain either a `server` tag (limiting the token to specific servers) or MUST contain at least one `x` tag matching the sha256 hash of the blob being retrieved (scoping the token to specific blob hashes). see [BUD-11](./11.md#tag-scoping). If the client did not send an `Authorization` header the server must respond with the appropriate HTTP status code `401` (Unauthorized) Example authorization token for retrieving a single blob: ```json { "id": "06d4842b9d7f8bf72440471704de4efa9ef8f0348e366d097405573994f66294", "pubkey": "ec0d11351457798907a3900fe465bfdc3b081be6efeb3d68c4d67774c0bc1f9a", "kind": 24242, "content": "Get bitcoin.pdf", "created_at": 1708771927, "tags": [ ["t", "get"], ["expiration", "1708857340"], ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"] ], "sig": "22ecb5116ba143e4c3d6dc4b53d549aed6970ec455f6d25d145e0ad1fd7c0e26c465b2e92d5fdf699c7050fa43e6a41f087ef167208d4f06425f61548168fd7f" } ``` Example authorization token for retrieving 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", "cdn.example.com"] ], "sig": "e402ade78e1714d40cd6bd3091bc5f4ada8e904e90301b5a2b9b5f0b6e95ce908d4f22b15e9fb86f8268a2131f8adbb3d1f0e7e7afd1ab0f4f08acb15822a999" } ``` ## 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 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 ## 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 See [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests) for more details