#fastly #spec #proxy #request-response #spectrust #edge-worker

spectrust_fastly_worker

SpecTrust library to integrate Spec Proxy with Fastly Compute@Edge

1 unstable release

0.1.0 Jul 7, 2022

#19 in #fastly

Apache-2.0

32KB
327 lines

SpecTrust Fastly Worker Library

SpecTrust Fastly Compute@Edge integration library.

This library provides a simple interface to integrate and configure a Spec Proxy instance and communicate with it through a Fastly Compute@Edge worker.

Please see the documentation for examples and more information.


lib.rs:

SpecTrust Fastly Compute@Edge integration library.

This library provides a simple interface to integrate and configure a Spec Proxy instance and communicate with it through a Fastly Compute@Edge worker.

It is useful to first understand some of the components of the Fastly worker system before using this library.

Working with our library was designed to be relatively simple. Here is an example of integrating our library.

use fastly::{Error, Request, Response};

use spectrust_fastly_worker::{spec_proxy_process, SpecConfiguration, SpecProxyMode};

#[fastly::main]
fn main(mut request: Request) -> Result<Response, Error> {
    let config = SpecConfiguration::builder(
        [
            // you will only need a backend for your server if you're running in Listening mode
            (
                "www.example.com",
                "example_origin",
            ),
            // and a backend for the spec proxy server
            (
                "www.example.com.specprotected.com",
                "example_spec_proxy_origin",
            ),
        ]
        .into(),
    )
    .with_operating_mode(SpecProxyMode::Listening)
    .build();

    spec_proxy_process(request, &config)
}

This example sets the Spec Proxy library into SpecProxyMode::Listening mode, which will send a copy of each incoming request to Spec Proxy. This configuration does not provide you with the full set of Spec Proxy features. If you would like to run in SpecProxyMode::Inline mode, please contact your SpecTrust representative about enabling this feature within Spec Proxy.

Note that at the time of writing, Fastly backends do not support wildcards, so each subdomain will require its own backend and its own entry in the HashMap.

Please contact your SpecTrust representative if you have any questions or comments.

Runtime Configuration

Please note that, at the time of writing, there is not enough information present to tell exactly how Fastly Dictionaries are implemented. Be aware of potential performance implications of using these Dictionaries for runtime configuration. This document claims there are microsecond read times for using these dictionaries.

Through the use of Fastly Dictionaries We can integrate a system that allows dynamically configuring the Spec Proxy library at runtime! This is a powerful feature that will prevent the need to deploy a new version of an edge worker just to change the settings of the Spec Proxy library. Setting this up is somewhat straightforward. You'll need to follow the instructions here which will create a Dictionary for your Fastly Service, then use the following code example to integrate the Dictionary with the SpecConfigurationBuilder.

use fastly::{ConfigStore, Error, Request, Response};

use spectrust_fastly_worker::{spec_proxy_process, SpecConfiguration, SpecProxyMode};

#[fastly::main]
fn main(mut request: Request) -> Result<Response, Error> {

    let mut builder = SpecConfiguration::builder(
        [
            // you will only need a backend for your server if you're running in Listening mode
            (
                "www.example.com",
                "example_origin",
            ),
            // and a backend for the spec proxy server
            (
                "www.example.com.specprotected.com",
                "example_spec_proxy_origin",
            ),
        ]
        .into(),
    );

    // Attempt to load a Dictionary to configure runtime values, we don't like panicking
    // so use the Result version, `try_open`
    if let Ok(spec_proxy_config) = ConfigStore::try_open("SpecProxy") {
        builder = match spec_proxy_config.try_get("disable_spec_proxy") {
            // if our dictionary value is present and set to "true", disable Spec Proxy
            Ok(Some(s)) => builder.with_disable_spec_proxy(s == "true"),
            // otherwise, default to enable Spec Proxy
            _ => builder.with_disable_spec_proxy(false),
        };

        builder = match spec_proxy_config.try_get("spec_proxy_mode") {
            // if our dictionary value is present and set to "inline", use Inline mode
            Ok(Some(s)) if s == "inline" => builder.with_operating_mode(SpecProxyMode::Inline),
            // otherwise, default to Listening mode
            _ => builder.with_operating_mode(SpecProxyMode::Listening),
        };

        builder = match spec_proxy_config.try_get("percentage_of_ips") {
            // if our dictionary value is present and set to a valid number, set the percentage
            // of IP traffic that's routed to Spec Proxy
            Ok(Some(s)) => builder.with_percentage_of_ips(s.parse().unwrap_or(100)),
            // otherwise, default to routing 100% of traffic to Spec Proxy
            _ => builder.with_percentage_of_ips(100),
        };
    }

    let config = builder.build();

    spec_proxy_process(request, &config)
}

In this example we use three keys in our Dictionary. disable_spec_proxy to configure whether or not the library is entirely disabled, spec_proxy_mode to configure the operating mode of Spec Proxy, and percentage_of_ips to configure the percentage of IPs that are routed through the Spec Proxy library.

We can now modify the Spec Proxy library during runtime through the Fastly web UI!

Note that this doesn't require restarting Spec Proxy, your edge worker, or anything else. The changes take effect by changing the runtime values in the Dictionary when the worker is run.

Dependencies

~5.5–7.5MB
~134K SLoC