1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// ::START CLIPPY LINTS::
// This block is auto-generated. Please do not edit it directly! If you would
// like to make changes, make them in `scripts/global-clippy-lints.sh`.
// ::END CLIPPY LINTS::
//! 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.
//! - [Fastly Compute@Edge Getting Started](https://developer.fastly.com/learning/compute)
//! - [Fastly Compute@Edge Rust](https://developer.fastly.com/learning/compute/rust/)
//! - [Fastly Backends Rust](https://developer.fastly.com/learning/compute/rust/#communicating-with-backend-servers-and-the-fastly-cache)
//! - [Fastly Backends API](https://developer.fastly.com/reference/api/services/backend/)
//!
//! Working with our library was designed to be relatively simple. Here is an
//! example of integrating our library.
//!
//! ```no_run
//! 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](https://developer.fastly.com/learning/concepts/dynamic-config/#edge-dictionaries)
//! claims there are microsecond read times for using these dictionaries.
//!
//! Through the use of
//! [Fastly Dictionaries](https://developer.fastly.com/reference/api/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](https://docs.fastly.com/en/guides/working-with-dictionaries-using-the-web-interface)
//! which will create a Dictionary for your Fastly Service, then use the following code example
//! to integrate the Dictionary with the [`SpecConfigurationBuilder`].
//!
//! - [Fastly Rust Docs](https://docs.rs/fastly/0.8.6/fastly/struct.ConfigStore.html)
//! - More about [Fastly Dictionaries](https://docs.fastly.com/en/guides/about-dictionaries)
//!
//! ```no_run
//! 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.
// Re-export all of our modules. Currently, this is our entire public API.
pub use *;
pub use *;
pub use *;