WasmFileMiddleware

Struct WasmFileMiddleware 

Source
pub struct WasmFileMiddleware { /* private fields */ }
Expand description

A middleware component for serving WebAssembly and JavaScript files.

This middleware serves the suika_ui_bg.wasm and suika_ui.js files when the request path matches the specified URL prefix. For other paths, it passes the request to the next middleware in the stack.

§Examples

use suika_server::request::Request;
use suika_server::response::Response;
use suika_server::middleware::{Middleware, Next, MiddlewareFuture};
use suika_wasm::WasmFileMiddleware;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use tokio::sync::Mutex as TokioMutex;

#[derive(Clone)]
struct MockNextMiddleware {
    called: Arc<TokioMutex<bool>>,
}

impl MockNextMiddleware {
    fn new() -> Self {
        Self {
            called: Arc::new(TokioMutex::new(false)),
        }
    }
}

impl Middleware for MockNextMiddleware {
    fn handle<'a>(
        &'a self,
        _req: &'a mut Request,
        _res: &'a mut Response,
        _next: Next<'a>,
    ) -> MiddlewareFuture<'a> {
        let called = Arc::clone(&self.called);
        Box::pin(async move {
            let mut called_lock = called.lock().await;
            *called_lock = true;
            Ok(())
        })
    }
}

#[tokio::main]
async fn main() {
    let mut req = Request::new(
        "GET /static/suika_ui_bg.wasm HTTP/1.1\r\n\r\n",
        Arc::new(Mutex::new(HashMap::new())),
    ).unwrap();
 
    let mut res = Response::new(None);

    let wasm_file_middleware = WasmFileMiddleware::new("/static", 3600);
    let next_middleware = MockNextMiddleware::new();
    let middleware_stack: Vec<Arc<dyn Middleware + Send + Sync>> = vec![Arc::new(next_middleware.clone())];
    let next = Next::new(middleware_stack.as_slice());

    wasm_file_middleware.handle(&mut req, &mut res, next.clone()).await.unwrap();
    let inner = res.get_inner().await;

    assert_eq!(inner.status_code(), Some(200));
    assert_eq!(inner.headers().get("Content-Type"), Some(&"application/wasm".to_string()));
}

Implementations§

Source§

impl WasmFileMiddleware

Source

pub fn new(url_prefix: &'static str, cache_duration: u64) -> Self

Creates a new WasmFileMiddleware.

§Arguments
  • url_prefix - The URL prefix for serving WebAssembly and JavaScript files.
  • cache_duration - The cache duration in seconds.
§Examples
use suika_wasm::WasmFileMiddleware;

let wasm_file_middleware = WasmFileMiddleware::new("/static", 3600);

Trait Implementations§

Source§

impl Middleware for WasmFileMiddleware

Source§

fn handle<'a>( &'a self, req: &'a mut Request, res: &'a mut Response, next: Next<'a>, ) -> MiddlewareFuture<'a>

Handles an incoming HTTP request by serving the .wasm or .js file if the request path matches the URL prefix.

§Arguments
  • req - A mutable reference to the incoming request.
  • res - A mutable reference to the response to be sent.
  • next - The next middleware in the stack.
§Returns

A future that resolves to a Result<(), HttpError>.

§Examples
use suika_server::request::Request;
use suika_server::response::Response;
use suika_server::middleware::{Middleware, Next, MiddlewareFuture};
use suika_wasm::WasmFileMiddleware;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use tokio::sync::Mutex as TokioMutex;

#[derive(Clone)]
struct MockNextMiddleware {
    called: Arc<TokioMutex<bool>>,
}

impl MockNextMiddleware {
    fn new() -> Self {
        Self {
            called: Arc::new(TokioMutex::new(false)),
        }
    }
}

impl Middleware for MockNextMiddleware {
    fn handle<'a>(
        &'a self,
        _req: &'a mut Request,
        _res: &'a mut Response,
        _next: Next<'a>,
    ) -> MiddlewareFuture<'a> {
        let called = Arc::clone(&self.called);
        Box::pin(async move {
            let mut called_lock = called.lock().await;
            *called_lock = true;
            Ok(())
        })
    }
}

#[tokio::main]
async fn main() {
    let mut req = Request::new(
        "GET /static/suika_ui.js HTTP/1.1\r\n\r\n",
        Arc::new(Mutex::new(HashMap::new())),
    ).unwrap();
 
    let mut res = Response::new(None);

    let wasm_file_middleware = WasmFileMiddleware::new("/static", 3600);
    let next_middleware = MockNextMiddleware::new();
    let middleware_stack: Vec<Arc<dyn Middleware + Send + Sync>> = vec![Arc::new(next_middleware.clone())];
    let next = Next::new(middleware_stack.as_slice());

    wasm_file_middleware.handle(&mut req, &mut res, next.clone()).await.unwrap();
    let inner = res.get_inner().await;

    assert_eq!(inner.status_code(), Some(200));
    assert_eq!(inner.headers().get("Content-Type"), Some(&"application/javascript".to_string()));
}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.