Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ node_modules/
.vscode/

*.wasm

package-lock.json
1 change: 1 addition & 0 deletions assemblyscript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [Geo Block](./assembly/geoBlock/README.md)
- [Headers](./assembly/headers/README.md)
- [JWT](./assembly/jwt/README.md)
- [KV Store](./assembly/kvStore/README.md)
- [Log time](./assembly/logTime/README.md)
- [Properties](./assembly/properties/README.md)

Expand Down
4 changes: 2 additions & 2 deletions assemblyscript/assembly/body/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ This application modifies the body in `onRequestBody` and `onResponseBody` funct

2. In `onRequestBody` it reads in the body from `get_buffer_bytes` and checks if it contains the term `Client`, if so it alters the body using `set_buffer_bytes`.

3. In `onResponseHeaders` it resets the `content-length` header, sets the `transfer-encoding` header and ensures that the runtime property `response.content_type` is set according to what it has recieved in the headers.
3. In `onResponseHeaders` it resets the `content-length` header, sets the `transfer-encoding` header and ensures that the runtime property `response.content_type` is set according to what it has received in the headers.

4. In `onResponseBody` it finally reads and logs the known properties and the returned body content.
4. In `onResponseBody` it finally reads and logs the known properties and the returns the body content.

This demonstrates the basic flow of how to manipulate the body in each life cycle hook, be mindful that altering the body requires you to manipulate the required headers before doing anything.

Expand Down
6 changes: 3 additions & 3 deletions assemblyscript/assembly/body/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import {
RootContext,
set_buffer_bytes,
set_property,
setLogLevel,
stream_context,
} from "@gcoredev/proxy-wasm-sdk-as/assembly";
import { setLogLevel } from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge";

class HttpBodyRoot extends RootContext {
createContext(context_id: u32): Context {
Expand Down Expand Up @@ -42,7 +42,7 @@ class HttpBody extends Context {
body_buffer_length: usize,
end_of_stream: bool
): FilterDataStatusValues {
log(LogLevelValues.debug, "onHttpRequestBody >>");
log(LogLevelValues.debug, "onRequestBody >>");
if (!end_of_stream) {
// Wait until the complete body is buffered
return FilterDataStatusValues.StopIterationAndBuffer;
Expand All @@ -57,7 +57,7 @@ class HttpBody extends Context {

if (bodyBytes.byteLength > 0) {
const bodyStr = String.UTF8.decode(bodyBytes);
log(LogLevelValues.debug, "onHttpRequestBody >> bodyStr: " + bodyStr);
log(LogLevelValues.debug, "onRequestBody >> bodyStr: " + bodyStr);
if (bodyStr.includes("Client")) {
const newBody = `Original message body (${body_buffer_length.toString()} bytes) redacted.\n`;
set_buffer_bytes(
Expand Down
2 changes: 1 addition & 1 deletion assemblyscript/assembly/geoBlock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import {
Context,
FilterHeadersStatusValues,
get_property,
getEnvVar,
registerRootContext,
RootContext,
send_http_response,
} from "@gcoredev/proxy-wasm-sdk-as/assembly";
import { getEnvVar } from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge";

const BAD_GATEWAY: u32 = 502;
const FORBIDDEN: u32 = 403;
Expand Down
6 changes: 4 additions & 2 deletions assemblyscript/assembly/geoRedirect/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import {
Context,
FilterHeadersStatusValues,
get_property,
getEnvVar,
log,
LogLevelValues,
registerRootContext,
RootContext,
send_http_response,
set_property,
setLogLevel,
stream_context,
} from "@gcoredev/proxy-wasm-sdk-as/assembly";
import {
getEnvVar,
setLogLevel,
} from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge";

const BAD_GATEWAY: u32 = 502;
const INTERNAL_SERVER_ERROR: u32 = 500;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {
registerRootContext,
RootContext,
send_http_response,
setLogLevel,
stream_context,
} from "@gcoredev/proxy-wasm-sdk-as/assembly";
import { setLogLevel } from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge";

function collectHeaders(
headers: Headers,
logHeaders: bool = true
logHeaders: bool = true,
): Set<string> {
// Iterate over headers adding them to the returned set and log them if required
const set = new Set<string>();
Expand All @@ -29,7 +29,7 @@ function collectHeaders(

function validateHeaders(
headers: Headers,
expectedHeaders: Set<string>
expectedHeaders: Set<string>,
): Set<string> {
// Ensure the headers only contain the expected headers
const headersArr = collectHeaders(headers, false).values();
Expand Down Expand Up @@ -62,27 +62,27 @@ class HttpHeaders extends Context {

// Get the request headers
const originalHeaders = collectHeaders(
stream_context.headers.request.get_headers()
stream_context.headers.request.get_headers(),
);

if (originalHeaders.size === 0) {
send_http_response(
550,
"internal server error",
String.UTF8.encode("Internal server error"),
[]
[],
);
return FilterHeadersStatusValues.StopIteration;
}

// Check if the "host" header is present
const hostHeader = stream_context.headers.request.get("host");
if (hostHeader === null) {
if (hostHeader && hostHeader === "") {
send_http_response(
551,
"internal server error",
String.UTF8.encode("Internal server error"),
[]
[],
);
return FilterHeadersStatusValues.StopIteration;
}
Expand Down Expand Up @@ -116,12 +116,12 @@ class HttpHeaders extends Context {
// This is a common issue in Proxy-Wasm environments, where certain operations are only valid during specific phases of the request/response lifecycle.
// i.e. runtime will panic as response headers are not available in the request phase.
const newResponseHeader = stream_context.headers.response.get(
"new-response-header"
"new-response-header",
);
if (newResponseHeader.length > 0) {
stream_context.headers.response.replace(
"new-response-header",
"value-02"
"value-02",
);
}

Expand All @@ -134,19 +134,19 @@ class HttpHeaders extends Context {
// Validate headers
const diff = validateHeaders(
stream_context.headers.request.get_headers(),
expectedHeaders
expectedHeaders,
);

if (diff.size > 0) {
log(
LogLevelValues.warn,
`Unexpected request headers: ` + diff.values().join(", ")
`Unexpected request headers: ` + diff.values().join(", "),
);
send_http_response(
552,
"internal server error",
String.UTF8.encode("Internal server error"),
[]
[],
);
return FilterHeadersStatusValues.StopIteration;
}
Expand All @@ -159,27 +159,27 @@ class HttpHeaders extends Context {
log(LogLevelValues.debug, "onResponseHeaders >> ");

const originalHeaders = collectHeaders(
stream_context.headers.response.get_headers()
stream_context.headers.response.get_headers(),
);

if (originalHeaders.size === 0) {
send_http_response(
550,
"internal server error",
String.UTF8.encode("Internal server error"),
[]
[],
);
return FilterHeadersStatusValues.StopIteration;
}

// Check if the "host" header is present
const hostHeader = stream_context.headers.response.get("host");
if (hostHeader === null) {
if (hostHeader && hostHeader === "") {
send_http_response(
551,
"internal server error",
String.UTF8.encode("Internal server error"),
[]
[],
);
return FilterHeadersStatusValues.StopIteration;
}
Expand All @@ -206,19 +206,19 @@ class HttpHeaders extends Context {

const diff = validateHeaders(
stream_context.headers.response.get_headers(),
expectedHeaders
expectedHeaders,
);

if (diff.size > 0) {
log(
LogLevelValues.warn,
`Unexpected response headers: ` + diff.values().join(", ")
`Unexpected response headers: ` + diff.values().join(", "),
);
send_http_response(
552,
"internal server error",
String.UTF8.encode("Internal server error"),
[]
[],
);
return FilterHeadersStatusValues.StopIteration;
}
Expand All @@ -231,7 +231,7 @@ class HttpHeaders extends Context {
onLog(): void {
log(
LogLevelValues.info,
"onLog >> completed (contextId): " + this.context_id.toString()
"onLog >> completed (contextId): " + this.context_id.toString(),
);
}
}
Expand Down
6 changes: 4 additions & 2 deletions assemblyscript/assembly/jwt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ export * from "@gcoredev/proxy-wasm-sdk-as/assembly/proxy"; // this exports the
import {
Context,
FilterHeadersStatusValues,
getSecretVar,
log,
LogLevelValues,
registerRootContext,
RootContext,
send_http_response,
setLogLevel,
stream_context,
} from "@gcoredev/proxy-wasm-sdk-as/assembly";
import {
getSecretVar,
setLogLevel,
} from "@gcoredev/proxy-wasm-sdk-as/assembly/fastedge";

import { jwtVerify, JwtValidation } from "@gcoredev/as-jwt/assembly";

Expand Down
31 changes: 31 additions & 0 deletions assemblyscript/assembly/kvStore/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
⏮️ Back to AssemblyScript [README.md](../../README.md)

# KV Store

This application modifies the body in the `onResponseBody` function.

It ignores the body received from the origin and instead just replaces it with results from interacting with a KV Store.

**Note** This is purely to demonstate how to interact with a KV Store. It has no real world use case.

## Application Flow

1. In `onResponseHeaders` it resets the `content-length` header, sets the `transfer-encoding` header and ensures that the runtime property `response.content_type` is set to `application/json`.

2. In `onResponseBody` it demonstrates how to interact with a KV Store.

This interaction with the KV Store is powered using query parameters.

### Query Parameters

`store` - the name of the store you wish to open. This is the name given to a store on the application.

`action` - What you wish to perform. Options are "get", "scan", "zscan", "zrange", "bfExists". ( If no action is provided it will default to "get" )

`key` - The key you wish to access in the KV Store.

`match` - A prefix match pattern, used by "scan" and "zscan". Must include a wildcard. e.g. `foo*`

`min` / `max` - Used by zrange for defining the range of scores you wish to receive results for.

`item` - Used by Bloom Filter exists function.
Loading