parsec_service/front/
front_end.rs1use crate::authenticators::Authenticate;
8use crate::back::dispatcher::Dispatcher;
9use crate::front::listener::Connection;
10use derivative::Derivative;
11use log::{info, trace};
12use parsec_interface::requests::AuthType;
13use parsec_interface::requests::ResponseStatus;
14use parsec_interface::requests::{Request, Response};
15use std::collections::HashMap;
16use std::io::{Error, ErrorKind, Result};
17
18#[derive(Derivative)]
25#[derivative(Debug)]
26pub struct FrontEndHandler {
27 dispatcher: Dispatcher,
28 #[derivative(Debug = "ignore")]
30 authenticators: HashMap<AuthType, Box<dyn Authenticate + Send + Sync>>,
31 body_len_limit: usize,
33}
34
35impl FrontEndHandler {
36 pub fn handle_request(&self, mut connection: Connection) {
44 trace!("handle_request ingress");
45 let request = match Request::read_from_stream(&mut connection.stream, self.body_len_limit) {
48 Ok(request) => request,
49 Err(status) => {
50 format_error!("Failed to read request", status);
51
52 let response = Response::from_status(status);
53 if response.header.status != ResponseStatus::Success {
54 format_error!("Sending back an error", response.header.status);
55 }
56 if let Err(status) = response.write_to_stream(&mut connection.stream) {
57 format_error!("Failed to write response", status);
58 }
59 return;
60 }
61 };
62
63 let (app, err_response) = if AuthType::NoAuth == request.header.auth_type {
65 (None, None)
66 } else if let Some(authenticator) = self.authenticators.get(&request.header.auth_type) {
68 match authenticator.authenticate(&request.auth, connection.metadata) {
70 Ok(app) => (Some(app), None),
73 Err(status) => (
74 None,
75 Some(Response::from_request_header(request.header, status)),
76 ),
77 }
78 } else {
79 (
80 None,
81 Some(Response::from_request_header(
82 request.header,
83 ResponseStatus::AuthenticatorNotRegistered,
84 )),
85 )
86 };
87
88 let response = if let Some(err_response) = err_response {
89 err_response
90 } else {
91 if crate::utils::GlobalConfig::log_error_details() {
92 if let Some(app) = &app.as_ref() {
93 info!(
94 "New request received from application name \"{}\"",
95 app.identity().name()
96 )
97 } else {
98 info!("New request received without authentication")
99 }
100 };
101 let response = self.dispatcher.dispatch_request(request, app.clone());
102 trace!("dispatch_request egress");
103 response
104 };
105
106 match response.write_to_stream(&mut connection.stream) {
109 Ok(_) => {
110 if crate::utils::GlobalConfig::log_error_details() {
111 if let Some(app) = app {
112 info!(
113 "Response for application name \"{}\" sent back",
114 app.identity().name()
115 );
116 } else {
117 info!("Response sent back from request without authentication");
118 }
119 }
120 }
121 Err(err) => format_error!("Failed to send response", err),
122 }
123 }
124}
125
126#[derive(Default, Derivative)]
128#[derivative(Debug)]
129pub struct FrontEndHandlerBuilder {
130 dispatcher: Option<Dispatcher>,
131 #[derivative(Debug = "ignore")]
132 authenticators: Option<HashMap<AuthType, Box<dyn Authenticate + Send + Sync>>>,
133 body_len_limit: Option<usize>,
134}
135
136impl FrontEndHandlerBuilder {
137 pub fn new() -> Self {
139 FrontEndHandlerBuilder {
140 dispatcher: None,
141 authenticators: None,
142 body_len_limit: None,
143 }
144 }
145
146 pub fn with_dispatcher(mut self, dispatcher: Dispatcher) -> Self {
148 self.dispatcher = Some(dispatcher);
149 self
150 }
151
152 pub fn with_authenticator(
154 mut self,
155 auth_type: AuthType,
156 authenticator: Box<dyn Authenticate + Send + Sync>,
157 ) -> Self {
158 match &mut self.authenticators {
159 Some(authenticators) => {
160 let _ = authenticators.insert(auth_type, authenticator);
161 }
162 None => {
163 let mut map = HashMap::new();
164 let _ = map.insert(auth_type, authenticator);
165 self.authenticators = Some(map);
166 }
167 };
168
169 self
170 }
171
172 pub fn with_body_len_limit(mut self, body_len_limit: usize) -> Self {
174 self.body_len_limit = Some(body_len_limit);
175 self
176 }
177
178 pub fn build(self) -> Result<FrontEndHandler> {
180 Ok(FrontEndHandler {
181 dispatcher: self
182 .dispatcher
183 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "dispatcher is missing"))?,
184 authenticators: self
185 .authenticators
186 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "authenticators is missing"))?,
187 body_len_limit: self
188 .body_len_limit
189 .ok_or_else(|| Error::new(ErrorKind::InvalidData, "body_len_limit is missing"))?,
190 })
191 }
192}