1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-06-20 16:35:17 +00:00

Create server

This commit is contained in:
2020-05-21 15:28:07 +02:00
parent 22d47efa9c
commit 1170a94309
12 changed files with 1239 additions and 30 deletions

4
src/controllers/mod.rs Normal file
View File

@ -0,0 +1,4 @@
pub mod routes;
pub mod server;
pub mod server_controller;

41
src/controllers/routes.rs Normal file
View 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
View 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
}

View 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")
}