Integration with Otoroshi
Wasmo plugins can be used with Otoroshi to build plugins to manipulate http requests.
Click here to read an article about Otoroshi and Wasmo.
§Bind Wasmo to Otoroshi
A convenient way to leverage Wasmo's plugins is by integrating Wasmo with Otoroshi. This enables manipulation of HTTP requests and responses within Otoroshi, facilitating the creation of mock API backends and addressing various other scenarios.
We can connect Otoroshi with Wasmo.
Steps are really straightforward :
- navigate to the danger zone of your Otoroshi instance (create a new Otoroshi instance if not already done)
- connect Wasmo by specify the URL field where your Wasmo is deployed : http://localhost:5001 (following the Getting Started tutorial).
- save the configuration
Congratulations! You can now use your Wasmo plugins in the Otoroshi plugins :
§Expose Wasmo behind Otoroshi
You can configure Wasmo to delegate its authentication to Otoroshi. You should use this configuration in a production environment.
You can follow this tutorial to deploy Otoroshi and Wasmo, both locally, and to secure access to Wasmo.
To have more informations about Otoroshi and Wasmo, you can follow the two tutorials:
§Otoroshi plugins
Wasmo can initialize plugins with predefined Otoroshi templates, which you can find directly on the UI.
§Wasm Pre-Route
This plugin can be used to use a wasm plugin as in pre-route phase
export function execute() {
let context = JSON.parse(Host.inputString());
if (context.request.headers["foo"] === "bar") {
const out = {
result: true
};
Host.outputString(JSON.stringify(out));
} else {
const error = {
result: false,
error: {
message: "you're not authorized",
status: 401
}
};
Host.outputString(JSON.stringify(error));
}
return 0;
}
§Wasm Request Transformer
Transform the content of the request with a wasm plugin
export function execute() {
let context = JSON.parse(Host.inputString())
Host.outputString(JSON.stringify({
...context,
method: "POST",
headers: {
...context.otoroshi_request.headers,
OTOROSHI_WASM_PLUGIN_ID: "OTOROSHI_WASM_REQUEST_TRANSFORMER",
"Content-Type": "application/json"
},
body_json: {
foo: "bar"
}
}))
return 0
}
§Wasm Response Transformer
Transform the content of a response with a wasm plugin
export function execute() {
let context = JSON.parse(Host.inputString())
Host.outputString(JSON.stringify({
...context,
status: 200,
headers: {
...context.otoroshi_response.headers,
OTOROSHI_WASM_PLUGIN_ID: "OTOROSHI_WASM_RESPONSE_TRANSFORMER",
"Content-Type": "application/json"
},
body_json: {
foo: "bar"
},
// cookies
}))
return 0
}
§Wasm Route matcher
The "matcher" is a tool that allows filtering a route during the routing phase. In practice, you can create two routes that are identical from a frontend perspective but have different "route matchers." These matchers will select one route or the other based on a specific criterion.
export function execute() {
let context = JSON.parse(Host.inputString())
Host.outputString(JSON.stringify({
result: context.request.headers.foo === "bar"
}))
return 0
}
§Wasm Sink
Handle unmatched requests with a wasm plugin
export function sink_matches() {
// const context = JSON.parse(Host.inputString())
Host.outputString(JSON.stringify({
result: true
}))
return 0
}
export function sink_handle() {
const context = JSON.parse(Host.inputString())
Host.outputString(JSON.stringify({
status: 200,
headers: {
'Content-Type': 'application/json'
},
body_json: {
"WASM_SINK_RESPONSE": `Unknown path and domain for ${context.request.path}`
}
}))
return 0
}
§Wasm Access Control
Delegate route access to a wasm plugin
export function execute() {
let context = JSON.parse(Host.inputString())
if (context.request.headers["foo"] === "bar") {
const out = {
result: true
}
Host.outputString(JSON.stringify(out))
} else {
const error = {
result: false,
error: {
message: "you're not authorized",
status: 401
}
}
Host.outputString(JSON.stringify(error))
}
return 0
}
§Wasm Backend
This plugin can be used to use a wasm plugin as backend
export function execute() {
const str = Host.inputString()
const context = JSON.parse(str)
let headers = { ...context.request.headers }
headers["foo"] = "bar"
const response = {
headers,
'Content-Type': "text/html",
body: `<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
font-family: monospace;
">
<h1>This HTML comes from the Wasmo plugin</h1>
<img src="https://maif.github.io/wasmo/wasmo.png" style="
width: 200;
">
</body>
</html>`,
status: 200
}
Host.outputString(JSON.stringify(response))
return 0
}