Liking cljdoc? Tell your friends :D

com.heavycomputation.cloudflare.r2

Cloudflare R2 object storage.

R2 speaks the S3 API, so this namespace signs requests with AWS Signature V4 and sends them over the JDK's http client (see the internal namespaces) — no AWS SDK, no dependencies. The public API:

(bucket m) ; build a bucket handle (put bucket key body) ; upload an object, multipart automatically (get-bytes bucket key) ; download; also head/exists?/get/get-stream (delete bucket key) ; remove; also delete-many for batches (list bucket opts) ; enumerate by prefix; also list-seq (lazy) (presigned-url bucket k) ; time-limited download/upload URL (request bucket req) ; escape hatch to the raw signed-S3 surface

put hides the single-PUT vs. multipart decision: small objects go up in one request, large objects (and unknown-length streams) are split into parts that upload concurrently and retry individually, so a network blip only costs the part that failed rather than the whole transfer.

get/head/list shadow clojure.core names, so this namespace excludes them; refer to it qualified (e.g. r2/get).

Cloudflare R2 object storage.

R2 speaks the S3 API, so this namespace signs requests with AWS Signature V4
and sends them over the JDK's http client (see the `internal` namespaces) —
no AWS SDK, no dependencies. The public API:

  (bucket m)                ; build a bucket handle
  (put bucket key body)     ; upload an object, multipart automatically
  (get-bytes bucket key)    ; download; also head/exists?/get/get-stream
  (delete bucket key)       ; remove; also delete-many for batches
  (list bucket opts)        ; enumerate by prefix; also list-seq (lazy)
  (presigned-url bucket k)  ; time-limited download/upload URL
  (request bucket req)      ; escape hatch to the raw signed-S3 surface

`put` hides the single-PUT vs. multipart decision: small objects go up in one
request, large objects (and unknown-length streams) are split into parts that
upload concurrently and retry individually, so a network blip only costs the
part that failed rather than the whole transfer.

`get`/`head`/`list` shadow `clojure.core` names, so this namespace excludes
them; refer to it qualified (e.g. `r2/get`).
raw docstring

bucketclj

(bucket {:keys [account-id access-key-id secret-access-key bucket region]
         :or {region "auto"}})

Build an R2 bucket handle from a config map:

{:account-id "abc123" :access-key-id "..." :secret-access-key "..." :bucket "uploads" :region "auto"} ; optional, see note below

:region is the SigV4 signing region. R2 accepts only its own region codes (auto, weur, enam, wnam, eeur, apac, oc) and rejects AWS regions like eu-west-2 with InvalidRegionName. Because we sign requests ourselves rather than going through an SDK's endpoint resolver, we can hand R2 its own code directly; auto (the default) works for every bucket regardless of where it lives.

Returns {:client <s3 client> :bucket <name>}, suitable for put and request.

Build an R2 bucket handle from a config map:

  {:account-id        "abc123"
   :access-key-id     "..."
   :secret-access-key "..."
   :bucket            "uploads"
   :region            "auto"}   ; optional, see note below

`:region` is the SigV4 *signing* region. R2 accepts only its own region codes
(`auto`, `weur`, `enam`, `wnam`, `eeur`, `apac`, `oc`) and rejects AWS regions
like `eu-west-2` with `InvalidRegionName`. Because we sign requests ourselves
rather than going through an SDK's endpoint resolver, we can hand R2 its own
code directly; `auto` (the default) works for every bucket regardless of where
it lives.

Returns `{:client <s3 client> :bucket <name>}`, suitable for `put` and
`request`.
raw docstring

content-type-forclj

(content-type-for k)

Infer a Content-Type from the extension of object key k, defaulting to "application/octet-stream" when the extension is unknown or absent.

Infer a Content-Type from the extension of object key `k`, defaulting to
"application/octet-stream" when the extension is unknown or absent.
raw docstring

deleteclj

(delete {:keys [client bucket]} key)

Delete the object at key. Idempotent — succeeds whether or not it existed. Returns true.

Delete the object at `key`. Idempotent — succeeds whether or not it existed.
Returns `true`.
raw docstring

delete-manyclj

(delete-many bucket keys)

Delete many objects in one (or, above 1000 keys, a few) batched requests. Returns {:deleted [key …] :errors [{:key :code :message} …]}.

Delete many objects in one (or, above 1000 keys, a few) batched requests.
Returns `{:deleted [key …] :errors [{:key :code :message} …]}`.
raw docstring

exists?clj

(exists? bucket key)

Whether an object exists under key.

Whether an object exists under `key`.
raw docstring

getclj

(get {:keys [client bucket]} key)

Fetch an object: its metadata (see head) plus :body bound to a byte[], or nil if it doesn't exist. Buffers the whole object in memory — use get-stream for large objects.

Fetch an object: its metadata (see `head`) plus `:body` bound to a `byte[]`,
or `nil` if it doesn't exist. Buffers the whole object in memory — use
`get-stream` for large objects.
raw docstring

get-bytesclj

(get-bytes {:keys [client bucket]} key)

Fetch an object's contents as a byte[], or nil if it doesn't exist. Reads the whole object into memory — use get-stream for large objects.

Fetch an object's contents as a `byte[]`, or `nil` if it doesn't exist.
Reads the whole object into memory — use `get-stream` for large objects.
raw docstring

get-streamclj

(get-stream {:keys [client bucket]} key)

Fetch an object for streaming: returns its metadata (see head) plus :body bound to an InputStream, or nil if it doesn't exist. The caller must close :body (e.g. with with-open) — it holds the live connection.

Fetch an object for streaming: returns its metadata (see `head`) plus `:body`
bound to an `InputStream`, or `nil` if it doesn't exist. The caller must close
`:body` (e.g. with `with-open`) — it holds the live connection.
raw docstring

(head {:keys [client bucket]} key)

Object metadata without its body, or nil if the object doesn't exist. Returns {:content-type :bytes :etag :last-modified :cache-control :metadata}.

Object metadata without its body, or `nil` if the object doesn't exist.
Returns `{:content-type :bytes :etag :last-modified :cache-control
:metadata}`.
raw docstring

listclj

(list {:keys [client bucket]}
      &
      [{:keys [prefix delimiter max-keys continuation-token]}])

List one page of objects. Options: :prefix restrict to keys starting with this string :delimiter roll keys up to common prefixes (e.g. "/" for folders) :max-keys page size (S3 default/cap is 1000) :continuation-token fetch the page following a previous truncated result

Returns {:objects [{:key :size :etag :last-modified} …] :common-prefixes ["a/" …] :truncated? bool :continuation-token <token-or-nil>}. When :truncated? is true, pass :continuation-token back to get the next page (or use list-seq).

List one page of objects. Options:
  :prefix              restrict to keys starting with this string
  :delimiter           roll keys up to common prefixes (e.g. "/" for folders)
  :max-keys            page size (S3 default/cap is 1000)
  :continuation-token  fetch the page following a previous truncated result

Returns `{:objects [{:key :size :etag :last-modified} …]
          :common-prefixes ["a/" …]
          :truncated? bool
          :continuation-token <token-or-nil>}`. When `:truncated?` is true,
pass `:continuation-token` back to get the next page (or use `list-seq`).
raw docstring

list-seqclj

(list-seq bucket & [opts])

Lazily enumerate every object matching opts (same options as list, minus :continuation-token), transparently following pagination. Each element is an object map {:key :size :etag :last-modified}. Pages are fetched as the seq is consumed, so realizing it performs I/O and may throw.

Lazily enumerate every object matching `opts` (same options as `list`, minus
`:continuation-token`), transparently following pagination. Each element is an
object map `{:key :size :etag :last-modified}`. Pages are fetched as the seq
is consumed, so realizing it performs I/O and may throw.
raw docstring

presigned-urlclj

(presigned-url {:keys [client bucket]}
               key
               &
               [{:keys [method expires] :or {method :get expires 900}}])

Build a presigned URL for key that grants temporary, credential-free access — anyone with the URL can use it until it expires. Options: :method :get (default) for downloads, :put for direct browser uploads :expires validity window in seconds (default 900 = 15 min; max 7 days)

For :put, a client PUTs the file straight to the returned URL, so large uploads never pass through your server. Returns the URL string.

Build a presigned URL for `key` that grants temporary, credential-free access
— anyone with the URL can use it until it expires. Options:
  :method   :get (default) for downloads, :put for direct browser uploads
  :expires  validity window in seconds (default 900 = 15 min; max 7 days)

For `:put`, a client `PUT`s the file straight to the returned URL, so large
uploads never pass through your server. Returns the URL string.
raw docstring

putclj

(put {:keys [client bucket]} key body & [opts])

Upload body to bucket under key, choosing single-PUT or multipart automatically.

body may be a java.io.File, byte[], or InputStream. Content-Type is inferred from the key's extension unless overridden.

Options (all optional): :content-type override the inferred Content-Type :multipart-threshold bytes at/above which multipart kicks in (~100 MB) :part-size multipart part size in bytes (~100 MB) :concurrency number of parts uploaded at once (4) :metadata map of custom metadata (stored as x-amz-meta-*) :cache-control Cache-Control header value

Returns {:key key :bucket bucket :etag etag :bytes n}. Throws ex-info on failure; an interrupted multipart upload is aborted first.

Upload `body` to `bucket` under `key`, choosing single-PUT or multipart
automatically.

`body` may be a `java.io.File`, `byte[]`, or `InputStream`. Content-Type is
inferred from the key's extension unless overridden.

Options (all optional):
  :content-type         override the inferred Content-Type
  :multipart-threshold  bytes at/above which multipart kicks in (~100 MB)
  :part-size            multipart part size in bytes (~100 MB)
  :concurrency          number of parts uploaded at once (4)
  :metadata             map of custom metadata (stored as x-amz-meta-*)
  :cache-control        Cache-Control header value

Returns `{:key key :bucket bucket :etag etag :bytes n}`. Throws `ex-info` on
failure; an interrupted multipart upload is aborted first.
raw docstring

requestclj

(request {:keys [client bucket]} {:keys [key] :as req})

Escape hatch to the raw signed-S3 surface for ops put doesn't cover (range gets, conditional ops, tagging, listing, ...).

req is {:method :key :query :headers :body}: :method is the HTTP verb, :key (optional) the object key, :query/:headers maps, :body a byte[]. The path is built from the handle's bucket (and :key if given). Returns the raw response {:status :headers :body} without throwing on 4xx/5xx, so the caller controls error handling.

Escape hatch to the raw signed-S3 surface for ops `put` doesn't cover (range
gets, conditional ops, tagging, listing, ...).

`req` is `{:method :key :query :headers :body}`: `:method` is the HTTP verb,
`:key` (optional) the object key, `:query`/`:headers` maps, `:body` a byte[].
The path is built from the handle's bucket (and `:key` if given). Returns the
raw response `{:status :headers :body}` without throwing on 4xx/5xx, so the
caller controls error handling.
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close