-
Notifications
You must be signed in to change notification settings - Fork 5
Making plugins for Octane
While Octane allows you access to raw body, headers, etc, you can architect your plugin to integrate seamlessly with octane. For example
let app = Octane::new();
app.get("/", YourPlugin::handle(|req, res| {
// access to your plugins custom req and res here
Flow::Next
}))?;
For tutorial purposes, let's make a Cookie handler which will be just a mere wrapper over the cookie
crate.
We start by making a new lib
cargo new --lib octane-cookies
We will now make a new Request
structure, its a cookie middleware, it won't need to do anything to the response so we'll leave it that way.
#[derive(Debug)]
pub struct CookieReq<'a> {
/// The original octane request we get from the client
pub request: &'a Request<'a>,
/// The cookies
pub data: CookieJar,
}
Note: It is extremely important to keep the original request in there, you can also derive deref to request to make it more seamless but that's not needed.
Now we perform actual cookie parsing using the Cookie crate. We write 2 functions and one method
impl<'a> CookieReq<'a> {
pub fn parse(req: &'a Request) -> Self {
let mut jar = CookieJar::new();
if let Some(key_value) = Self::get_cookies(req) {
for cookie in key_value.split("; ") {
if let Ok(x) = Cookie::parse(cookie) {
jar.add(x.into_owned())
}
}
}
Self {
request: req,
data: jar,
}
}
pub fn get(&self, name: &str) -> Option<&Cookie> {
self.data.get(name)
}
pub fn handle<T>(closure: T) -> Closure
where
T: Fn(CookieReq, &mut Response) -> Flow + Send + Sync + 'static,
{
route_next!(|req, res| closure(CookieReq::parse(req), res))
}
}
Notice the signature of handle
there, its similar to what the methods in the Route trait takes in. Now we can
let app = Octane::new();
app.get("/", CookieReq::handle(|req, res| {
let cookie = req.get("cookie");
Flow::Next
}))?;
But what if you want to have best of any two of the plugins you are using? That's why the parse method above is pub
but unfortunately, we won't get to have that syntax above now.
let app = Octane::new();
app.get("/", CookieReq::handle(|req, res| {
let cookie = req.get("cookie");
let second_middleware = YourPlugin::parse(req.request);
Flow::Next
}))?;