mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2025-06-20 16:35:17 +00:00
Create server
This commit is contained in:
4
src/controllers/mod.rs
Normal file
4
src/controllers/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod routes;
|
||||
pub mod server;
|
||||
|
||||
pub mod server_controller;
|
41
src/controllers/routes.rs
Normal file
41
src/controllers/routes.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use std::error::Error;
|
||||
|
||||
use crate::controllers::routes::Method::GET;
|
||||
use crate::controllers::server_controller;
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
|
||||
/// Project routes
|
||||
///
|
||||
/// @author Pierre Hubert
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum Method {
|
||||
GET,
|
||||
POST,
|
||||
}
|
||||
|
||||
/// Define types
|
||||
pub type RequestResult = Result<(), Box<dyn Error>>;
|
||||
pub type RequestProcess = Box<dyn Fn(&mut HttpRequestHandler) -> RequestResult>;
|
||||
|
||||
pub struct Route {
|
||||
/// The Verb used for the request
|
||||
pub method: Method,
|
||||
|
||||
/// The URI of the request, with the leading "/"
|
||||
pub uri: &'static str,
|
||||
|
||||
/// If set to true, unauthenticated requests will be rejected
|
||||
pub need_login: bool,
|
||||
|
||||
/// The function called to process a request
|
||||
pub func: RequestProcess,
|
||||
}
|
||||
|
||||
/// Get the list of routes available
|
||||
pub fn get_routes() -> Vec<Route> {
|
||||
vec![
|
||||
// Server meta routes
|
||||
Route { method: GET, uri: "/", need_login: false, func: Box::new(server_controller::main_index) }
|
||||
]
|
||||
}
|
80
src/controllers/server.rs
Normal file
80
src/controllers/server.rs
Normal file
@ -0,0 +1,80 @@
|
||||
use actix_web::{App, HttpResponse, HttpServer, web, http};
|
||||
|
||||
use crate::controllers::routes::{get_routes, Route};
|
||||
use crate::data::config::Config;
|
||||
use crate::data::http_error::HttpError;
|
||||
use crate::controllers::routes::Method::{GET, POST};
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
|
||||
/// Main server functions
|
||||
///
|
||||
/// @author Pierre Hubert
|
||||
|
||||
/// Process an incoming request
|
||||
async fn process_request(req: web::HttpRequest) -> HttpResponse {
|
||||
let routes = get_routes();
|
||||
|
||||
// We search the appropriate route for the request
|
||||
let mut route: Option<&Route> = None;
|
||||
for el in &routes {
|
||||
|
||||
// Check verb
|
||||
if !(req.method() == http::Method::GET && el.method == GET) &&
|
||||
!(req.method() == http::Method::POST && el.method == POST) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check path
|
||||
if !el.uri.eq(req.uri()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
route = Some(el);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if a route was found
|
||||
if let None = route {
|
||||
return HttpResponse::NotFound().json(HttpError::not_found("Method not found!"));
|
||||
}
|
||||
let route = route.unwrap();
|
||||
|
||||
// Execute the request
|
||||
let mut request = HttpRequestHandler::new(req);
|
||||
|
||||
match (route.func)(&mut request) {
|
||||
|
||||
// Set default error response if required
|
||||
Err(e) => {
|
||||
if !request.has_response() {
|
||||
request.internal_error(e).unwrap_err();
|
||||
}
|
||||
}
|
||||
|
||||
// Set default success response if required
|
||||
Ok(_) => {
|
||||
if !request.has_response() {
|
||||
request.success("Success").unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// I use this to be quiet with IntelliJ
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => {println!("Unexpected case (server.rs)!")}
|
||||
}
|
||||
|
||||
request.response()
|
||||
}
|
||||
|
||||
|
||||
/// Given the configuration, start the server
|
||||
pub async fn start_server(conf: &Config) -> std::io::Result<()> {
|
||||
let addr = conf.server_listen_address();
|
||||
println!("Start to listen on http://{}/", addr);
|
||||
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.route("**", web::get().to(process_request))
|
||||
.route("**", web::post().to(process_request))
|
||||
}).bind(&addr)?.run().await
|
||||
}
|
11
src/controllers/server_controller.rs
Normal file
11
src/controllers/server_controller.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
use crate::controllers::routes::RequestResult;
|
||||
|
||||
/// Main server controller
|
||||
///
|
||||
/// @author Pierre Hubert
|
||||
|
||||
/// Root server index
|
||||
pub fn main_index(request: &mut HttpRequestHandler) -> RequestResult {
|
||||
request.success("Comunic API server V3. (c) Pierre Hubert 2020")
|
||||
}
|
Reference in New Issue
Block a user