Skip to content

Commit

Permalink
[FIX] cross language compatible meta subject (#372)
Browse files Browse the repository at this point in the history
BREAKING CHANGE
  • Loading branch information
András Tóth authored Sep 27, 2022
1 parent adf39af commit 6bdf6ff
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
41 changes: 41 additions & 0 deletions nats-base-client/base64.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export class Base64Codec {
static encode(bytes: string | Uint8Array): string {
if (typeof bytes === "string") {
return btoa(bytes);
}
const a = Array.from(bytes);
return btoa(String.fromCharCode(...a));
}

static decode(s: string, binary = false): Uint8Array | string {
const bin = atob(s);
if (!binary) {
return bin;
}
return Uint8Array.from(bin, (c) => c.charCodeAt(0));
}
}

export class Base64UrlCodec {
static encode(bytes: string | Uint8Array): string {
return Base64UrlCodec.toB64URLEncoding(Base64Codec.encode(bytes));
}

static decode(s: string, binary = false): Uint8Array | string {
return Base64Codec.decode(Base64UrlCodec.fromB64URLEncoding(s), binary);
}

static toB64URLEncoding(b64str: string): string {
return b64str
.replace(/=/g, "")
.replace(/\+/g, "-")
.replace(/\//g, "_");
}

static fromB64URLEncoding(b64str: string): string {
// pads are % 4, but not necessary on decoding
return b64str
.replace(/_/g, "/")
.replace(/-/g, "+");
}
}
5 changes: 3 additions & 2 deletions nats-base-client/objectstore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
StreamInfoRequestOptions,
} from "./types.ts";
import { validateBucket, validateKey } from "./kv.ts";
import { Base64UrlCodec } from "./base64.ts";
import { JSONCodec } from "./codec.ts";
import { nuid } from "./nuid.ts";
import { deferred } from "./util.ts";
Expand Down Expand Up @@ -248,7 +249,7 @@ export class ObjectStoreImpl implements ObjectStore {
return Promise.reject(error);
}

const meta = `$O.${this.name}.M.${obj}`;
const meta = this._metaSubject(obj);
try {
const m = await this.jsm.streams.getMessage(this.stream, {
last_by_subj: meta,
Expand Down Expand Up @@ -674,7 +675,7 @@ export class ObjectStoreImpl implements ObjectStore {
}

_metaSubject(n: string): string {
return `$O.${this.name}.M.${n}`;
return `$O.${this.name}.M.${Base64UrlCodec.encode(n)}`;
}

_metaSubjectAll(): string {
Expand Down
10 changes: 8 additions & 2 deletions tests/objectstore_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { assertRejects } from "https://deno.land/std@0.152.0/testing/asserts.ts"
import { equals } from "https://deno.land/std@0.152.0/bytes/mod.ts";
import { ObjectInfo, ObjectStoreMeta } from "../nats-base-client/types.ts";
import { SHA256 } from "../nats-base-client/sha256.js";
import { Base64UrlCodec } from "../nats-base-client/base64.ts";

function readableStreamFrom(data: Uint8Array): ReadableStream<Uint8Array> {
return new ReadableStream<Uint8Array>({
Expand Down Expand Up @@ -676,9 +677,14 @@ Deno.test("objectstore - sanitize", async () => {
const info = await os.status({
subjects_filter: ">",
});
assertEquals(info.streamInfo.state?.subjects!["$O.test.M.has_dots_here"], 1);
assertEquals(
info.streamInfo.state.subjects!["$O.test.M.the_spaces_are_here"],
info.streamInfo.state
?.subjects![`$O.test.M.${Base64UrlCodec.encode("has_dots_here")}`],
1,
);
assertEquals(
info.streamInfo.state
.subjects![`$O.test.M.${Base64UrlCodec.encode("the_spaces_are_here")}`],
1,
);

Expand Down

0 comments on commit 6bdf6ff

Please sign in to comment.