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