1use std::convert::Infallible;
2use std::net::{IpAddr, SocketAddr};
3use std::str::FromStr;
4use std::sync::Arc;
5use std::time::Duration;
6
7use crate::ferron_res::server_software::SERVER_SOFTWARE;
8use crate::ferron_util::combine_config::combine_config;
9use crate::ferron_util::error_config::combine_error_config;
10use crate::ferron_util::error_pages::generate_default_error_page;
11use crate::ferron_util::url_sanitizer::sanitize_url;
12
13use crate::ferron_common::{
14 ErrorLogger, LogMessage, RequestData, ServerModuleHandlers, SocketData,
15};
16use async_channel::Sender;
17use chrono::prelude::*;
18use futures_util::TryStreamExt;
19use http::header::CONTENT_TYPE;
20use http_body_util::combinators::BoxBody;
21use http_body_util::{BodyExt, Empty, Full, StreamBody};
22use hyper::body::{Body, Bytes, Frame};
23use hyper::header::{self, HeaderName, HeaderValue};
24use hyper::{HeaderMap, Method, Request, Response, StatusCode};
25use hyper_tungstenite::is_upgrade_request;
26use tokio::fs;
27use tokio::io::BufReader;
28use tokio::time::timeout;
29use tokio_rustls_acme2::ResolvesServerCertAcme;
30use tokio_util::io::ReaderStream;
31use yaml_rust2::Yaml;
32
33async fn generate_error_response(
34 status_code: StatusCode,
35 config: &Yaml,
36 headers: &Option<HeaderMap>,
37) -> Response<BoxBody<Bytes, std::io::Error>> {
38 let bare_body =
39 generate_default_error_page(status_code, config["serverAdministratorEmail"].as_str());
40 let mut content_length: Option<u64> = bare_body.len().try_into().ok();
41 let mut response_body = Full::new(Bytes::from(bare_body))
42 .map_err(|e| match e {})
43 .boxed();
44
45 if let Some(error_pages) = config["errorPages"].as_vec() {
46 for error_page_yaml in error_pages {
47 if let Some(page_status_code) = error_page_yaml["scode"].as_i64() {
48 let page_status_code = match StatusCode::from_u16(match page_status_code.try_into() {
49 Ok(status_code) => status_code,
50 Err(_) => continue,
51 }) {
52 Ok(status_code) => status_code,
53 Err(_) => continue,
54 };
55 if status_code != page_status_code {
56 continue;
57 }
58 if let Some(page_path) = error_page_yaml["path"].as_str() {
59 let file = fs::File::open(page_path).await;
60
61 let file = match file {
62 Ok(file) => file,
63 Err(_) => continue,
64 };
65
66 content_length = match file.metadata().await {
67 Ok(metadata) => Some(metadata.len()),
68 Err(_) => None,
69 };
70
71 let reader_stream = ReaderStream::new(BufReader::with_capacity(12800, file));
73
74 let stream_body = StreamBody::new(reader_stream.map_ok(Frame::data));
75 let boxed_body = stream_body.boxed();
76
77 response_body = boxed_body;
78
79 break;
80 }
81 }
82 }
83 }
84
85 let mut response_builder = Response::builder().status(status_code);
86
87 if let Some(headers) = headers {
88 let headers_iter = headers.iter();
89 for (name, value) in headers_iter {
90 if name != header::CONTENT_TYPE && name != header::CONTENT_LENGTH {
91 response_builder = response_builder.header(name, value);
92 }
93 }
94 }
95
96 if let Some(content_length) = content_length {
97 response_builder = response_builder.header(header::CONTENT_LENGTH, content_length);
98 }
99 response_builder =
100 response_builder.header(header::CONTENT_TYPE, HeaderValue::from_static("text/html"));
101
102 response_builder.body(response_body).unwrap_or_default()
103}
104
105#[allow(clippy::too_many_arguments)]
106async fn log_combined(
107 logger: &Sender<LogMessage>,
108 client_ip: IpAddr,
109 auth_user: Option<String>,
110 method: String,
111 request_path: String,
112 protocol: String,
113 status_code: u16,
114 content_length: Option<u64>,
115 referrer: Option<String>,
116 user_agent: Option<String>,
117) {
118 let now: DateTime<Local> = Local::now();
119 let formatted_time = now.format("%d/%b/%Y:%H:%M:%S %z").to_string();
120 logger
121 .send(LogMessage::new(
122 format!(
123 "{} - {} [{}] \"{} {} {}\" {} {} {} {}",
124 client_ip,
125 match auth_user {
126 Some(auth_user) => auth_user,
127 None => String::from("-"),
128 },
129 formatted_time,
130 method,
131 request_path,
132 protocol,
133 status_code,
134 match content_length {
135 Some(content_length) => format!("{content_length}"),
136 None => String::from("-"),
137 },
138 match referrer {
139 Some(referrer) => format!(
140 "\"{}\"",
141 referrer.replace("\\", "\\\\").replace("\"", "\\\"")
142 ),
143 None => String::from("-"),
144 },
145 match user_agent {
146 Some(user_agent) => format!(
147 "\"{}\"",
148 user_agent.replace("\\", "\\\\").replace("\"", "\\\"")
149 ),
150 None => String::from("-"),
151 },
152 ),
153 false,
154 ))
155 .await
156 .unwrap_or_default();
157}
158
159#[allow(clippy::too_many_arguments)]
160async fn request_handler_wrapped(
161 mut request: Request<BoxBody<Bytes, std::io::Error>>,
162 remote_address: SocketAddr,
163 local_address: SocketAddr,
164 encrypted: bool,
165 config: Arc<Yaml>,
166 logger: Sender<LogMessage>,
167 handlers_vec: Vec<Box<dyn ServerModuleHandlers + Send>>,
168 acme_http01_resolver_option: Option<Arc<ResolvesServerCertAcme>>,
169 http3_alt_port: Option<u16>,
170) -> Result<Response<BoxBody<Bytes, std::io::Error>>, Infallible> {
171 let is_proxy_request = match request.version() {
172 hyper::Version::HTTP_2 | hyper::Version::HTTP_3 => {
173 request.method() == hyper::Method::CONNECT && request.uri().host().is_some()
174 }
175 _ => request.uri().host().is_some(),
176 };
177 let is_connect_proxy_request = request.method() == hyper::Method::CONNECT;
178
179 let log_method = String::from(request.method().as_str());
181 let log_request_path = match is_proxy_request {
182 true => request.uri().to_string(),
183 false => format!(
184 "{}{}",
185 request.uri().path(),
186 match request.uri().query() {
187 Some(query) => format!("?{query}"),
188 None => String::from(""),
189 }
190 ),
191 };
192 let log_protocol = String::from(match request.version() {
193 hyper::Version::HTTP_09 => "HTTP/0.9",
194 hyper::Version::HTTP_10 => "HTTP/1.0",
195 hyper::Version::HTTP_11 => "HTTP/1.1",
196 hyper::Version::HTTP_2 => "HTTP/2.0",
197 hyper::Version::HTTP_3 => "HTTP/3.0",
198 _ => "HTTP/Unknown",
199 });
200 let log_referrer = match request.headers().get(header::REFERER) {
201 Some(header_value) => match header_value.to_str() {
202 Ok(header_value) => Some(String::from(header_value)),
203 Err(_) => None,
204 },
205 None => None,
206 };
207 let log_user_agent = match request.headers().get(header::USER_AGENT) {
208 Some(header_value) => match header_value.to_str() {
209 Ok(header_value) => Some(String::from(header_value)),
210 Err(_) => None,
211 },
212 None => None,
213 };
214 let log_enabled = config["global"]["logFilePath"].as_str().is_some();
215 let error_log_enabled = config["global"]["errorLogFilePath"].as_str().is_some();
216
217 let mut socket_data = SocketData::new(remote_address, local_address, encrypted);
219
220 match request.version() {
221 hyper::Version::HTTP_2 | hyper::Version::HTTP_3 => {
222 if let Some(authority) = request.uri().authority() {
224 let authority = authority.to_owned();
225 let headers = request.headers_mut();
226 if !headers.contains_key(header::HOST) {
227 if let Ok(authority_value) = HeaderValue::from_bytes(authority.as_str().as_bytes()) {
228 headers.append(header::HOST, authority_value);
229 }
230 }
231 }
232
233 let mut cookie_normalized = String::new();
235 let mut cookie_set = false;
236 let headers = request.headers_mut();
237 for cookie in headers.get_all(header::COOKIE) {
238 if let Ok(cookie) = cookie.to_str() {
239 if cookie_set {
240 cookie_normalized.push_str("; ");
241 }
242 cookie_set = true;
243 cookie_normalized.push_str(cookie);
244 }
245 }
246 if cookie_set {
247 if let Ok(cookie_value) = HeaderValue::from_bytes(cookie_normalized.as_bytes()) {
248 headers.insert(header::COOKIE, cookie_value);
249 }
250 }
251 }
252 _ => (),
253 }
254
255 let host_header_option = request.headers().get(header::HOST);
256 if let Some(header_data) = host_header_option {
257 match header_data.to_str() {
258 Ok(host_header) => {
259 let host_header_lower_case = host_header.to_lowercase();
260 if host_header_lower_case != *host_header {
261 let host_header_value = match HeaderValue::from_str(&host_header_lower_case) {
262 Ok(host_header_value) => host_header_value,
263 Err(err) => {
264 if error_log_enabled {
265 logger
266 .send(LogMessage::new(
267 format!("Host header sanitation error: {err}"),
268 true,
269 ))
270 .await
271 .unwrap_or_default();
272 }
273 let response = Response::builder()
274 .status(StatusCode::BAD_REQUEST)
275 .header(header::CONTENT_TYPE, HeaderValue::from_static("text/html"))
276 .body(
277 Full::new(Bytes::from(generate_default_error_page(
278 StatusCode::BAD_REQUEST,
279 None,
280 )))
281 .map_err(|e| match e {})
282 .boxed(),
283 )
284 .unwrap_or_default();
285
286 if log_enabled {
287 log_combined(
288 &logger,
289 socket_data.remote_addr.ip(),
290 None,
291 log_method,
292 log_request_path,
293 log_protocol,
294 response.status().as_u16(),
295 match response.headers().get(header::CONTENT_LENGTH) {
296 Some(header_value) => match header_value.to_str() {
297 Ok(header_value) => match header_value.parse::<u64>() {
298 Ok(content_length) => Some(content_length),
299 Err(_) => response.body().size_hint().exact(),
300 },
301 Err(_) => response.body().size_hint().exact(),
302 },
303 None => response.body().size_hint().exact(),
304 },
305 log_referrer,
306 log_user_agent,
307 )
308 .await;
309 }
310 let (mut response_parts, response_body) = response.into_parts();
311 if let Some(http3_alt_port) = http3_alt_port {
312 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
313 Some(value) => {
314 let header_value_old = String::from_utf8_lossy(value.as_bytes());
315 let header_value_new =
316 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
317
318 if header_value_old != header_value_new {
319 HeaderValue::from_bytes(
320 format!("{header_value_old}, {header_value_new}").as_bytes(),
321 )
322 } else {
323 HeaderValue::from_bytes(header_value_old.as_bytes())
324 }
325 }
326 None => HeaderValue::from_bytes(
327 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
328 ),
329 } {
330 response_parts.headers.insert(header::ALT_SVC, header_value);
331 }
332 }
333 response_parts
334 .headers
335 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
336
337 return Ok(Response::from_parts(response_parts, response_body));
338 }
339 };
340
341 request
342 .headers_mut()
343 .insert(header::HOST, host_header_value);
344 }
345 }
346 Err(err) => {
347 if error_log_enabled {
348 logger
349 .send(LogMessage::new(
350 format!("Host header sanitation error: {err}"),
351 true,
352 ))
353 .await
354 .unwrap_or_default();
355 }
356 let response = Response::builder()
357 .status(StatusCode::BAD_REQUEST)
358 .header(header::CONTENT_TYPE, HeaderValue::from_static("text/html"))
359 .body(
360 Full::new(Bytes::from(generate_default_error_page(
361 StatusCode::BAD_REQUEST,
362 None,
363 )))
364 .map_err(|e| match e {})
365 .boxed(),
366 )
367 .unwrap_or_default();
368 if log_enabled {
369 log_combined(
370 &logger,
371 socket_data.remote_addr.ip(),
372 None,
373 log_method,
374 log_request_path,
375 log_protocol,
376 response.status().as_u16(),
377 match response.headers().get(header::CONTENT_LENGTH) {
378 Some(header_value) => match header_value.to_str() {
379 Ok(header_value) => match header_value.parse::<u64>() {
380 Ok(content_length) => Some(content_length),
381 Err(_) => response.body().size_hint().exact(),
382 },
383 Err(_) => response.body().size_hint().exact(),
384 },
385 None => response.body().size_hint().exact(),
386 },
387 log_referrer,
388 log_user_agent,
389 )
390 .await;
391 }
392 let (mut response_parts, response_body) = response.into_parts();
393 if let Some(http3_alt_port) = http3_alt_port {
394 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
395 Some(value) => {
396 let header_value_old = String::from_utf8_lossy(value.as_bytes());
397 let header_value_new =
398 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
399
400 if header_value_old != header_value_new {
401 HeaderValue::from_bytes(
402 format!("{header_value_old}, {header_value_new}").as_bytes(),
403 )
404 } else {
405 HeaderValue::from_bytes(header_value_old.as_bytes())
406 }
407 }
408 None => HeaderValue::from_bytes(
409 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
410 ),
411 } {
412 response_parts.headers.insert(header::ALT_SVC, header_value);
413 }
414 }
415 response_parts
416 .headers
417 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
418
419 return Ok(Response::from_parts(response_parts, response_body));
420 }
421 }
422 };
423
424 let mut combined_config = match combine_config(
426 config.clone(),
427 match is_proxy_request || is_connect_proxy_request {
428 false => match request.headers().get(header::HOST) {
429 Some(value) => value.to_str().ok(),
430 None => None,
431 },
432 true => None,
433 },
434 local_address.ip(),
435 request.uri().path(),
436 ) {
437 Some(config) => config,
438 None => {
439 if error_log_enabled {
440 logger
441 .send(LogMessage::new(
442 String::from("Cannot determine server configuration"),
443 true,
444 ))
445 .await
446 .unwrap_or_default();
447 }
448 let response = Response::builder()
449 .status(StatusCode::INTERNAL_SERVER_ERROR)
450 .header(header::CONTENT_TYPE, HeaderValue::from_static("text/html"))
451 .body(
452 Full::new(Bytes::from(generate_default_error_page(
453 StatusCode::INTERNAL_SERVER_ERROR,
454 None,
455 )))
456 .map_err(|e| match e {})
457 .boxed(),
458 )
459 .unwrap_or_default();
460 if log_enabled {
461 log_combined(
462 &logger,
463 socket_data.remote_addr.ip(),
464 None,
465 log_method,
466 log_request_path,
467 log_protocol,
468 response.status().as_u16(),
469 match response.headers().get(header::CONTENT_LENGTH) {
470 Some(header_value) => match header_value.to_str() {
471 Ok(header_value) => match header_value.parse::<u64>() {
472 Ok(content_length) => Some(content_length),
473 Err(_) => response.body().size_hint().exact(),
474 },
475 Err(_) => response.body().size_hint().exact(),
476 },
477 None => response.body().size_hint().exact(),
478 },
479 log_referrer,
480 log_user_agent,
481 )
482 .await;
483 }
484 let (mut response_parts, response_body) = response.into_parts();
485 if let Some(http3_alt_port) = http3_alt_port {
486 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
487 Some(value) => {
488 let header_value_old = String::from_utf8_lossy(value.as_bytes());
489 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
490
491 if header_value_old != header_value_new {
492 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
493 } else {
494 HeaderValue::from_bytes(header_value_old.as_bytes())
495 }
496 }
497 None => HeaderValue::from_bytes(
498 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
499 ),
500 } {
501 response_parts.headers.insert(header::ALT_SVC, header_value);
502 }
503 }
504 response_parts
505 .headers
506 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
507
508 return Ok(Response::from_parts(response_parts, response_body));
509 }
510 };
511
512 let url_pathname = request.uri().path();
513 let sanitized_url_pathname = match sanitize_url(
514 url_pathname,
515 combined_config["allowDoubleSlashes"]
516 .as_bool()
517 .unwrap_or_default(),
518 ) {
519 Ok(sanitized_url) => sanitized_url,
520 Err(err) => {
521 if error_log_enabled {
522 logger
523 .send(LogMessage::new(
524 format!("URL sanitation error: {err}"),
525 true,
526 ))
527 .await
528 .unwrap_or_default();
529 }
530 let response =
531 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
532 if log_enabled {
533 log_combined(
534 &logger,
535 socket_data.remote_addr.ip(),
536 None,
537 log_method,
538 log_request_path,
539 log_protocol,
540 response.status().as_u16(),
541 match response.headers().get(header::CONTENT_LENGTH) {
542 Some(header_value) => match header_value.to_str() {
543 Ok(header_value) => match header_value.parse::<u64>() {
544 Ok(content_length) => Some(content_length),
545 Err(_) => response.body().size_hint().exact(),
546 },
547 Err(_) => response.body().size_hint().exact(),
548 },
549 None => response.body().size_hint().exact(),
550 },
551 log_referrer,
552 log_user_agent,
553 )
554 .await;
555 }
556 let (mut response_parts, response_body) = response.into_parts();
557 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
558 let custom_headers_hash_iter = custom_headers_hash.iter();
559 for (header_name, header_value) in custom_headers_hash_iter {
560 if let Some(header_name) = header_name.as_str() {
561 if let Some(header_value) = header_value.as_str() {
562 if !response_parts.headers.contains_key(header_name) {
563 if let Ok(header_value) =
564 HeaderValue::from_str(&header_value.replace("{path}", url_pathname))
565 {
566 if let Ok(header_name) = HeaderName::from_str(header_name) {
567 response_parts.headers.insert(header_name, header_value);
568 }
569 }
570 }
571 }
572 }
573 }
574 }
575 if let Some(http3_alt_port) = http3_alt_port {
576 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
577 Some(value) => {
578 let header_value_old = String::from_utf8_lossy(value.as_bytes());
579 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
580
581 if header_value_old != header_value_new {
582 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
583 } else {
584 HeaderValue::from_bytes(header_value_old.as_bytes())
585 }
586 }
587 None => HeaderValue::from_bytes(
588 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
589 ),
590 } {
591 response_parts.headers.insert(header::ALT_SVC, header_value);
592 }
593 }
594 response_parts
595 .headers
596 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
597
598 return Ok(Response::from_parts(response_parts, response_body));
599 }
600 };
601
602 if sanitized_url_pathname != url_pathname {
603 let (mut parts, body) = request.into_parts();
604 let mut url_parts = parts.uri.into_parts();
605 url_parts.path_and_query = Some(
606 match format!(
607 "{}{}",
608 sanitized_url_pathname,
609 match url_parts.path_and_query {
610 Some(path_and_query) => {
611 match path_and_query.query() {
612 Some(query) => format!("?{query}"),
613 None => String::from(""),
614 }
615 }
616 None => String::from(""),
617 }
618 )
619 .parse()
620 {
621 Ok(path_and_query) => path_and_query,
622 Err(err) => {
623 if error_log_enabled {
624 logger
625 .send(LogMessage::new(
626 format!("URL sanitation error: {err}"),
627 true,
628 ))
629 .await
630 .unwrap_or_default();
631 }
632 let response =
633 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
634 if log_enabled {
635 log_combined(
636 &logger,
637 socket_data.remote_addr.ip(),
638 None,
639 log_method,
640 log_request_path,
641 log_protocol,
642 response.status().as_u16(),
643 match response.headers().get(header::CONTENT_LENGTH) {
644 Some(header_value) => match header_value.to_str() {
645 Ok(header_value) => match header_value.parse::<u64>() {
646 Ok(content_length) => Some(content_length),
647 Err(_) => response.body().size_hint().exact(),
648 },
649 Err(_) => response.body().size_hint().exact(),
650 },
651 None => response.body().size_hint().exact(),
652 },
653 log_referrer,
654 log_user_agent,
655 )
656 .await;
657 }
658 let (mut response_parts, response_body) = response.into_parts();
659 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
660 let custom_headers_hash_iter = custom_headers_hash.iter();
661 for (header_name, header_value) in custom_headers_hash_iter {
662 if let Some(header_name) = header_name.as_str() {
663 if let Some(header_value) = header_value.as_str() {
664 if !response_parts.headers.contains_key(header_name) {
665 if let Ok(header_value) = HeaderValue::from_str(
666 &header_value.replace("{path}", &sanitized_url_pathname),
667 ) {
668 if let Ok(header_name) = HeaderName::from_str(header_name) {
669 response_parts.headers.insert(header_name, header_value);
670 }
671 }
672 }
673 }
674 }
675 }
676 }
677 if let Some(http3_alt_port) = http3_alt_port {
678 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
679 Some(value) => {
680 let header_value_old = String::from_utf8_lossy(value.as_bytes());
681 let header_value_new =
682 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
683
684 if header_value_old != header_value_new {
685 HeaderValue::from_bytes(
686 format!("{header_value_old}, {header_value_new}").as_bytes(),
687 )
688 } else {
689 HeaderValue::from_bytes(header_value_old.as_bytes())
690 }
691 }
692 None => HeaderValue::from_bytes(
693 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
694 ),
695 } {
696 response_parts.headers.insert(header::ALT_SVC, header_value);
697 }
698 }
699 response_parts
700 .headers
701 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
702
703 return Ok(Response::from_parts(response_parts, response_body));
704 }
705 },
706 );
707 parts.uri = match hyper::Uri::from_parts(url_parts) {
708 Ok(uri) => uri,
709 Err(err) => {
710 if error_log_enabled {
711 logger
712 .send(LogMessage::new(
713 format!("URL sanitation error: {err}"),
714 true,
715 ))
716 .await
717 .unwrap_or_default();
718 }
719 let response =
720 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
721 if log_enabled {
722 log_combined(
723 &logger,
724 socket_data.remote_addr.ip(),
725 None,
726 log_method,
727 log_request_path,
728 log_protocol,
729 response.status().as_u16(),
730 match response.headers().get(header::CONTENT_LENGTH) {
731 Some(header_value) => match header_value.to_str() {
732 Ok(header_value) => match header_value.parse::<u64>() {
733 Ok(content_length) => Some(content_length),
734 Err(_) => response.body().size_hint().exact(),
735 },
736 Err(_) => response.body().size_hint().exact(),
737 },
738 None => response.body().size_hint().exact(),
739 },
740 log_referrer,
741 log_user_agent,
742 )
743 .await;
744 }
745 let (mut response_parts, response_body) = response.into_parts();
746 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
747 let custom_headers_hash_iter = custom_headers_hash.iter();
748 for (header_name, header_value) in custom_headers_hash_iter {
749 if let Some(header_name) = header_name.as_str() {
750 if let Some(header_value) = header_value.as_str() {
751 if !response_parts.headers.contains_key(header_name) {
752 if let Ok(header_value) =
753 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
754 {
755 if let Ok(header_name) = HeaderName::from_str(header_name) {
756 response_parts.headers.insert(header_name, header_value);
757 }
758 }
759 }
760 }
761 }
762 }
763 }
764 if let Some(http3_alt_port) = http3_alt_port {
765 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
766 Some(value) => {
767 let header_value_old = String::from_utf8_lossy(value.as_bytes());
768 let header_value_new =
769 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
770
771 if header_value_old != header_value_new {
772 HeaderValue::from_bytes(
773 format!("{header_value_old}, {header_value_new}").as_bytes(),
774 )
775 } else {
776 HeaderValue::from_bytes(header_value_old.as_bytes())
777 }
778 }
779 None => HeaderValue::from_bytes(
780 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
781 ),
782 } {
783 response_parts.headers.insert(header::ALT_SVC, header_value);
784 }
785 }
786 response_parts
787 .headers
788 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
789
790 return Ok(Response::from_parts(response_parts, response_body));
791 }
792 };
793 request = Request::from_parts(parts, body);
794 if let Some(new_combined_config) = combine_config(
795 config.clone(),
796 match is_proxy_request || is_connect_proxy_request {
797 false => match request.headers().get(header::HOST) {
798 Some(value) => value.to_str().ok(),
799 None => None,
800 },
801 true => None,
802 },
803 local_address.ip(),
804 request.uri().path(),
805 ) {
806 combined_config = new_combined_config;
807 }
808 }
809 drop(config);
810
811 if request.uri().path() == "*" {
812 let response = match request.method() {
813 &Method::OPTIONS => Response::builder()
814 .status(StatusCode::NO_CONTENT)
815 .header(
816 header::ALLOW,
817 HeaderValue::from_static("GET, POST, HEAD, OPTIONS"),
818 )
819 .body(Empty::new().map_err(|e| match e {}).boxed())
820 .unwrap_or_default(),
821 _ => {
822 let mut header_map = HeaderMap::new();
823 header_map.insert(
824 header::ALLOW,
825 HeaderValue::from_static("GET, POST, HEAD, OPTIONS"),
826 );
827 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &Some(header_map)).await
828 }
829 };
830 if log_enabled {
831 log_combined(
832 &logger,
833 socket_data.remote_addr.ip(),
834 None,
835 log_method,
836 log_request_path,
837 log_protocol,
838 response.status().as_u16(),
839 match response.headers().get(header::CONTENT_LENGTH) {
840 Some(header_value) => match header_value.to_str() {
841 Ok(header_value) => match header_value.parse::<u64>() {
842 Ok(content_length) => Some(content_length),
843 Err(_) => response.body().size_hint().exact(),
844 },
845 Err(_) => response.body().size_hint().exact(),
846 },
847 None => response.body().size_hint().exact(),
848 },
849 log_referrer,
850 log_user_agent,
851 )
852 .await;
853 }
854 let (mut response_parts, response_body) = response.into_parts();
855 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
856 let custom_headers_hash_iter = custom_headers_hash.iter();
857 for (header_name, header_value) in custom_headers_hash_iter {
858 if let Some(header_name) = header_name.as_str() {
859 if let Some(header_value) = header_value.as_str() {
860 if !response_parts.headers.contains_key(header_name) {
861 if let Ok(header_value) =
862 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
863 {
864 if let Ok(header_name) = HeaderName::from_str(header_name) {
865 response_parts.headers.insert(header_name, header_value);
866 }
867 }
868 }
869 }
870 }
871 }
872 }
873 if let Some(http3_alt_port) = http3_alt_port {
874 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
875 Some(value) => {
876 let header_value_old = String::from_utf8_lossy(value.as_bytes());
877 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
878
879 if header_value_old != header_value_new {
880 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
881 } else {
882 HeaderValue::from_bytes(header_value_old.as_bytes())
883 }
884 }
885 None => HeaderValue::from_bytes(
886 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
887 ),
888 } {
889 response_parts.headers.insert(header::ALT_SVC, header_value);
890 }
891 }
892 response_parts
893 .headers
894 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
895
896 return Ok(Response::from_parts(response_parts, response_body));
897 }
898
899 if let Some(acme_http01_resolver) = acme_http01_resolver_option {
901 if let Some(challenge_token) = request
902 .uri()
903 .path()
904 .strip_prefix("/.well-known/acme-challenge/")
905 {
906 if let Some(acme_response) = acme_http01_resolver.get_http_01_key_auth(challenge_token) {
907 let response = Response::builder()
908 .status(StatusCode::OK)
909 .header(
910 CONTENT_TYPE,
911 HeaderValue::from_static("application/octet-stream"),
912 )
913 .body(
914 Full::new(Bytes::from(acme_response))
915 .map_err(|e| match e {})
916 .boxed(),
917 )
918 .unwrap_or_default();
919
920 let (mut response_parts, response_body) = response.into_parts();
921 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
922 let custom_headers_hash_iter = custom_headers_hash.iter();
923 for (header_name, header_value) in custom_headers_hash_iter {
924 if let Some(header_name) = header_name.as_str() {
925 if let Some(header_value) = header_value.as_str() {
926 if !response_parts.headers.contains_key(header_name) {
927 if let Ok(header_value) =
928 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
929 {
930 if let Ok(header_name) = HeaderName::from_str(header_name) {
931 response_parts.headers.insert(header_name, header_value);
932 }
933 }
934 }
935 }
936 }
937 }
938 }
939 if let Some(http3_alt_port) = http3_alt_port {
940 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
941 Some(value) => {
942 let header_value_old = String::from_utf8_lossy(value.as_bytes());
943 let header_value_new =
944 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
945
946 if header_value_old != header_value_new {
947 HeaderValue::from_bytes(
948 format!("{header_value_old}, {header_value_new}").as_bytes(),
949 )
950 } else {
951 HeaderValue::from_bytes(header_value_old.as_bytes())
952 }
953 }
954 None => HeaderValue::from_bytes(
955 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
956 ),
957 } {
958 response_parts.headers.insert(header::ALT_SVC, header_value);
959 }
960 }
961 response_parts
962 .headers
963 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
964
965 let response = Response::from_parts(response_parts, response_body);
966
967 if log_enabled {
968 log_combined(
969 &logger,
970 socket_data.remote_addr.ip(),
971 None,
972 log_method,
973 log_request_path,
974 log_protocol,
975 response.status().as_u16(),
976 match response.headers().get(header::CONTENT_LENGTH) {
977 Some(header_value) => match header_value.to_str() {
978 Ok(header_value) => match header_value.parse::<u64>() {
979 Ok(content_length) => Some(content_length),
980 Err(_) => response.body().size_hint().exact(),
981 },
982 Err(_) => response.body().size_hint().exact(),
983 },
984 None => response.body().size_hint().exact(),
985 },
986 log_referrer,
987 log_user_agent,
988 )
989 .await;
990 }
991 return Ok(response);
992 }
993 }
994 };
995
996 let cloned_logger = logger.clone();
997 let error_logger = match error_log_enabled {
998 true => ErrorLogger::new(cloned_logger),
999 false => ErrorLogger::without_logger(),
1000 };
1001
1002 if is_connect_proxy_request {
1003 let mut connect_proxy_handlers = None;
1004 for mut handlers in handlers_vec {
1005 if handlers.does_connect_proxy_requests() {
1006 connect_proxy_handlers = Some(handlers);
1007 break;
1008 }
1009 }
1010
1011 if let Some(mut connect_proxy_handlers) = connect_proxy_handlers {
1012 if let Some(connect_address) = request.uri().authority().map(|auth| auth.to_string()) {
1013 let client_ip = socket_data.remote_addr.ip();
1015 let custom_headers_yaml = combined_config["customHeaders"].clone();
1016
1017 tokio::spawn(async move {
1018 match hyper::upgrade::on(request).await {
1019 Ok(upgraded_request) => {
1020 let result = connect_proxy_handlers
1021 .connect_proxy_request_handler(
1022 upgraded_request,
1023 &connect_address,
1024 &combined_config,
1025 &socket_data,
1026 &error_logger,
1027 )
1028 .await;
1029 match result {
1030 Ok(_) => (),
1031 Err(err) => {
1032 error_logger
1033 .log(&format!("Unexpected error for CONNECT request: {err}"))
1034 .await;
1035 }
1036 }
1037 }
1038 Err(err) => {
1039 error_logger
1040 .log(&format!(
1041 "Error while upgrading HTTP CONNECT request: {err}"
1042 ))
1043 .await
1044 }
1045 }
1046 });
1047
1048 let response = Response::builder()
1049 .body(Empty::new().map_err(|e| match e {}).boxed())
1050 .unwrap_or_default();
1051
1052 if log_enabled {
1053 log_combined(
1054 &logger,
1055 client_ip,
1056 None,
1057 log_method,
1058 log_request_path,
1059 log_protocol,
1060 response.status().as_u16(),
1061 match response.headers().get(header::CONTENT_LENGTH) {
1062 Some(header_value) => match header_value.to_str() {
1063 Ok(header_value) => match header_value.parse::<u64>() {
1064 Ok(content_length) => Some(content_length),
1065 Err(_) => response.body().size_hint().exact(),
1066 },
1067 Err(_) => response.body().size_hint().exact(),
1068 },
1069 None => response.body().size_hint().exact(),
1070 },
1071 log_referrer,
1072 log_user_agent,
1073 )
1074 .await;
1075 }
1076
1077 let (mut response_parts, response_body) = response.into_parts();
1078 if let Some(custom_headers_hash) = custom_headers_yaml.as_hash() {
1079 let custom_headers_hash_iter = custom_headers_hash.iter();
1080 for (header_name, header_value) in custom_headers_hash_iter {
1081 if let Some(header_name) = header_name.as_str() {
1082 if let Some(header_value) = header_value.as_str() {
1083 if !response_parts.headers.contains_key(header_name) {
1084 if let Ok(header_value) =
1085 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1086 {
1087 if let Ok(header_name) = HeaderName::from_str(header_name) {
1088 response_parts.headers.insert(header_name, header_value);
1089 }
1090 }
1091 }
1092 }
1093 }
1094 }
1095 }
1096 if let Some(http3_alt_port) = http3_alt_port {
1097 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1098 Some(value) => {
1099 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1100 let header_value_new =
1101 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1102
1103 if header_value_old != header_value_new {
1104 HeaderValue::from_bytes(
1105 format!("{header_value_old}, {header_value_new}").as_bytes(),
1106 )
1107 } else {
1108 HeaderValue::from_bytes(header_value_old.as_bytes())
1109 }
1110 }
1111 None => HeaderValue::from_bytes(
1112 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1113 ),
1114 } {
1115 response_parts.headers.insert(header::ALT_SVC, header_value);
1116 }
1117 }
1118 response_parts
1119 .headers
1120 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1121
1122 Ok(Response::from_parts(response_parts, response_body))
1123 } else {
1124 let response = Response::builder()
1125 .status(StatusCode::BAD_REQUEST)
1126 .body(Empty::new().map_err(|e| match e {}).boxed())
1127 .unwrap_or_default();
1128
1129 if log_enabled {
1130 log_combined(
1131 &logger,
1132 socket_data.remote_addr.ip(),
1133 None,
1134 log_method,
1135 log_request_path,
1136 log_protocol,
1137 response.status().as_u16(),
1138 match response.headers().get(header::CONTENT_LENGTH) {
1139 Some(header_value) => match header_value.to_str() {
1140 Ok(header_value) => match header_value.parse::<u64>() {
1141 Ok(content_length) => Some(content_length),
1142 Err(_) => response.body().size_hint().exact(),
1143 },
1144 Err(_) => response.body().size_hint().exact(),
1145 },
1146 None => response.body().size_hint().exact(),
1147 },
1148 log_referrer,
1149 log_user_agent,
1150 )
1151 .await;
1152 }
1153 let (mut response_parts, response_body) = response.into_parts();
1154 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1155 let custom_headers_hash_iter = custom_headers_hash.iter();
1156 for (header_name, header_value) in custom_headers_hash_iter {
1157 if let Some(header_name) = header_name.as_str() {
1158 if let Some(header_value) = header_value.as_str() {
1159 if !response_parts.headers.contains_key(header_name) {
1160 if let Ok(header_value) =
1161 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1162 {
1163 if let Ok(header_name) = HeaderName::from_str(header_name) {
1164 response_parts.headers.insert(header_name, header_value);
1165 }
1166 }
1167 }
1168 }
1169 }
1170 }
1171 }
1172 if let Some(http3_alt_port) = http3_alt_port {
1173 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1174 Some(value) => {
1175 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1176 let header_value_new =
1177 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1178
1179 if header_value_old != header_value_new {
1180 HeaderValue::from_bytes(
1181 format!("{header_value_old}, {header_value_new}").as_bytes(),
1182 )
1183 } else {
1184 HeaderValue::from_bytes(header_value_old.as_bytes())
1185 }
1186 }
1187 None => HeaderValue::from_bytes(
1188 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1189 ),
1190 } {
1191 response_parts.headers.insert(header::ALT_SVC, header_value);
1192 }
1193 }
1194 response_parts
1195 .headers
1196 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1197
1198 Ok(Response::from_parts(response_parts, response_body))
1199 }
1200 } else {
1201 let response = Response::builder()
1202 .status(StatusCode::NOT_IMPLEMENTED)
1203 .body(Empty::new().map_err(|e| match e {}).boxed())
1204 .unwrap_or_default();
1205
1206 if log_enabled {
1207 log_combined(
1208 &logger,
1209 socket_data.remote_addr.ip(),
1210 None,
1211 log_method,
1212 log_request_path,
1213 log_protocol,
1214 response.status().as_u16(),
1215 match response.headers().get(header::CONTENT_LENGTH) {
1216 Some(header_value) => match header_value.to_str() {
1217 Ok(header_value) => match header_value.parse::<u64>() {
1218 Ok(content_length) => Some(content_length),
1219 Err(_) => response.body().size_hint().exact(),
1220 },
1221 Err(_) => response.body().size_hint().exact(),
1222 },
1223 None => response.body().size_hint().exact(),
1224 },
1225 log_referrer,
1226 log_user_agent,
1227 )
1228 .await;
1229 }
1230 let (mut response_parts, response_body) = response.into_parts();
1231 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1232 let custom_headers_hash_iter = custom_headers_hash.iter();
1233 for (header_name, header_value) in custom_headers_hash_iter {
1234 if let Some(header_name) = header_name.as_str() {
1235 if let Some(header_value) = header_value.as_str() {
1236 if !response_parts.headers.contains_key(header_name) {
1237 if let Ok(header_value) =
1238 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1239 {
1240 if let Ok(header_name) = HeaderName::from_str(header_name) {
1241 response_parts.headers.insert(header_name, header_value);
1242 }
1243 }
1244 }
1245 }
1246 }
1247 }
1248 }
1249 if let Some(http3_alt_port) = http3_alt_port {
1250 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1251 Some(value) => {
1252 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1253 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1254
1255 if header_value_old != header_value_new {
1256 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
1257 } else {
1258 HeaderValue::from_bytes(header_value_old.as_bytes())
1259 }
1260 }
1261 None => HeaderValue::from_bytes(
1262 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1263 ),
1264 } {
1265 response_parts.headers.insert(header::ALT_SVC, header_value);
1266 }
1267 }
1268 response_parts
1269 .headers
1270 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1271
1272 Ok(Response::from_parts(response_parts, response_body))
1273 }
1274 } else {
1275 let is_websocket_request = is_upgrade_request(&request);
1276 let (request_parts, request_body) = request.into_parts();
1277 let request_parts_cloned = if combined_config["errorConfig"].is_array() {
1278 let mut request_parts_cloned = request_parts.clone();
1279 request_parts_cloned
1280 .headers
1281 .insert(header::CONTENT_LENGTH, HeaderValue::from_static("0"));
1282 Some(request_parts_cloned)
1283 } else {
1284 None
1286 };
1287 let request = Request::from_parts(request_parts, request_body);
1288 let mut request_data = RequestData::new(request, None, None, None);
1289 let mut latest_auth_data = None;
1290 let mut error_status_code = None;
1291 let mut executed_handlers = Vec::new();
1292 let mut handlers_iter: Box<
1293 dyn Iterator<Item = Box<dyn ServerModuleHandlers + Send + 'static>> + Send,
1294 > = Box::new(handlers_vec.into_iter());
1295 while let Some(mut handlers) = handlers_iter.next() {
1296 if is_websocket_request && handlers.does_websocket_requests(&combined_config, &socket_data) {
1297 let (request, _, _, _) = request_data.into_parts();
1298
1299 let client_ip = socket_data.remote_addr.ip();
1301 let custom_headers_yaml = combined_config["customHeaders"].clone();
1302 let request_uri = request.uri().to_owned();
1303 let request_headers = request.headers().to_owned();
1304
1305 let (original_response, websocket) = match hyper_tungstenite::upgrade(request, None) {
1306 Ok(data) => data,
1307 Err(err) => {
1308 error_logger
1309 .log(&format!("Error while upgrading WebSocket request: {err}"))
1310 .await;
1311
1312 let response = Response::builder()
1313 .status(StatusCode::INTERNAL_SERVER_ERROR)
1314 .body(
1315 Full::new(Bytes::from(generate_default_error_page(
1316 StatusCode::INTERNAL_SERVER_ERROR,
1317 None,
1318 )))
1319 .map_err(|e| match e {})
1320 .boxed(),
1321 )
1322 .unwrap_or_default();
1323
1324 if log_enabled {
1325 log_combined(
1326 &logger,
1327 socket_data.remote_addr.ip(),
1328 None,
1329 log_method,
1330 log_request_path,
1331 log_protocol,
1332 response.status().as_u16(),
1333 match response.headers().get(header::CONTENT_LENGTH) {
1334 Some(header_value) => match header_value.to_str() {
1335 Ok(header_value) => match header_value.parse::<u64>() {
1336 Ok(content_length) => Some(content_length),
1337 Err(_) => response.body().size_hint().exact(),
1338 },
1339 Err(_) => response.body().size_hint().exact(),
1340 },
1341 None => response.body().size_hint().exact(),
1342 },
1343 log_referrer,
1344 log_user_agent,
1345 )
1346 .await;
1347 }
1348 let (mut response_parts, response_body) = response.into_parts();
1349 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1350 let custom_headers_hash_iter = custom_headers_hash.iter();
1351 for (header_name, header_value) in custom_headers_hash_iter {
1352 if let Some(header_name) = header_name.as_str() {
1353 if let Some(header_value) = header_value.as_str() {
1354 if !response_parts.headers.contains_key(header_name) {
1355 if let Ok(header_value) = HeaderValue::from_str(
1356 &header_value.replace("{path}", &sanitized_url_pathname),
1357 ) {
1358 if let Ok(header_name) = HeaderName::from_str(header_name) {
1359 response_parts.headers.insert(header_name, header_value);
1360 }
1361 }
1362 }
1363 }
1364 }
1365 }
1366 }
1367 if let Some(http3_alt_port) = http3_alt_port {
1368 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1369 Some(value) => {
1370 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1371 let header_value_new =
1372 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1373
1374 if header_value_old != header_value_new {
1375 HeaderValue::from_bytes(
1376 format!("{header_value_old}, {header_value_new}").as_bytes(),
1377 )
1378 } else {
1379 HeaderValue::from_bytes(header_value_old.as_bytes())
1380 }
1381 }
1382 None => HeaderValue::from_bytes(
1383 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1384 ),
1385 } {
1386 response_parts.headers.insert(header::ALT_SVC, header_value);
1387 }
1388 }
1389 response_parts
1390 .headers
1391 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1392
1393 return Ok(Response::from_parts(response_parts, response_body));
1394 }
1395 };
1396
1397 tokio::spawn(async move {
1398 let result = handlers
1399 .websocket_request_handler(
1400 websocket,
1401 &request_uri,
1402 &request_headers,
1403 &combined_config,
1404 &socket_data,
1405 &error_logger,
1406 )
1407 .await;
1408 match result {
1409 Ok(_) => (),
1410 Err(err) => {
1411 error_logger
1412 .log(&format!("Unexpected error for WebSocket request: {err}"))
1413 .await;
1414 }
1415 }
1416 });
1417
1418 let response = original_response.map(|body| body.map_err(|err| match err {}).boxed());
1419
1420 if log_enabled {
1421 log_combined(
1422 &logger,
1423 client_ip,
1424 None,
1425 log_method,
1426 log_request_path,
1427 log_protocol,
1428 response.status().as_u16(),
1429 match response.headers().get(header::CONTENT_LENGTH) {
1430 Some(header_value) => match header_value.to_str() {
1431 Ok(header_value) => match header_value.parse::<u64>() {
1432 Ok(content_length) => Some(content_length),
1433 Err(_) => response.body().size_hint().exact(),
1434 },
1435 Err(_) => response.body().size_hint().exact(),
1436 },
1437 None => response.body().size_hint().exact(),
1438 },
1439 log_referrer,
1440 log_user_agent,
1441 )
1442 .await;
1443 }
1444
1445 let (mut response_parts, response_body) = response.into_parts();
1446 if let Some(custom_headers_hash) = custom_headers_yaml.as_hash() {
1447 let custom_headers_hash_iter = custom_headers_hash.iter();
1448 for (header_name, header_value) in custom_headers_hash_iter {
1449 if let Some(header_name) = header_name.as_str() {
1450 if let Some(header_value) = header_value.as_str() {
1451 if !response_parts.headers.contains_key(header_name) {
1452 if let Ok(header_value) =
1453 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1454 {
1455 if let Ok(header_name) = HeaderName::from_str(header_name) {
1456 response_parts.headers.insert(header_name, header_value);
1457 }
1458 }
1459 }
1460 }
1461 }
1462 }
1463 }
1464 if let Some(http3_alt_port) = http3_alt_port {
1465 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1466 Some(value) => {
1467 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1468 let header_value_new =
1469 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1470
1471 if header_value_old != header_value_new {
1472 HeaderValue::from_bytes(
1473 format!("{header_value_old}, {header_value_new}").as_bytes(),
1474 )
1475 } else {
1476 HeaderValue::from_bytes(header_value_old.as_bytes())
1477 }
1478 }
1479 None => HeaderValue::from_bytes(
1480 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1481 ),
1482 } {
1483 response_parts.headers.insert(header::ALT_SVC, header_value);
1484 }
1485 }
1486 response_parts
1487 .headers
1488 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1489
1490 return Ok(Response::from_parts(response_parts, response_body));
1491 }
1492
1493 let response_result = match is_proxy_request {
1494 true => {
1495 handlers
1496 .proxy_request_handler(request_data, &combined_config, &socket_data, &error_logger)
1497 .await
1498 }
1499 false => {
1500 handlers
1501 .request_handler(request_data, &combined_config, &socket_data, &error_logger)
1502 .await
1503 }
1504 };
1505
1506 executed_handlers.push(handlers);
1507 match response_result {
1508 Ok(response) => {
1509 let (
1510 request_option,
1511 auth_data,
1512 original_url,
1513 response,
1514 status,
1515 headers,
1516 new_remote_address,
1517 parallel_fn,
1518 ) = response.into_parts();
1519 latest_auth_data = auth_data.clone();
1520 if let Some(new_remote_address) = new_remote_address {
1521 socket_data.remote_addr = new_remote_address;
1522 };
1523 if let Some(parallel_fn) = parallel_fn {
1524 tokio::spawn(parallel_fn);
1529 }
1530 match response {
1531 Some(response) => {
1532 let (mut response_parts, response_body) = response.into_parts();
1533 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1534 let custom_headers_hash_iter = custom_headers_hash.iter();
1535 for (header_name, header_value) in custom_headers_hash_iter {
1536 if let Some(header_name) = header_name.as_str() {
1537 if let Some(header_value) = header_value.as_str() {
1538 if !response_parts.headers.contains_key(header_name) {
1539 if let Ok(header_value) = HeaderValue::from_str(
1540 &header_value.replace("{path}", &sanitized_url_pathname),
1541 ) {
1542 if let Ok(header_name) = HeaderName::from_str(header_name) {
1543 response_parts.headers.insert(header_name, header_value);
1544 }
1545 }
1546 }
1547 }
1548 }
1549 }
1550 }
1551 if let Some(http3_alt_port) = http3_alt_port {
1552 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1553 Some(value) => {
1554 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1555 let header_value_new =
1556 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1557
1558 if header_value_old != header_value_new {
1559 HeaderValue::from_bytes(
1560 format!("{header_value_old}, {header_value_new}").as_bytes(),
1561 )
1562 } else {
1563 HeaderValue::from_bytes(header_value_old.as_bytes())
1564 }
1565 }
1566 None => HeaderValue::from_bytes(
1567 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1568 ),
1569 } {
1570 response_parts.headers.insert(header::ALT_SVC, header_value);
1571 }
1572 }
1573 response_parts
1574 .headers
1575 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1576
1577 let mut response = Response::from_parts(response_parts, response_body);
1578
1579 while let Some(mut executed_handler) = executed_handlers.pop() {
1580 let response_status = match is_proxy_request {
1581 true => {
1582 executed_handler
1583 .proxy_response_modifying_handler(response)
1584 .await
1585 }
1586 false => executed_handler.response_modifying_handler(response).await,
1587 };
1588 response = match response_status {
1589 Ok(response) => response,
1590 Err(err) => {
1591 if error_log_enabled {
1592 logger
1593 .send(LogMessage::new(
1594 format!("Unexpected error while serving a request: {err}"),
1595 true,
1596 ))
1597 .await
1598 .unwrap_or_default();
1599 }
1600
1601 let response = generate_error_response(
1602 StatusCode::INTERNAL_SERVER_ERROR,
1603 &combined_config,
1604 &headers,
1605 )
1606 .await;
1607 if log_enabled {
1608 log_combined(
1609 &logger,
1610 socket_data.remote_addr.ip(),
1611 auth_data,
1612 log_method,
1613 log_request_path,
1614 log_protocol,
1615 response.status().as_u16(),
1616 match response.headers().get(header::CONTENT_LENGTH) {
1617 Some(header_value) => match header_value.to_str() {
1618 Ok(header_value) => match header_value.parse::<u64>() {
1619 Ok(content_length) => Some(content_length),
1620 Err(_) => response.body().size_hint().exact(),
1621 },
1622 Err(_) => response.body().size_hint().exact(),
1623 },
1624 None => response.body().size_hint().exact(),
1625 },
1626 log_referrer,
1627 log_user_agent,
1628 )
1629 .await;
1630 }
1631 let (mut response_parts, response_body) = response.into_parts();
1632 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1633 let custom_headers_hash_iter = custom_headers_hash.iter();
1634 for (header_name, header_value) in custom_headers_hash_iter {
1635 if let Some(header_name) = header_name.as_str() {
1636 if let Some(header_value) = header_value.as_str() {
1637 if !response_parts.headers.contains_key(header_name) {
1638 if let Ok(header_value) = HeaderValue::from_str(
1639 &header_value.replace("{path}", &sanitized_url_pathname),
1640 ) {
1641 if let Ok(header_name) = HeaderName::from_str(header_name) {
1642 response_parts.headers.insert(header_name, header_value);
1643 }
1644 }
1645 }
1646 }
1647 }
1648 }
1649 }
1650 if let Some(http3_alt_port) = http3_alt_port {
1651 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1652 Some(value) => {
1653 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1654 let header_value_new =
1655 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1656
1657 if header_value_old != header_value_new {
1658 HeaderValue::from_bytes(
1659 format!("{header_value_old}, {header_value_new}").as_bytes(),
1660 )
1661 } else {
1662 HeaderValue::from_bytes(header_value_old.as_bytes())
1663 }
1664 }
1665 None => HeaderValue::from_bytes(
1666 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"")
1667 .as_bytes(),
1668 ),
1669 } {
1670 response_parts.headers.insert(header::ALT_SVC, header_value);
1671 }
1672 }
1673 response_parts
1674 .headers
1675 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1676
1677 return Ok(Response::from_parts(response_parts, response_body));
1678 }
1679 };
1680 }
1681
1682 if log_enabled {
1683 log_combined(
1684 &logger,
1685 socket_data.remote_addr.ip(),
1686 auth_data,
1687 log_method,
1688 log_request_path,
1689 log_protocol,
1690 response.status().as_u16(),
1691 match response.headers().get(header::CONTENT_LENGTH) {
1692 Some(header_value) => match header_value.to_str() {
1693 Ok(header_value) => match header_value.parse::<u64>() {
1694 Ok(content_length) => Some(content_length),
1695 Err(_) => response.body().size_hint().exact(),
1696 },
1697 Err(_) => response.body().size_hint().exact(),
1698 },
1699 None => response.body().size_hint().exact(),
1700 },
1701 log_referrer,
1702 log_user_agent,
1703 )
1704 .await;
1705 }
1706
1707 return Ok(response);
1708 }
1709 None => match status {
1710 Some(status) => {
1711 let request = if let Some(request) = request_option {
1712 Some(request)
1713 } else {
1714 request_parts_cloned.clone().map(|request_parts_cloned| {
1715 Request::from_parts(
1716 request_parts_cloned,
1717 Empty::new().map_err(|e| match e {}).boxed(),
1718 )
1719 })
1720 };
1721 if let Some(request) = request {
1722 if let Some(combined_error_config) =
1723 combine_error_config(&combined_config, status.as_u16())
1724 {
1725 combined_config = combined_error_config;
1726 error_status_code = Some(status);
1727 handlers_iter = Box::new(executed_handlers.into_iter().chain(handlers_iter));
1728 executed_handlers = Vec::new();
1729 request_data =
1730 RequestData::new(request, auth_data, original_url, error_status_code);
1731 continue;
1732 }
1733 }
1734 let response = generate_error_response(status, &combined_config, &headers).await;
1735 let (mut response_parts, response_body) = response.into_parts();
1736 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1737 let custom_headers_hash_iter = custom_headers_hash.iter();
1738 for (header_name, header_value) in custom_headers_hash_iter {
1739 if let Some(header_name) = header_name.as_str() {
1740 if let Some(header_value) = header_value.as_str() {
1741 if !response_parts.headers.contains_key(header_name) {
1742 if let Ok(header_value) = HeaderValue::from_str(
1743 &header_value.replace("{path}", &sanitized_url_pathname),
1744 ) {
1745 if let Ok(header_name) = HeaderName::from_str(header_name) {
1746 response_parts.headers.insert(header_name, header_value);
1747 }
1748 }
1749 }
1750 }
1751 }
1752 }
1753 }
1754 if let Some(http3_alt_port) = http3_alt_port {
1755 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1756 Some(value) => {
1757 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1758 let header_value_new =
1759 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1760
1761 if header_value_old != header_value_new {
1762 HeaderValue::from_bytes(
1763 format!("{header_value_old}, {header_value_new}").as_bytes(),
1764 )
1765 } else {
1766 HeaderValue::from_bytes(header_value_old.as_bytes())
1767 }
1768 }
1769 None => HeaderValue::from_bytes(
1770 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1771 ),
1772 } {
1773 response_parts.headers.insert(header::ALT_SVC, header_value);
1774 }
1775 }
1776 response_parts
1777 .headers
1778 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1779
1780 let mut response = Response::from_parts(response_parts, response_body);
1781
1782 while let Some(mut executed_handler) = executed_handlers.pop() {
1783 let response_status = match is_proxy_request {
1784 true => {
1785 executed_handler
1786 .proxy_response_modifying_handler(response)
1787 .await
1788 }
1789 false => executed_handler.response_modifying_handler(response).await,
1790 };
1791 response = match response_status {
1792 Ok(response) => response,
1793 Err(err) => {
1794 if error_log_enabled {
1795 logger
1796 .send(LogMessage::new(
1797 format!("Unexpected error while serving a request: {err}"),
1798 true,
1799 ))
1800 .await
1801 .unwrap_or_default();
1802 }
1803
1804 let response = generate_error_response(
1805 StatusCode::INTERNAL_SERVER_ERROR,
1806 &combined_config,
1807 &headers,
1808 )
1809 .await;
1810 if log_enabled {
1811 log_combined(
1812 &logger,
1813 socket_data.remote_addr.ip(),
1814 auth_data,
1815 log_method,
1816 log_request_path,
1817 log_protocol,
1818 response.status().as_u16(),
1819 match response.headers().get(header::CONTENT_LENGTH) {
1820 Some(header_value) => match header_value.to_str() {
1821 Ok(header_value) => match header_value.parse::<u64>() {
1822 Ok(content_length) => Some(content_length),
1823 Err(_) => response.body().size_hint().exact(),
1824 },
1825 Err(_) => response.body().size_hint().exact(),
1826 },
1827 None => response.body().size_hint().exact(),
1828 },
1829 log_referrer,
1830 log_user_agent,
1831 )
1832 .await;
1833 }
1834 let (mut response_parts, response_body) = response.into_parts();
1835 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash()
1836 {
1837 let custom_headers_hash_iter = custom_headers_hash.iter();
1838 for (header_name, header_value) in custom_headers_hash_iter {
1839 if let Some(header_name) = header_name.as_str() {
1840 if let Some(header_value) = header_value.as_str() {
1841 if !response_parts.headers.contains_key(header_name) {
1842 if let Ok(header_value) = HeaderValue::from_str(
1843 &header_value.replace("{path}", &sanitized_url_pathname),
1844 ) {
1845 if let Ok(header_name) = HeaderName::from_str(header_name) {
1846 response_parts.headers.insert(header_name, header_value);
1847 }
1848 }
1849 }
1850 }
1851 }
1852 }
1853 }
1854 if let Some(http3_alt_port) = http3_alt_port {
1855 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC)
1856 {
1857 Some(value) => {
1858 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1859 let header_value_new =
1860 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1861
1862 if header_value_old != header_value_new {
1863 HeaderValue::from_bytes(
1864 format!("{header_value_old}, {header_value_new}").as_bytes(),
1865 )
1866 } else {
1867 HeaderValue::from_bytes(header_value_old.as_bytes())
1868 }
1869 }
1870 None => HeaderValue::from_bytes(
1871 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"")
1872 .as_bytes(),
1873 ),
1874 } {
1875 response_parts.headers.insert(header::ALT_SVC, header_value);
1876 }
1877 }
1878 response_parts
1879 .headers
1880 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1881
1882 return Ok(Response::from_parts(response_parts, response_body));
1883 }
1884 };
1885 }
1886
1887 if log_enabled {
1888 log_combined(
1889 &logger,
1890 socket_data.remote_addr.ip(),
1891 auth_data,
1892 log_method,
1893 log_request_path,
1894 log_protocol,
1895 response.status().as_u16(),
1896 match response.headers().get(header::CONTENT_LENGTH) {
1897 Some(header_value) => match header_value.to_str() {
1898 Ok(header_value) => match header_value.parse::<u64>() {
1899 Ok(content_length) => Some(content_length),
1900 Err(_) => response.body().size_hint().exact(),
1901 },
1902 Err(_) => response.body().size_hint().exact(),
1903 },
1904 None => response.body().size_hint().exact(),
1905 },
1906 log_referrer,
1907 log_user_agent,
1908 )
1909 .await;
1910 }
1911 return Ok(response);
1912 }
1913 None => match request_option {
1914 Some(request) => {
1915 request_data =
1916 RequestData::new(request, auth_data, original_url, error_status_code);
1917 continue;
1918 }
1919 None => {
1920 break;
1921 }
1922 },
1923 },
1924 }
1925 }
1926 Err(err) => {
1927 let response =
1928 generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, &combined_config, &None)
1929 .await;
1930
1931 let (mut response_parts, response_body) = response.into_parts();
1932 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1933 let custom_headers_hash_iter = custom_headers_hash.iter();
1934 for (header_name, header_value) in custom_headers_hash_iter {
1935 if let Some(header_name) = header_name.as_str() {
1936 if let Some(header_value) = header_value.as_str() {
1937 if !response_parts.headers.contains_key(header_name) {
1938 if let Ok(header_value) = HeaderValue::from_str(
1939 &header_value.replace("{path}", &sanitized_url_pathname),
1940 ) {
1941 if let Ok(header_name) = HeaderName::from_str(header_name) {
1942 response_parts.headers.insert(header_name, header_value);
1943 }
1944 }
1945 }
1946 }
1947 }
1948 }
1949 }
1950 if let Some(http3_alt_port) = http3_alt_port {
1951 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1952 Some(value) => {
1953 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1954 let header_value_new =
1955 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
1956
1957 if header_value_old != header_value_new {
1958 HeaderValue::from_bytes(
1959 format!("{header_value_old}, {header_value_new}").as_bytes(),
1960 )
1961 } else {
1962 HeaderValue::from_bytes(header_value_old.as_bytes())
1963 }
1964 }
1965 None => HeaderValue::from_bytes(
1966 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
1967 ),
1968 } {
1969 response_parts.headers.insert(header::ALT_SVC, header_value);
1970 }
1971 }
1972 response_parts
1973 .headers
1974 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1975
1976 let mut response = Response::from_parts(response_parts, response_body);
1977
1978 while let Some(mut executed_handler) = executed_handlers.pop() {
1979 let response_status = match is_proxy_request {
1980 true => {
1981 executed_handler
1982 .proxy_response_modifying_handler(response)
1983 .await
1984 }
1985 false => executed_handler.response_modifying_handler(response).await,
1986 };
1987 response = match response_status {
1988 Ok(response) => response,
1989 Err(err) => {
1990 if error_log_enabled {
1991 logger
1992 .send(LogMessage::new(
1993 format!("Unexpected error while serving a request: {err}"),
1994 true,
1995 ))
1996 .await
1997 .unwrap_or_default();
1998 }
1999
2000 let response = generate_error_response(
2001 StatusCode::INTERNAL_SERVER_ERROR,
2002 &combined_config,
2003 &None,
2004 )
2005 .await;
2006 if log_enabled {
2007 log_combined(
2008 &logger,
2009 socket_data.remote_addr.ip(),
2010 latest_auth_data,
2011 log_method,
2012 log_request_path,
2013 log_protocol,
2014 response.status().as_u16(),
2015 match response.headers().get(header::CONTENT_LENGTH) {
2016 Some(header_value) => match header_value.to_str() {
2017 Ok(header_value) => match header_value.parse::<u64>() {
2018 Ok(content_length) => Some(content_length),
2019 Err(_) => response.body().size_hint().exact(),
2020 },
2021 Err(_) => response.body().size_hint().exact(),
2022 },
2023 None => response.body().size_hint().exact(),
2024 },
2025 log_referrer,
2026 log_user_agent,
2027 )
2028 .await;
2029 }
2030 let (mut response_parts, response_body) = response.into_parts();
2031 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
2032 let custom_headers_hash_iter = custom_headers_hash.iter();
2033 for (header_name, header_value) in custom_headers_hash_iter {
2034 if let Some(header_name) = header_name.as_str() {
2035 if let Some(header_value) = header_value.as_str() {
2036 if !response_parts.headers.contains_key(header_name) {
2037 if let Ok(header_value) = HeaderValue::from_str(
2038 &header_value.replace("{path}", &sanitized_url_pathname),
2039 ) {
2040 if let Ok(header_name) = HeaderName::from_str(header_name) {
2041 response_parts.headers.insert(header_name, header_value);
2042 }
2043 }
2044 }
2045 }
2046 }
2047 }
2048 }
2049 if let Some(http3_alt_port) = http3_alt_port {
2050 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
2051 Some(value) => {
2052 let header_value_old = String::from_utf8_lossy(value.as_bytes());
2053 let header_value_new =
2054 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
2055
2056 if header_value_old != header_value_new {
2057 HeaderValue::from_bytes(
2058 format!("{header_value_old}, {header_value_new}").as_bytes(),
2059 )
2060 } else {
2061 HeaderValue::from_bytes(header_value_old.as_bytes())
2062 }
2063 }
2064 None => HeaderValue::from_bytes(
2065 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
2066 ),
2067 } {
2068 response_parts.headers.insert(header::ALT_SVC, header_value);
2069 }
2070 }
2071 response_parts
2072 .headers
2073 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
2074
2075 return Ok(Response::from_parts(response_parts, response_body));
2076 }
2077 };
2078 }
2079
2080 if error_log_enabled {
2081 logger
2082 .send(LogMessage::new(
2083 format!("Unexpected error while serving a request: {err}"),
2084 true,
2085 ))
2086 .await
2087 .unwrap_or_default();
2088 }
2089
2090 if log_enabled {
2091 log_combined(
2092 &logger,
2093 socket_data.remote_addr.ip(),
2094 latest_auth_data,
2095 log_method,
2096 log_request_path,
2097 log_protocol,
2098 response.status().as_u16(),
2099 match response.headers().get(header::CONTENT_LENGTH) {
2100 Some(header_value) => match header_value.to_str() {
2101 Ok(header_value) => match header_value.parse::<u64>() {
2102 Ok(content_length) => Some(content_length),
2103 Err(_) => response.body().size_hint().exact(),
2104 },
2105 Err(_) => response.body().size_hint().exact(),
2106 },
2107 None => response.body().size_hint().exact(),
2108 },
2109 log_referrer,
2110 log_user_agent,
2111 )
2112 .await;
2113 }
2114 return Ok(response);
2115 }
2116 }
2117 }
2118
2119 let response = generate_error_response(StatusCode::NOT_FOUND, &combined_config, &None).await;
2120
2121 let (mut response_parts, response_body) = response.into_parts();
2122 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
2123 let custom_headers_hash_iter = custom_headers_hash.iter();
2124 for (header_name, header_value) in custom_headers_hash_iter {
2125 if let Some(header_name) = header_name.as_str() {
2126 if let Some(header_value) = header_value.as_str() {
2127 if !response_parts.headers.contains_key(header_name) {
2128 if let Ok(header_value) =
2129 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
2130 {
2131 if let Ok(header_name) = HeaderName::from_str(header_name) {
2132 response_parts.headers.insert(header_name, header_value);
2133 }
2134 }
2135 }
2136 }
2137 }
2138 }
2139 }
2140 if let Some(http3_alt_port) = http3_alt_port {
2141 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
2142 Some(value) => {
2143 let header_value_old = String::from_utf8_lossy(value.as_bytes());
2144 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
2145
2146 if header_value_old != header_value_new {
2147 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
2148 } else {
2149 HeaderValue::from_bytes(header_value_old.as_bytes())
2150 }
2151 }
2152 None => HeaderValue::from_bytes(
2153 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
2154 ),
2155 } {
2156 response_parts.headers.insert(header::ALT_SVC, header_value);
2157 }
2158 }
2159 response_parts
2160 .headers
2161 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
2162
2163 let mut response = Response::from_parts(response_parts, response_body);
2164
2165 while let Some(mut executed_handler) = executed_handlers.pop() {
2166 let response_status = match is_proxy_request {
2167 true => {
2168 executed_handler
2169 .proxy_response_modifying_handler(response)
2170 .await
2171 }
2172 false => executed_handler.response_modifying_handler(response).await,
2173 };
2174 response = match response_status {
2175 Ok(response) => response,
2176 Err(err) => {
2177 if error_log_enabled {
2178 logger
2179 .send(LogMessage::new(
2180 format!("Unexpected error while serving a request: {err}"),
2181 true,
2182 ))
2183 .await
2184 .unwrap_or_default();
2185 }
2186
2187 let response =
2188 generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, &combined_config, &None)
2189 .await;
2190 if log_enabled {
2191 log_combined(
2192 &logger,
2193 socket_data.remote_addr.ip(),
2194 latest_auth_data,
2195 log_method,
2196 log_request_path,
2197 log_protocol,
2198 response.status().as_u16(),
2199 match response.headers().get(header::CONTENT_LENGTH) {
2200 Some(header_value) => match header_value.to_str() {
2201 Ok(header_value) => match header_value.parse::<u64>() {
2202 Ok(content_length) => Some(content_length),
2203 Err(_) => response.body().size_hint().exact(),
2204 },
2205 Err(_) => response.body().size_hint().exact(),
2206 },
2207 None => response.body().size_hint().exact(),
2208 },
2209 log_referrer,
2210 log_user_agent,
2211 )
2212 .await;
2213 }
2214 let (mut response_parts, response_body) = response.into_parts();
2215 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
2216 let custom_headers_hash_iter = custom_headers_hash.iter();
2217 for (header_name, header_value) in custom_headers_hash_iter {
2218 if let Some(header_name) = header_name.as_str() {
2219 if let Some(header_value) = header_value.as_str() {
2220 if !response_parts.headers.contains_key(header_name) {
2221 if let Ok(header_value) = HeaderValue::from_str(
2222 &header_value.replace("{path}", &sanitized_url_pathname),
2223 ) {
2224 if let Ok(header_name) = HeaderName::from_str(header_name) {
2225 response_parts.headers.insert(header_name, header_value);
2226 }
2227 }
2228 }
2229 }
2230 }
2231 }
2232 }
2233 if let Some(http3_alt_port) = http3_alt_port {
2234 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
2235 Some(value) => {
2236 let header_value_old = String::from_utf8_lossy(value.as_bytes());
2237 let header_value_new =
2238 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
2239
2240 if header_value_old != header_value_new {
2241 HeaderValue::from_bytes(
2242 format!("{header_value_old}, {header_value_new}").as_bytes(),
2243 )
2244 } else {
2245 HeaderValue::from_bytes(header_value_old.as_bytes())
2246 }
2247 }
2248 None => HeaderValue::from_bytes(
2249 format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes(),
2250 ),
2251 } {
2252 response_parts.headers.insert(header::ALT_SVC, header_value);
2253 }
2254 }
2255 response_parts
2256 .headers
2257 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
2258
2259 return Ok(Response::from_parts(response_parts, response_body));
2260 }
2261 };
2262 }
2263
2264 if log_enabled {
2265 log_combined(
2266 &logger,
2267 socket_data.remote_addr.ip(),
2268 latest_auth_data,
2269 log_method,
2270 log_request_path,
2271 log_protocol,
2272 response.status().as_u16(),
2273 match response.headers().get(header::CONTENT_LENGTH) {
2274 Some(header_value) => match header_value.to_str() {
2275 Ok(header_value) => match header_value.parse::<u64>() {
2276 Ok(content_length) => Some(content_length),
2277 Err(_) => response.body().size_hint().exact(),
2278 },
2279 Err(_) => response.body().size_hint().exact(),
2280 },
2281 None => response.body().size_hint().exact(),
2282 },
2283 log_referrer,
2284 log_user_agent,
2285 )
2286 .await;
2287 }
2288 Ok(response)
2289 }
2290}
2291
2292#[allow(clippy::too_many_arguments)]
2293pub async fn request_handler(
2294 request: Request<BoxBody<Bytes, std::io::Error>>,
2295 remote_address: SocketAddr,
2296 local_address: SocketAddr,
2297 encrypted: bool,
2298 config: Arc<Yaml>,
2299 logger: Sender<LogMessage>,
2300 handlers_vec: Vec<Box<dyn ServerModuleHandlers + Send>>,
2301 acme_http01_resolver_option: Option<Arc<ResolvesServerCertAcme>>,
2302 http3_alt_port: Option<u16>,
2303) -> Result<Response<BoxBody<Bytes, std::io::Error>>, anyhow::Error> {
2304 let timeout_yaml = &config["global"]["timeout"];
2305 if timeout_yaml.is_null() {
2306 request_handler_wrapped(
2307 request,
2308 remote_address,
2309 local_address,
2310 encrypted,
2311 config,
2312 logger,
2313 handlers_vec,
2314 acme_http01_resolver_option,
2315 http3_alt_port,
2316 )
2317 .await
2318 .map_err(|e| anyhow::anyhow!(e))
2319 } else {
2320 let timeout_millis = timeout_yaml.as_i64().unwrap_or(300000) as u64;
2321 match timeout(
2322 Duration::from_millis(timeout_millis),
2323 request_handler_wrapped(
2324 request,
2325 remote_address,
2326 local_address,
2327 encrypted,
2328 config,
2329 logger,
2330 handlers_vec,
2331 acme_http01_resolver_option,
2332 http3_alt_port,
2333 ),
2334 )
2335 .await
2336 {
2337 Ok(response) => response.map_err(|e| anyhow::anyhow!(e)),
2338 Err(_) => Err(anyhow::anyhow!("The client or server has timed out")),
2339 }
2340 }
2341}