Skip to content

Latest commit

 

History

History
89 lines (73 loc) · 4.38 KB

r2.md

File metadata and controls

89 lines (73 loc) · 4.38 KB

R2

R2 is object storage. A Worker reaches a bucket through an r2_buckets binding. celld stores the objects in the fleet bucket that the node opened with --bucket, so R2 has the durability of that object store. On a node without a fleet bucket, every R2 method fails. Read the Workers API reference for the API.

Example

The R2 example reads, writes, and deletes objects in an R2 bucket.

API

  • get(key, { range, onlyIf }) returns an R2ObjectBody with a streamed body, or null. A range is an offset, a length, a suffix, or a Range header.
  • head(key) returns the object record without the body.
  • put(key, value, { httpMetadata, customMetadata, onlyIf }) takes a string, an ArrayBuffer, a typed array, a Blob, or a ReadableStream. A refused condition returns null.
  • delete(keys) removes one key or a list of keys.
  • list({ prefix, delimiter, cursor, startAfter }) returns a page of objects.
  • createMultipartUpload(key) returns a handle. uploadPart(number, value) sends one part, and complete(parts) assembles the object.

Keys and storage

Each binding has its own bucket_name, and celld stores key <key> as the object r2/<bucket_name>/<key>. A key is 1 to 1024 bytes. A streamed put() body that grows past 8 MiB becomes a multipart upload. delete() removes up to 1000 keys in one call. celld has no public bucket URL, no presigned URL, and no S3 endpoint, so put a Worker in front of the bytes to publish them.

The object store keeps some keys in a percent-encoded form: a key with a non-ASCII character, a control character, or one of % \ { } ^ ` [ ] " < > ~ # | * ?. For example, přehled.html becomes r2/<bucket_name>/p%C5%99ehled.html. Each empty segment becomes %, so photos/ becomes r2/<bucket_name>/photos/%, and a/b, /a/b, a//b, and a/b/ are four different objects, as in Cloudflare R2. list() returns the decoded key, but it sorts by the encoded form and compares startAfter with the encoded form. Cloudflare R2 sorts by UTF-8 bytes. For example, Cloudflare R2 returns a~ after startAfter: "aa", but celld compares a%7E with aa and skips the key. A cursor from a celld listing does not have this problem.

list() fails when it reaches an object that another tool wrote with a percent-encoded key that is not UTF-8, such as a%FF.

celld 0.5.1 and earlier removed each empty segment from a key. An object that such a version wrote under photos/ stays under photos, and list() returns it as photos.

Multipart uploads

A multipart upload lives on the node that opened it. Read Multipart upload for the part rules. A part that arrives before its predecessor waits in memory, up to 256 MiB, and celld then refuses a further part. A waiting part can be replaced. A part that already went to the object store cannot, and celld refuses that write.

Differences from Cloudflare

  • An R2 binding uses the fleet bucket under r2/<bucket_name>/.
  • The five content headers are stored as headers. customMetadata, cacheExpiry, the checksums, and the storage class are stored together as one JSON value, under the celld-r2 user-metadata name (celld_r2 on Azure Blob Storage, which refuses a hyphen in a metadata name).
  • An object another tool wrote still reads through the binding. Its user metadata becomes its customMetadata, and its headers become its httpMetadata. Use celld r2 put to write the complete record.
  • celld r2 get|head|put|delete|list replaces wrangler r2 object. The command reads the fleet bucket directly, so it needs no running node.
  • An object version equals its content ETag, so identical content produces the same version.
  • ssecKey and jurisdiction are unavailable.
  • A conditional write cannot use a streamed body larger than 8 MiB.
  • createMultipartUpload() does not accept a checksum.
  • A multipart upload cannot resume on another node or after a restart. celld also cannot replace a part that the object store already holds.
  • Out-of-order parts can use at most 256 MiB of memory, and completion cannot change the stored part order.

The Cloudflare compatibility page lists the runtime APIs and the unsupported services.