Skip to content

Commit

Permalink
Add device detection hostcall (#330)
Browse files Browse the repository at this point in the history
* Add hostcall for device_detection.

This is closely patterned on the geolocation hostcall.

The new test that executes the hostcall needs a new SDK, so this
will be followed by a separate commit that comments it out. That
can be reverted once the new SDK is available.

* device_detection: Temporarily comment out tests that need new SDK.

These tests depend on a new SDK for the device_detection hostcall,
comment them out for now. This is in its own commit to make it
easy to revert.

* Minor changes from cargo fmt.

* Fix copy/pasted identifier.
  • Loading branch information
silentbicycle committed Nov 7, 2023
1 parent 6e60112 commit c4531d3
Show file tree
Hide file tree
Showing 21 changed files with 640 additions and 11 deletions.
2 changes: 2 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ async fn create_execution_context(
if let Some(config_path) = args.config_path() {
let config = FastlyConfig::from_file(config_path)?;
let backends = config.backends();
let device_detection = config.device_detection();
let geolocation = config.geolocation();
let dictionaries = config.dictionaries();
let object_stores = config.object_stores();
Expand All @@ -258,6 +259,7 @@ async fn create_execution_context(

ctx = ctx
.with_backends(backends.clone())
.with_device_detection(device_detection.clone())
.with_geolocation(geolocation.clone())
.with_dictionaries(dictionaries.clone())
.with_object_stores(object_stores.clone())
Expand Down
9 changes: 8 additions & 1 deletion cli/tests/integration/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use tracing_subscriber::filter::EnvFilter;
use viceroy_lib::config::UnknownImportBehavior;
use viceroy_lib::{
body::Body,
config::{Dictionaries, FastlyConfig, Geolocation, ObjectStores, SecretStores},
config::{
DeviceDetection, Dictionaries, FastlyConfig, Geolocation, ObjectStores, SecretStores,
},
ExecuteCtx, ProfilingStrategy, ViceroyService,
};

Expand Down Expand Up @@ -49,6 +51,7 @@ pub type TestResult = Result<(), Error>;
pub struct Test {
module_path: PathBuf,
backends: TestBackends,
device_detection: DeviceDetection,
dictionaries: Dictionaries,
geolocation: Geolocation,
object_stores: ObjectStores,
Expand All @@ -68,6 +71,7 @@ impl Test {
Self {
module_path,
backends: TestBackends::new(),
device_detection: DeviceDetection::new(),
dictionaries: Dictionaries::new(),
geolocation: Geolocation::new(),
object_stores: ObjectStores::new(),
Expand All @@ -87,6 +91,7 @@ impl Test {
Self {
module_path,
backends: TestBackends::new(),
device_detection: DeviceDetection::new(),
dictionaries: Dictionaries::new(),
geolocation: Geolocation::new(),
object_stores: ObjectStores::new(),
Expand All @@ -103,6 +108,7 @@ impl Test {
let config = fastly_toml.parse::<FastlyConfig>()?;
Ok(Self {
backends: TestBackends::from_backend_configs(config.backends()),
device_detection: config.device_detection().to_owned(),
dictionaries: config.dictionaries().to_owned(),
geolocation: config.geolocation().to_owned(),
object_stores: config.object_stores().to_owned(),
Expand Down Expand Up @@ -279,6 +285,7 @@ impl Test {
)?
.with_backends(self.backends.backend_configs().await)
.with_dictionaries(self.dictionaries.clone())
.with_device_detection(self.device_detection.clone())
.with_geolocation(self.geolocation.clone())
.with_object_stores(self.object_stores.clone())
.with_secret_stores(self.secret_stores.clone())
Expand Down
66 changes: 66 additions & 0 deletions cli/tests/integration/device_detection_lookup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// use crate::common::{Test, TestResult};
// use hyper::{body::to_bytes, StatusCode};

// #[tokio::test(flavor = "multi_thread")]
// async fn json_device_detection_lookup_works() -> TestResult {
// const FASTLY_TOML: &str = r#"
// name = "json-device-detection-lookup"
// description = "json device detection lookup test"
// authors = ["Test User <test_user@fastly.com>"]
// language = "rust"
// [local_server]
// [local_server.device_detection]
// file = "../test-fixtures/data/device-detection-mapping.json"
// format = "json"
// "#;

// let resp = Test::using_fixture("device-detection-lookup.wasm")
// .using_fastly_toml(FASTLY_TOML)?
// .against_empty()
// .await?;

// assert_eq!(resp.status(), StatusCode::OK);
// assert!(to_bytes(resp.into_body())
// .await
// .expect("can read body")
// .to_vec()
// .is_empty());

// Ok(())
// }

// #[tokio::test(flavor = "multi_thread")]
// async fn inline_toml_device_detection_lookup_works() -> TestResult {
// const FASTLY_TOML: &str = r#"
// name = "inline-toml-device-detection-lookup"
// description = "inline toml device detection lookup test"
// authors = ["Test User <test_user@fastly.com>"]
// language = "rust"
// [local_server]
// [local_server.device_detection]
// format = "inline-toml"
// [local_server.device_detection.user_agents]
// [local_server.device_detection.user_agents."Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0 [FBAN/FBIOS;FBAV/8.0.0.28.18;FBBV/1665515;FBDV/iPhone4,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/7.0.4;FBSS/2; FBCR/Telekom.de;FBID/phone;FBLC/de_DE;FBOP/5]"]
// user_agent = {}
// os = {}
// device = {name = "iPhone", brand = "Apple", model = "iPhone4,1", hwtype = "Mobile Phone", is_ereader = false, is_gameconsole = false, is_mediaplayer = false, is_mobile = true, is_smarttv = false, is_tablet = false, is_tvplayer = false, is_desktop = false, is_touchscreen = true }
// [local_server.device_detection.user_agents."ghosts-app/1.0.2.1 (ASUSTeK COMPUTER INC.; X550CC; Windows 8 (X86); en)"]
// user_agent = {}
// os = {}
// device = {name = "Asus TeK", brand = "Asus", model = "TeK", is_desktop = false }
// "#;

// let resp = Test::using_fixture("device-detection-lookup.wasm")
// .using_fastly_toml(FASTLY_TOML)?
// .against_empty()
// .await?;

// assert_eq!(resp.status(), StatusCode::OK);
// assert!(to_bytes(resp.into_body())
// .await
// .expect("can read body")
// .to_vec()
// .is_empty());

// Ok(())
// }
1 change: 1 addition & 0 deletions cli/tests/integration/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod async_io;
mod body;
mod client_certs;
mod common;
mod device_detection_lookup;
mod dictionary_lookup;
mod downstream_req;
mod env_vars;
Expand Down
11 changes: 11 additions & 0 deletions lib/compute-at-edge-abi/compute-at-edge.witx
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,17 @@
)
)

(module $fastly_device_detection
(@interface func (export "lookup")
(param $user_agent string)

(param $buf (@witx pointer (@witx char8)))
(param $buf_len (@witx usize))
(param $nwritten_out (@witx pointer (@witx usize)))
(result $err (expected (error $fastly_status)))
)
)

(module $fastly_object_store
(@interface func (export "open")
(param $name string)
Expand Down
20 changes: 20 additions & 0 deletions lib/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ pub use self::backends::{Backend, ClientCertError, ClientCertInfo};

pub type Backends = HashMap<String, Arc<Backend>>;

/// Types and deserializers for device detection configuration settings.
mod device_detection;

pub use self::device_detection::DeviceDetection;

/// Types and deserializers for geolocation configuration settings.
mod geolocation;

Expand Down Expand Up @@ -85,6 +90,12 @@ impl FastlyConfig {
&self.local_server.backends.0
}

/// Get the device detection configuration.
pub fn device_detection(&self) -> &DeviceDetection {
&self.local_server.device_detection
}

/// Get the geolocation configuration.
pub fn geolocation(&self) -> &Geolocation {
&self.local_server.geolocation
}
Expand Down Expand Up @@ -182,6 +193,7 @@ impl TryInto<FastlyConfig> for TomlFastlyConfig {
#[derive(Clone, Debug, Default)]
pub struct LocalServerConfig {
backends: BackendsConfig,
device_detection: DeviceDetection,
geolocation: Geolocation,
dictionaries: DictionariesConfig,
object_stores: ObjectStoreConfig,
Expand All @@ -201,6 +213,7 @@ pub enum ExperimentalModule {
#[derive(Deserialize)]
struct RawLocalServerConfig {
backends: Option<Table>,
device_detection: Option<Table>,
geolocation: Option<Table>,
#[serde(alias = "config_stores")]
dictionaries: Option<Table>,
Expand All @@ -214,6 +227,7 @@ impl TryInto<LocalServerConfig> for RawLocalServerConfig {
fn try_into(self) -> Result<LocalServerConfig, Self::Error> {
let Self {
backends,
device_detection,
geolocation,
dictionaries,
object_stores,
Expand All @@ -224,6 +238,11 @@ impl TryInto<LocalServerConfig> for RawLocalServerConfig {
} else {
BackendsConfig::default()
};
let device_detection = if let Some(device_detection) = device_detection {
device_detection.try_into()?
} else {
DeviceDetection::default()
};
let geolocation = if let Some(geolocation) = geolocation {
geolocation.try_into()?
} else {
Expand All @@ -247,6 +266,7 @@ impl TryInto<LocalServerConfig> for RawLocalServerConfig {

Ok(LocalServerConfig {
backends,
device_detection,
geolocation,
dictionaries,
object_stores,
Expand Down
Loading

0 comments on commit c4531d3

Please sign in to comment.