4.0 KiB
rackspace-cdn-adapter.ops
Purpose
Reusable Cloud Files HTTP operations used by RackspaceCdnAdapter: object GET (objectGet), HEAD (objectHead), PUT (objectPut), DELETE (objectDelete), Range read (objectPartial), streaming GET (objectStream), and parseMetadata for HEAD response headers. Each function takes a CallContext (fetch + endpoint + token + container + region + signal + retry + headers) and returns the result; the adapter composes them with the OTel wrapper and signal guards.
Split out so tests can exercise each operation in isolation without spinning up a full adapter.
Features
objectGet— full-body GET, 404/410 →undefined, 401/403/other →errorForStatusthrow, retry on transient.objectHead— HEAD with retry.objectPut— PUT with auth token, content-type and content-length headers.objectDelete— DELETE; returnstrue/falsefor 2xx/404 outcomes.objectPartial— Range read; delegates 200/206/416 disambiguation to@suaveplan/storage-http'sconsumeRangeResponse; increments range-fallback counter on 200.objectStream— single GET without retry; returns the rawResponseso the caller can pumpbody.getReader().parseMetadata— extractsStorageMetadatafrom HEAD response headers.
Usage: Basic
import { objectGet } from "@suaveplan/storage-cdn-rackspace";
const bytes = await objectGet({
fetch, storageEndpoint, token, container, region, signal: undefined, retry: {}, headers: {}
}, "a/b.bin");
Usage: Advanced
import {
objectHead,
objectPartial,
parseMetadata,
} from "@suaveplan/storage-cdn-rackspace";
async function existsAndMeta(ctx) {
const response = await objectHead(ctx, "a/b.bin");
if (response.status === 404) return null;
return parseMetadata(response);
}
async function readSlice(ctx, key, off, len) {
return objectPartial(ctx, key, off, len);
}
API Reference
interface CallContext
{ fetch, storageEndpoint, token, container, region, signal, retry, headers }.
objectGet(ctx, key): Promise<Uint8Array | undefined>
Returns undefined on 404/410, the response bytes on 200, throws on other non-ok.
objectHead(ctx, key): Promise<Response>
Raw response — caller decides.
objectPut(ctx, key, body, contentType): Promise<void>
Throws on non-ok. The caller-supplied contentType overrides headers["content-type"].
objectDelete(ctx, key): Promise<boolean>
true on 2xx, false on 404/410, throws on other non-ok.
objectPartial(ctx, key, offset, length): Promise<Uint8Array | null>
null on 404/410, sliced bytes from 206 or 200-fallback; increments range_fallback_total when origin returned 200.
objectStream(ctx, key): Promise<Response>
Throws on non-ok; otherwise returns the raw response with the body intact for the caller to pump.
parseMetadata(response): StorageMetadata
Extracts Content-Length (defaulting size to 0 when absent or unparsed), Last-Modified (defaulting to Date.now() when missing or unparseable).
Implementation Notes
- The Range read uses
@suaveplan/storage-http'sconsumeRangeResponsedirectly to avoid duplicating the 200/206/416 disambiguation. The counter increment is wired locally so the metric carriesprovider="rackspace". objectStreamdoes NOT go throughretryWithBackoff— streaming responses can't be retried mid-stream without buffering, and the underlying retry classifier is response-shape rather than stream-shape.parseMetadatareturns a usable shape even when the origin omitsContent-Length(some Swift configurations don't set it on partial-content responses). Callers that need exact size must callgetItemSizeagainst an origin that does.- The
baseHeadershelper always re-merges the auth token last so a caller-suppliedx-auth-tokencannot override it accidentally. objectGetand friends consumectx.retrydirectly so callers customise retry per-operation if needed — the adapter currently passes one shared retry config per instance.