Skip to content

Controllers

The Controller trait

Controller is defined in src/controller/mod.rs and has two static methods:

pub trait Controller {
fn is_matching(request: &Request, connection: &ConnectionInfo) -> bool;
fn process(request: &Request, response: Response, connection: &ConnectionInfo) -> Response;
}
  • is_matching — called in declaration order inside App::execute; the first controller that returns true wins.
  • process — receives the partially-built response (already populated with standard headers from Header::get_header_list) and must return it with a status code and body.

Complete minimal example

use rust_web_server::controller::Controller;
use rust_web_server::request::{METHOD, Request};
use rust_web_server::response::{Response, STATUS_CODE_REASON_PHRASE};
use rust_web_server::range::Range;
use rust_web_server::mime_type::MimeType;
use rust_web_server::server::ConnectionInfo;
pub struct HelloController;
impl Controller for HelloController {
fn is_matching(request: &Request, _conn: &ConnectionInfo) -> bool {
request.method == METHOD.get && request.request_uri == "/hello"
}
fn process(_req: &Request, mut response: Response, _conn: &ConnectionInfo) -> Response {
response.status_code = *STATUS_CODE_REASON_PHRASE.n200_ok.status_code;
response.reason_phrase = STATUS_CODE_REASON_PHRASE.n200_ok.reason_phrase.to_string();
response.content_range_list = vec![
Range::get_content_range(
b"Hello, world!".to_vec(),
MimeType::TEXT_PLAIN.to_string(),
)
];
response
}
}

Registering a controller

Controllers are hardcoded in App::execute inside src/app/mod.rs. To add your own, you currently need a custom Application implementation that checks your controller before (or after) the built-in list:

use rust_web_server::application::Application;
use rust_web_server::app::App;
use rust_web_server::controller::Controller;
use rust_web_server::header::Header;
use rust_web_server::request::Request;
use rust_web_server::response::{Response, STATUS_CODE_REASON_PHRASE};
use rust_web_server::server::ConnectionInfo;
use rust_web_server::core::New;
pub struct MyApp;
impl Application for MyApp {
fn execute(&self, request: &Request, connection: &ConnectionInfo) -> Result<Response, String> {
// Check custom controllers first
if HelloController::is_matching(request, connection) {
let header_list = Header::get_header_list(request);
let response = Response::get_response(
STATUS_CODE_REASON_PHRASE.n501_not_implemented,
Some(header_list),
None,
);
return Ok(HelloController::process(request, response, connection));
}
// Fall through to the built-in controller chain
App::new().execute(request, connection)
}
}

Built-in controllers

These are registered in App::execute in this order (first match wins):

ControllerMatches
IndexControllerGET / — serves index.html from the static directory
StyleControllerGET *.css
ScriptControllerGET *.js
FileUploadInitiateControllerPOST /upload/initiate
FormUrlEncodedEnctypePostMethodControllerPOST with application/x-www-form-urlencoded
FormGetMethodControllerGET requests with query parameters to form paths
FormMultipartEnctypePostMethodControllerPOST with multipart/form-data
HealthControllerGET /healthz — returns 200 OK
ReadyControllerGET /readyz — returns 200 when SERVER_READY is set
MetricsControllerGET /metrics — Prometheus text format
FaviconControllerGET /favicon.ico
StaticResourceControllerAny GET for a file found under the static directory
NotFoundControllerCatch-all — returns 404 Not Found