Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add edge rate limiting hostcalls #333

Merged
merged 1 commit into from
Nov 13, 2023
Merged
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
15 changes: 15 additions & 0 deletions cli/tests/integration/edge_rate_limiting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Tests related to HTTP request and response bodies.

use {
crate::common::{Test, TestResult},
hyper::StatusCode,
};

#[tokio::test(flavor = "multi_thread")]
async fn check_hostcalls_implemented() -> TestResult {
let resp = Test::using_fixture("edge-rate-limiting.wasm")
.against_empty()
.await?;
assert_eq!(resp.status(), StatusCode::OK);
Ok(())
}
1 change: 1 addition & 0 deletions cli/tests/integration/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod common;
mod device_detection_lookup;
mod dictionary_lookup;
mod downstream_req;
mod edge_rate_limiting;
mod env_vars;
mod geolocation_lookup;
mod grpc;
Expand Down
53 changes: 53 additions & 0 deletions lib/compute-at-edge-abi/compute-at-edge.witx
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,59 @@
)
)

(module $fastly_erl
(@interface func (export "check_rate")
(param $rc string)
(param $entry string)
(param $delta u32)
(param $window u32)
(param $limit u32)
(param $pb string)
(param $ttl u32)

(result $err (expected $blocked (error $fastly_status)))
)

(@interface func (export "ratecounter_increment")
(param $rc string)
(param $entry string)
(param $delta u32)

(result $err (expected (error $fastly_status)))
)

(@interface func (export "ratecounter_lookup_rate")
(param $rc string)
(param $entry string)
(param $window u32)

(result $err (expected $rate (error $fastly_status)))
)

(@interface func (export "ratecounter_lookup_count")
(param $rc string)
(param $entry string)
(param $duration u32)

(result $err (expected $count (error $fastly_status)))
)

(@interface func (export "penaltybox_add")
(param $pb string)
(param $entry string)
(param $ttl u32)

(result $err (expected (error $fastly_status)))
)

(@interface func (export "penaltybox_has")
(param $pb string)
(param $entry string)

(result $err (expected $has (error $fastly_status)))
)
)

(module $fastly_object_store
(@interface func (export "open")
(param $name string)
Expand Down
5 changes: 5 additions & 0 deletions lib/compute-at-edge-abi/typenames.witx
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,8 @@
(field $dns_error_info_code u16)
(field $tls_alert_id u8)
))

(typename $blocked u32)
(typename $rate u32)
(typename $count u32)
(typename $has u32)
1 change: 1 addition & 0 deletions lib/src/linking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ pub fn link_host_functions(
wiggle_abi::fastly_config_store::add_to_linker(linker, WasmCtx::session)?;
wiggle_abi::fastly_dictionary::add_to_linker(linker, WasmCtx::session)?;
wiggle_abi::fastly_device_detection::add_to_linker(linker, WasmCtx::session)?;
wiggle_abi::fastly_erl::add_to_linker(linker, WasmCtx::session)?;
wiggle_abi::fastly_geo::add_to_linker(linker, WasmCtx::session)?;
wiggle_abi::fastly_http_body::add_to_linker(linker, WasmCtx::session)?;
wiggle_abi::fastly_http_req::add_to_linker(linker, WasmCtx::session)?;
Expand Down
1 change: 1 addition & 0 deletions lib/src/wiggle_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ mod config_store;
mod device_detection_impl;
mod dictionary_impl;
mod entity;
mod erl_impl;
mod fastly_purge_impl;
mod geo_impl;
mod headers;
Expand Down
62 changes: 62 additions & 0 deletions lib/src/wiggle_abi/erl_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::{
error::Error, session::Session, wiggle_abi::fastly_erl::FastlyErl, wiggle_abi::GuestPtr,
};

impl FastlyErl for Session {
fn check_rate(
&mut self,
_rc: &GuestPtr<str>,
_entry: &GuestPtr<str>,
_delta: u32,
_window: u32,
_limit: u32,
_pb: &GuestPtr<str>,
_ttl: u32,
) -> std::result::Result<u32, Error> {
Ok(0)
}

fn ratecounter_increment(
&mut self,
_rc: &GuestPtr<str>,
_entry: &GuestPtr<str>,
_delta: u32,
) -> std::result::Result<(), Error> {
Ok(())
}

fn ratecounter_lookup_rate(
&mut self,
_rc: &GuestPtr<str>,
_entry: &GuestPtr<str>,
_window: u32,
) -> std::result::Result<u32, Error> {
Ok(0)
}

fn ratecounter_lookup_count(
&mut self,
_rc: &GuestPtr<str>,
_entry: &GuestPtr<str>,
_duration: u32,
) -> std::result::Result<u32, Error> {
Ok(0)
}

fn penaltybox_add(
&mut self,
_pb: &GuestPtr<str>,
_entry: &GuestPtr<str>,
_ttl: u32,
) -> std::result::Result<(), Error> {
Ok(())
}

fn penaltybox_has(
&mut self,
_pb: &GuestPtr<str>,
_entry: &GuestPtr<str>,
) -> std::result::Result<u32, Error> {
Ok(0)
}
}
33 changes: 33 additions & 0 deletions test-fixtures/src/bin/edge-rate-limiting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! A guest program to test that edge-rate-limiting API is implemented.

//use std::time::Duration;

//use fastly::erl::{CounterDuration, Penaltybox, RateCounter, RateWindow, ERL};

fn main() {
// let entry = "entry";

// let rc = RateCounter::open("rc");
// let pb = Penaltybox::open("pb");
// let erl = ERL::open(rc, pb);

// let not_blocked = erl
// .check_rate(entry, 1, RateWindow::TenSecs, 100, Duration::from_secs(300))
// .unwrap();
// assert_eq!(not_blocked, false);

// let rc2 = RateCounter::open("rc");
// let rate_1 = rc2.lookup_rate(entry, RateWindow::OneSec).unwrap();
// assert_eq!(rate_1, 0);

// let count10 = rc2.lookup_count(entry, CounterDuration::TenSec).unwrap();
// assert_eq!(count10, 0);

// assert!(rc2.increment(entry, 600).is_ok());

// let pb2 = Penaltybox::open("pb");
// let not_in_pb = pb2.has(entry).unwrap();
// assert_eq!(not_in_pb, false);

// assert!(pb2.add(entry, Duration::from_secs(300)).is_ok());
}