Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fallback to manifest values if they're not specified in ExtismPluginOptions #73

Merged
merged 35 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c8070a4
fix: fallback to manifest values if they're not specified in ExtismPl…
mhmd-azeez Jun 25, 2024
fb9b1a3
add tests
mhmd-azeez Jun 25, 2024
7e73e7f
log manifest
mhmd-azeez Jun 25, 2024
d004368
fix tests
mhmd-azeez Jun 25, 2024
24c1f8a
refactor
mhmd-azeez Jun 26, 2024
d3e0dbc
fix tests
mhmd-azeez Jun 26, 2024
5f658d4
fix property names to match the json structure
mhmd-azeez Jun 26, 2024
99618e2
add manifest timeout
mhmd-azeez Jun 26, 2024
4d2d57d
fix tests
mhmd-azeez Jun 26, 2024
70b1e71
fix call timeout
mhmd-azeez Jun 26, 2024
4c458e8
fix tests
mhmd-azeez Jun 26, 2024
4fe346f
make manifest property names consistent with ExtismPluginOptions
mhmd-azeez Jun 26, 2024
4568274
memory options
mhmd-azeez Jun 26, 2024
0bff08b
add tests for memory
mhmd-azeez Jun 27, 2024
dd3908c
add more tests
mhmd-azeez Jun 27, 2024
3248e19
add timeout test
mhmd-azeez Jun 27, 2024
43e75ac
add cancellation to call context
mhmd-azeez Jun 27, 2024
4f4edc8
add guard before host functions
mhmd-azeez Jun 30, 2024
7fdd7f6
timeout.wasm => sleep.wasm
mhmd-azeez Jul 1, 2024
aa3b507
use worker.terminate to cancel a call
mhmd-azeez Jul 2, 2024
9914611
refactor
mhmd-azeez Jul 2, 2024
c033ea6
fix build
mhmd-azeez Jul 2, 2024
355d1ad
revert background plugin cancellation work
mhmd-azeez Jul 2, 2024
4bf6cc9
refactor
mhmd-azeez Jul 2, 2024
c68125d
bring back cancellation
mhmd-azeez Jul 2, 2024
b6300e4
fix build
mhmd-azeez Jul 2, 2024
6404b64
refactor
mhmd-azeez Jul 4, 2024
5032877
remove timeout
mhmd-azeez Jul 4, 2024
2a8f747
apply chris' suggestions
mhmd-azeez Jul 7, 2024
8cbfdd8
use log_error instead of error_set
mhmd-azeez Jul 7, 2024
b868ec5
formatting
mhmd-azeez Jul 7, 2024
a780636
use release build
mhmd-azeez Jul 7, 2024
9630a69
fix tests
mhmd-azeez Jul 7, 2024
13fa089
fix test
mhmd-azeez Jul 7, 2024
35495de
pass worker into BackgroundPlugin's ctor
mhmd-azeez Jul 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,22 @@ export type ManifestWasm = (
export interface Manifest {
wasm: Array<ManifestWasm>;
config?: PluginConfigLike;
allowedPaths?: { [key: string]: string } | undefined;

/**
* A list of allowed hostnames. Wildcard subdomains are supported via `*`.
*
* Requires the plugin to run in a worker using `runInWorker: true`.
*
* @example
* ```ts
* await createPlugin('path/to/some/wasm', {
* runInWorker: true,
* allowedHosts: ['*.example.com', 'www.dylibso.com']
* })
* ```
*/
allowedHosts?: string[] | undefined;
}

/**
Expand Down
60 changes: 60 additions & 0 deletions src/mod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,31 @@ if (typeof WebAssembly === 'undefined') {
await plugin.close();
}
});

test('we fallback to Manifest.allowedHosts if ExtismPluginOptions.allowedHosts is not specified', async () => {
const plugin = await createPlugin(
{ wasm: [{ name: 'main', url: 'https://localhost:8124/wasm/http.wasm' }], allowedHosts: ['*.typicode.com'] },
{ useWasi: true, functions: {}, runInWorker: true },
);

try {
const [err, data] = await plugin
.call('http_get', '{"url": "https://jsonplaceholder.typicode.com/todos/1"}')
.then(
(data) => [null, data],
(err) => [err, null],
);
assert(err === null);
assert.deepEqual(data.json(), {
userId: 1,
id: 1,
title: 'delectus aut autem',
completed: false,
});
} finally {
await plugin.close();
}
});
}

test('createPlugin fails as expected when calling unknown function', async () => {
Expand Down Expand Up @@ -611,6 +636,25 @@ if (typeof WebAssembly === 'undefined') {
}
});

test('we fallback to Manifest.config if ExtismPluginOptions.config is not specified', async () => {
const plugin = await createPlugin(
{ wasm: [{ url: 'https://localhost:8124/wasm/hello_haskell.wasm' }], config: { greeting: 'Howdy' } },
{ useWasi: true }
);

try {
let output = await plugin.call('testing', 'John');

assert.equal(output?.string(), 'Howdy, John');

output = await plugin.call('testing', 'Ben');
assert(output !== null);
assert.equal(output?.string(), 'Howdy, Ben');
} finally {
await plugin.close();
}
});

// TODO(chrisdickinson): this turns out to be pretty tricky to test, since
// deno and node's wasi bindings bypass JS entirely and write directly to
// their respective FDs. I'm settling for tests that exercise both behaviors.
Expand Down Expand Up @@ -671,6 +715,22 @@ if (typeof WebAssembly === 'undefined') {
}
});

test('we fallback to Manifest.allowedPaths if ExtismPluginOptions.allowedPaths is not specified', async () => {
const plugin = await createPlugin(
{ wasm: [{ url: 'https://localhost:8124/wasm/fs.wasm'}], allowedPaths: { '/mnt': 'tests/data' } },
{ useWasi: true }
);

try {
const output = await plugin.call('run_test', '');
assert(output !== null);
const result = output.string();
assert.equal(result, 'hello world!');
} finally {
await plugin.close();
}
});

test('linking to a wasi command side-module works', async () => {
const plugin = await createPlugin(
{
Expand Down
12 changes: 10 additions & 2 deletions src/mod.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CAPABILITIES } from './polyfills/deno-capabilities.ts';

import type { ManifestLike, InternalConfig, ExtismPluginOptions, Plugin } from './interfaces.ts';
import type { Manifest, ManifestLike, InternalConfig, ExtismPluginOptions, Plugin } from './interfaces.ts';

import { toWasmModuleData as _toWasmModuleData } from './manifest.ts';

Expand Down Expand Up @@ -73,6 +73,14 @@ export async function createPlugin(
opts.useWasi ??= false;
opts.enableWasiOutput ??= opts.useWasi ? CAPABILITIES.extismStdoutEnvVarSet : false;
opts.functions = opts.functions || {};

const m = await Promise.resolve(manifest)
if ((m as Manifest).wasm) {
opts.allowedPaths ??= (m as Manifest).allowedPaths;
opts.allowedHosts ??= (m as Manifest).allowedHosts;
opts.config ??= (m as Manifest).config;
}

opts.allowedPaths ??= {};
// TODO(chrisdickinson): reset this to `CAPABILITIES.hasWorkerCapability` once we've fixed https://github.com/extism/js-sdk/issues/46.
opts.runInWorker ??= false;
Expand All @@ -91,7 +99,7 @@ export async function createPlugin(
);
}

const [names, moduleData] = await _toWasmModuleData(await Promise.resolve(manifest), opts.fetch ?? fetch);
const [names, moduleData] = await _toWasmModuleData(m, opts.fetch ?? fetch);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to support manifest options when the manifest is provided via fetch, we might rework _toWasmModuleData to return a third item, manifestOpts, then perform this call before normalizing the options in this function.

intoManifest is the chokepoint at which all the disparate input types are unified into something "manifest-like", so we could extract manifest-provided options here and then use them in createPlugin to finish normalizing the input options.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this what you meant?

const manifestOpts : ManifestOptions = {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! That's perfect, thank you!


const ic: InternalConfig = {
allowedHosts: opts.allowedHosts as [],
Expand Down
Loading