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=\":{}\", h3-29=\":{}\"", http3_alt_port, 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=\":{}\", h3-29=\":{}\"", http3_alt_port, 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=\":{}\", h3-29=\":{}\"", http3_alt_port, 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=\":{}\", h3-29=\":{}\"", http3_alt_port, 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,
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 =
489 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
490
491 if header_value_old != header_value_new {
492 HeaderValue::from_bytes(
493 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
494 )
495 } else {
496 HeaderValue::from_bytes(header_value_old.as_bytes())
497 }
498 }
499 None => HeaderValue::from_bytes(
500 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
501 ),
502 } {
503 response_parts.headers.insert(header::ALT_SVC, header_value);
504 }
505 }
506 response_parts
507 .headers
508 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
509
510 return Ok(Response::from_parts(response_parts, response_body));
511 }
512 };
513
514 let url_pathname = request.uri().path();
515 let sanitized_url_pathname = match sanitize_url(
516 url_pathname,
517 combined_config["allowDoubleSlashes"]
518 .as_bool()
519 .unwrap_or_default(),
520 ) {
521 Ok(sanitized_url) => sanitized_url,
522 Err(err) => {
523 if error_log_enabled {
524 logger
525 .send(LogMessage::new(
526 format!("URL sanitation error: {}", err),
527 true,
528 ))
529 .await
530 .unwrap_or_default();
531 }
532 let response =
533 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
534 if log_enabled {
535 log_combined(
536 &logger,
537 socket_data.remote_addr.ip(),
538 None,
539 log_method,
540 log_request_path,
541 log_protocol,
542 response.status().as_u16(),
543 match response.headers().get(header::CONTENT_LENGTH) {
544 Some(header_value) => match header_value.to_str() {
545 Ok(header_value) => match header_value.parse::<u64>() {
546 Ok(content_length) => Some(content_length),
547 Err(_) => response.body().size_hint().exact(),
548 },
549 Err(_) => response.body().size_hint().exact(),
550 },
551 None => response.body().size_hint().exact(),
552 },
553 log_referrer,
554 log_user_agent,
555 )
556 .await;
557 }
558 let (mut response_parts, response_body) = response.into_parts();
559 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
560 let custom_headers_hash_iter = custom_headers_hash.iter();
561 for (header_name, header_value) in custom_headers_hash_iter {
562 if let Some(header_name) = header_name.as_str() {
563 if let Some(header_value) = header_value.as_str() {
564 if !response_parts.headers.contains_key(header_name) {
565 if let Ok(header_value) =
566 HeaderValue::from_str(&header_value.replace("{path}", url_pathname))
567 {
568 if let Ok(header_name) = HeaderName::from_str(header_name) {
569 response_parts.headers.insert(header_name, header_value);
570 }
571 }
572 }
573 }
574 }
575 }
576 }
577 if let Some(http3_alt_port) = http3_alt_port {
578 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
579 Some(value) => {
580 let header_value_old = String::from_utf8_lossy(value.as_bytes());
581 let header_value_new =
582 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
583
584 if header_value_old != header_value_new {
585 HeaderValue::from_bytes(
586 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
587 )
588 } else {
589 HeaderValue::from_bytes(header_value_old.as_bytes())
590 }
591 }
592 None => HeaderValue::from_bytes(
593 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
594 ),
595 } {
596 response_parts.headers.insert(header::ALT_SVC, header_value);
597 }
598 }
599 response_parts
600 .headers
601 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
602
603 return Ok(Response::from_parts(response_parts, response_body));
604 }
605 };
606
607 if sanitized_url_pathname != url_pathname {
608 let (mut parts, body) = request.into_parts();
609 let mut url_parts = parts.uri.into_parts();
610 url_parts.path_and_query = Some(
611 match format!(
612 "{}{}",
613 sanitized_url_pathname,
614 match url_parts.path_and_query {
615 Some(path_and_query) => {
616 match path_and_query.query() {
617 Some(query) => format!("?{}", query),
618 None => String::from(""),
619 }
620 }
621 None => String::from(""),
622 }
623 )
624 .parse()
625 {
626 Ok(path_and_query) => path_and_query,
627 Err(err) => {
628 if error_log_enabled {
629 logger
630 .send(LogMessage::new(
631 format!("URL sanitation error: {}", err),
632 true,
633 ))
634 .await
635 .unwrap_or_default();
636 }
637 let response =
638 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
639 if log_enabled {
640 log_combined(
641 &logger,
642 socket_data.remote_addr.ip(),
643 None,
644 log_method,
645 log_request_path,
646 log_protocol,
647 response.status().as_u16(),
648 match response.headers().get(header::CONTENT_LENGTH) {
649 Some(header_value) => match header_value.to_str() {
650 Ok(header_value) => match header_value.parse::<u64>() {
651 Ok(content_length) => Some(content_length),
652 Err(_) => response.body().size_hint().exact(),
653 },
654 Err(_) => response.body().size_hint().exact(),
655 },
656 None => response.body().size_hint().exact(),
657 },
658 log_referrer,
659 log_user_agent,
660 )
661 .await;
662 }
663 let (mut response_parts, response_body) = response.into_parts();
664 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
665 let custom_headers_hash_iter = custom_headers_hash.iter();
666 for (header_name, header_value) in custom_headers_hash_iter {
667 if let Some(header_name) = header_name.as_str() {
668 if let Some(header_value) = header_value.as_str() {
669 if !response_parts.headers.contains_key(header_name) {
670 if let Ok(header_value) = HeaderValue::from_str(
671 &header_value.replace("{path}", &sanitized_url_pathname),
672 ) {
673 if let Ok(header_name) = HeaderName::from_str(header_name) {
674 response_parts.headers.insert(header_name, header_value);
675 }
676 }
677 }
678 }
679 }
680 }
681 }
682 if let Some(http3_alt_port) = http3_alt_port {
683 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
684 Some(value) => {
685 let header_value_old = String::from_utf8_lossy(value.as_bytes());
686 let header_value_new =
687 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
688
689 if header_value_old != header_value_new {
690 HeaderValue::from_bytes(
691 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
692 )
693 } else {
694 HeaderValue::from_bytes(header_value_old.as_bytes())
695 }
696 }
697 None => HeaderValue::from_bytes(
698 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
699 ),
700 } {
701 response_parts.headers.insert(header::ALT_SVC, header_value);
702 }
703 }
704 response_parts
705 .headers
706 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
707
708 return Ok(Response::from_parts(response_parts, response_body));
709 }
710 },
711 );
712 parts.uri = match hyper::Uri::from_parts(url_parts) {
713 Ok(uri) => uri,
714 Err(err) => {
715 if error_log_enabled {
716 logger
717 .send(LogMessage::new(
718 format!("URL sanitation error: {}", err),
719 true,
720 ))
721 .await
722 .unwrap_or_default();
723 }
724 let response =
725 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
726 if log_enabled {
727 log_combined(
728 &logger,
729 socket_data.remote_addr.ip(),
730 None,
731 log_method,
732 log_request_path,
733 log_protocol,
734 response.status().as_u16(),
735 match response.headers().get(header::CONTENT_LENGTH) {
736 Some(header_value) => match header_value.to_str() {
737 Ok(header_value) => match header_value.parse::<u64>() {
738 Ok(content_length) => Some(content_length),
739 Err(_) => response.body().size_hint().exact(),
740 },
741 Err(_) => response.body().size_hint().exact(),
742 },
743 None => response.body().size_hint().exact(),
744 },
745 log_referrer,
746 log_user_agent,
747 )
748 .await;
749 }
750 let (mut response_parts, response_body) = response.into_parts();
751 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
752 let custom_headers_hash_iter = custom_headers_hash.iter();
753 for (header_name, header_value) in custom_headers_hash_iter {
754 if let Some(header_name) = header_name.as_str() {
755 if let Some(header_value) = header_value.as_str() {
756 if !response_parts.headers.contains_key(header_name) {
757 if let Ok(header_value) =
758 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
759 {
760 if let Ok(header_name) = HeaderName::from_str(header_name) {
761 response_parts.headers.insert(header_name, header_value);
762 }
763 }
764 }
765 }
766 }
767 }
768 }
769 if let Some(http3_alt_port) = http3_alt_port {
770 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
771 Some(value) => {
772 let header_value_old = String::from_utf8_lossy(value.as_bytes());
773 let header_value_new =
774 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
775
776 if header_value_old != header_value_new {
777 HeaderValue::from_bytes(
778 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
779 )
780 } else {
781 HeaderValue::from_bytes(header_value_old.as_bytes())
782 }
783 }
784 None => HeaderValue::from_bytes(
785 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
786 ),
787 } {
788 response_parts.headers.insert(header::ALT_SVC, header_value);
789 }
790 }
791 response_parts
792 .headers
793 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
794
795 return Ok(Response::from_parts(response_parts, response_body));
796 }
797 };
798 request = Request::from_parts(parts, body);
799 }
800
801 if request.uri().path() == "*" {
802 let response = match request.method() {
803 &Method::OPTIONS => Response::builder()
804 .status(StatusCode::NO_CONTENT)
805 .header(header::ALLOW, "GET, POST, HEAD, OPTIONS")
806 .body(Empty::new().map_err(|e| match e {}).boxed())
807 .unwrap_or_default(),
808 _ => {
809 let mut header_map = HeaderMap::new();
810 if let Ok(header_value) = HeaderValue::from_str("GET, POST, HEAD, OPTIONS") {
811 header_map.insert(header::ALLOW, header_value);
812 };
813 generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &Some(header_map)).await
814 }
815 };
816 if log_enabled {
817 log_combined(
818 &logger,
819 socket_data.remote_addr.ip(),
820 None,
821 log_method,
822 log_request_path,
823 log_protocol,
824 response.status().as_u16(),
825 match response.headers().get(header::CONTENT_LENGTH) {
826 Some(header_value) => match header_value.to_str() {
827 Ok(header_value) => match header_value.parse::<u64>() {
828 Ok(content_length) => Some(content_length),
829 Err(_) => response.body().size_hint().exact(),
830 },
831 Err(_) => response.body().size_hint().exact(),
832 },
833 None => response.body().size_hint().exact(),
834 },
835 log_referrer,
836 log_user_agent,
837 )
838 .await;
839 }
840 let (mut response_parts, response_body) = response.into_parts();
841 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
842 let custom_headers_hash_iter = custom_headers_hash.iter();
843 for (header_name, header_value) in custom_headers_hash_iter {
844 if let Some(header_name) = header_name.as_str() {
845 if let Some(header_value) = header_value.as_str() {
846 if !response_parts.headers.contains_key(header_name) {
847 if let Ok(header_value) =
848 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
849 {
850 if let Ok(header_name) = HeaderName::from_str(header_name) {
851 response_parts.headers.insert(header_name, header_value);
852 }
853 }
854 }
855 }
856 }
857 }
858 }
859 if let Some(http3_alt_port) = http3_alt_port {
860 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
861 Some(value) => {
862 let header_value_old = String::from_utf8_lossy(value.as_bytes());
863 let header_value_new =
864 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
865
866 if header_value_old != header_value_new {
867 HeaderValue::from_bytes(
868 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
869 )
870 } else {
871 HeaderValue::from_bytes(header_value_old.as_bytes())
872 }
873 }
874 None => HeaderValue::from_bytes(
875 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
876 ),
877 } {
878 response_parts.headers.insert(header::ALT_SVC, header_value);
879 }
880 }
881 response_parts
882 .headers
883 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
884
885 return Ok(Response::from_parts(response_parts, response_body));
886 }
887
888 if let Some(acme_http01_resolver) = acme_http01_resolver_option {
890 if let Some(challenge_token) = request
891 .uri()
892 .path()
893 .strip_prefix("/.well-known/acme-challenge/")
894 {
895 if let Some(acme_response) = acme_http01_resolver.get_http_01_key_auth(challenge_token) {
896 let response = Response::builder()
897 .status(StatusCode::OK)
898 .header(
899 CONTENT_TYPE,
900 HeaderValue::from_static("application/octet-stream"),
901 )
902 .body(
903 Full::new(Bytes::from(acme_response))
904 .map_err(|e| match e {})
905 .boxed(),
906 )
907 .unwrap_or_default();
908
909 let (mut response_parts, response_body) = response.into_parts();
910 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
911 let custom_headers_hash_iter = custom_headers_hash.iter();
912 for (header_name, header_value) in custom_headers_hash_iter {
913 if let Some(header_name) = header_name.as_str() {
914 if let Some(header_value) = header_value.as_str() {
915 if !response_parts.headers.contains_key(header_name) {
916 if let Ok(header_value) =
917 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
918 {
919 if let Ok(header_name) = HeaderName::from_str(header_name) {
920 response_parts.headers.insert(header_name, header_value);
921 }
922 }
923 }
924 }
925 }
926 }
927 }
928 if let Some(http3_alt_port) = http3_alt_port {
929 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
930 Some(value) => {
931 let header_value_old = String::from_utf8_lossy(value.as_bytes());
932 let header_value_new =
933 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
934
935 if header_value_old != header_value_new {
936 HeaderValue::from_bytes(
937 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
938 )
939 } else {
940 HeaderValue::from_bytes(header_value_old.as_bytes())
941 }
942 }
943 None => HeaderValue::from_bytes(
944 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
945 ),
946 } {
947 response_parts.headers.insert(header::ALT_SVC, header_value);
948 }
949 }
950 response_parts
951 .headers
952 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
953
954 let response = Response::from_parts(response_parts, response_body);
955
956 if log_enabled {
957 log_combined(
958 &logger,
959 socket_data.remote_addr.ip(),
960 None,
961 log_method,
962 log_request_path,
963 log_protocol,
964 response.status().as_u16(),
965 match response.headers().get(header::CONTENT_LENGTH) {
966 Some(header_value) => match header_value.to_str() {
967 Ok(header_value) => match header_value.parse::<u64>() {
968 Ok(content_length) => Some(content_length),
969 Err(_) => response.body().size_hint().exact(),
970 },
971 Err(_) => response.body().size_hint().exact(),
972 },
973 None => response.body().size_hint().exact(),
974 },
975 log_referrer,
976 log_user_agent,
977 )
978 .await;
979 }
980 return Ok(response);
981 }
982 }
983 };
984
985 let cloned_logger = logger.clone();
986 let error_logger = match error_log_enabled {
987 true => ErrorLogger::new(cloned_logger),
988 false => ErrorLogger::without_logger(),
989 };
990
991 if is_connect_proxy_request {
992 let mut connect_proxy_handlers = None;
993 for mut handlers in handlers_vec {
994 if handlers.does_connect_proxy_requests() {
995 connect_proxy_handlers = Some(handlers);
996 break;
997 }
998 }
999
1000 if let Some(mut connect_proxy_handlers) = connect_proxy_handlers {
1001 if let Some(connect_address) = request.uri().authority().map(|auth| auth.to_string()) {
1002 let client_ip = socket_data.remote_addr.ip();
1004 let custom_headers_yaml = combined_config["customHeaders"].clone();
1005
1006 tokio::spawn(async move {
1007 match hyper::upgrade::on(request).await {
1008 Ok(upgraded_request) => {
1009 let result = connect_proxy_handlers
1010 .connect_proxy_request_handler(
1011 upgraded_request,
1012 &connect_address,
1013 &combined_config,
1014 &socket_data,
1015 &error_logger,
1016 )
1017 .await;
1018 match result {
1019 Ok(_) => (),
1020 Err(err) => {
1021 error_logger
1022 .log(&format!("Unexpected error for CONNECT request: {}", err))
1023 .await;
1024 }
1025 }
1026 }
1027 Err(err) => {
1028 error_logger
1029 .log(&format!(
1030 "Error while upgrading HTTP CONNECT request: {}",
1031 err
1032 ))
1033 .await
1034 }
1035 }
1036 });
1037
1038 let response = Response::builder()
1039 .body(Empty::new().map_err(|e| match e {}).boxed())
1040 .unwrap_or_default();
1041
1042 if log_enabled {
1043 log_combined(
1044 &logger,
1045 client_ip,
1046 None,
1047 log_method,
1048 log_request_path,
1049 log_protocol,
1050 response.status().as_u16(),
1051 match response.headers().get(header::CONTENT_LENGTH) {
1052 Some(header_value) => match header_value.to_str() {
1053 Ok(header_value) => match header_value.parse::<u64>() {
1054 Ok(content_length) => Some(content_length),
1055 Err(_) => response.body().size_hint().exact(),
1056 },
1057 Err(_) => response.body().size_hint().exact(),
1058 },
1059 None => response.body().size_hint().exact(),
1060 },
1061 log_referrer,
1062 log_user_agent,
1063 )
1064 .await;
1065 }
1066
1067 let (mut response_parts, response_body) = response.into_parts();
1068 if let Some(custom_headers_hash) = custom_headers_yaml.as_hash() {
1069 let custom_headers_hash_iter = custom_headers_hash.iter();
1070 for (header_name, header_value) in custom_headers_hash_iter {
1071 if let Some(header_name) = header_name.as_str() {
1072 if let Some(header_value) = header_value.as_str() {
1073 if !response_parts.headers.contains_key(header_name) {
1074 if let Ok(header_value) =
1075 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1076 {
1077 if let Ok(header_name) = HeaderName::from_str(header_name) {
1078 response_parts.headers.insert(header_name, header_value);
1079 }
1080 }
1081 }
1082 }
1083 }
1084 }
1085 }
1086 if let Some(http3_alt_port) = http3_alt_port {
1087 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1088 Some(value) => {
1089 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1090 let header_value_new =
1091 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1092
1093 if header_value_old != header_value_new {
1094 HeaderValue::from_bytes(
1095 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1096 )
1097 } else {
1098 HeaderValue::from_bytes(header_value_old.as_bytes())
1099 }
1100 }
1101 None => HeaderValue::from_bytes(
1102 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1103 ),
1104 } {
1105 response_parts.headers.insert(header::ALT_SVC, header_value);
1106 }
1107 }
1108 response_parts
1109 .headers
1110 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1111
1112 Ok(Response::from_parts(response_parts, response_body))
1113 } else {
1114 let response = Response::builder()
1115 .status(StatusCode::BAD_REQUEST)
1116 .body(Empty::new().map_err(|e| match e {}).boxed())
1117 .unwrap_or_default();
1118
1119 if log_enabled {
1120 log_combined(
1121 &logger,
1122 socket_data.remote_addr.ip(),
1123 None,
1124 log_method,
1125 log_request_path,
1126 log_protocol,
1127 response.status().as_u16(),
1128 match response.headers().get(header::CONTENT_LENGTH) {
1129 Some(header_value) => match header_value.to_str() {
1130 Ok(header_value) => match header_value.parse::<u64>() {
1131 Ok(content_length) => Some(content_length),
1132 Err(_) => response.body().size_hint().exact(),
1133 },
1134 Err(_) => response.body().size_hint().exact(),
1135 },
1136 None => response.body().size_hint().exact(),
1137 },
1138 log_referrer,
1139 log_user_agent,
1140 )
1141 .await;
1142 }
1143 let (mut response_parts, response_body) = response.into_parts();
1144 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1145 let custom_headers_hash_iter = custom_headers_hash.iter();
1146 for (header_name, header_value) in custom_headers_hash_iter {
1147 if let Some(header_name) = header_name.as_str() {
1148 if let Some(header_value) = header_value.as_str() {
1149 if !response_parts.headers.contains_key(header_name) {
1150 if let Ok(header_value) =
1151 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1152 {
1153 if let Ok(header_name) = HeaderName::from_str(header_name) {
1154 response_parts.headers.insert(header_name, header_value);
1155 }
1156 }
1157 }
1158 }
1159 }
1160 }
1161 }
1162 if let Some(http3_alt_port) = http3_alt_port {
1163 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1164 Some(value) => {
1165 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1166 let header_value_new =
1167 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1168
1169 if header_value_old != header_value_new {
1170 HeaderValue::from_bytes(
1171 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1172 )
1173 } else {
1174 HeaderValue::from_bytes(header_value_old.as_bytes())
1175 }
1176 }
1177 None => HeaderValue::from_bytes(
1178 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1179 ),
1180 } {
1181 response_parts.headers.insert(header::ALT_SVC, header_value);
1182 }
1183 }
1184 response_parts
1185 .headers
1186 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1187
1188 Ok(Response::from_parts(response_parts, response_body))
1189 }
1190 } else {
1191 let response = Response::builder()
1192 .status(StatusCode::NOT_IMPLEMENTED)
1193 .body(Empty::new().map_err(|e| match e {}).boxed())
1194 .unwrap_or_default();
1195
1196 if log_enabled {
1197 log_combined(
1198 &logger,
1199 socket_data.remote_addr.ip(),
1200 None,
1201 log_method,
1202 log_request_path,
1203 log_protocol,
1204 response.status().as_u16(),
1205 match response.headers().get(header::CONTENT_LENGTH) {
1206 Some(header_value) => match header_value.to_str() {
1207 Ok(header_value) => match header_value.parse::<u64>() {
1208 Ok(content_length) => Some(content_length),
1209 Err(_) => response.body().size_hint().exact(),
1210 },
1211 Err(_) => response.body().size_hint().exact(),
1212 },
1213 None => response.body().size_hint().exact(),
1214 },
1215 log_referrer,
1216 log_user_agent,
1217 )
1218 .await;
1219 }
1220 let (mut response_parts, response_body) = response.into_parts();
1221 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1222 let custom_headers_hash_iter = custom_headers_hash.iter();
1223 for (header_name, header_value) in custom_headers_hash_iter {
1224 if let Some(header_name) = header_name.as_str() {
1225 if let Some(header_value) = header_value.as_str() {
1226 if !response_parts.headers.contains_key(header_name) {
1227 if let Ok(header_value) =
1228 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1229 {
1230 if let Ok(header_name) = HeaderName::from_str(header_name) {
1231 response_parts.headers.insert(header_name, header_value);
1232 }
1233 }
1234 }
1235 }
1236 }
1237 }
1238 }
1239 if let Some(http3_alt_port) = http3_alt_port {
1240 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1241 Some(value) => {
1242 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1243 let header_value_new =
1244 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1245
1246 if header_value_old != header_value_new {
1247 HeaderValue::from_bytes(
1248 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1249 )
1250 } else {
1251 HeaderValue::from_bytes(header_value_old.as_bytes())
1252 }
1253 }
1254 None => HeaderValue::from_bytes(
1255 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1256 ),
1257 } {
1258 response_parts.headers.insert(header::ALT_SVC, header_value);
1259 }
1260 }
1261 response_parts
1262 .headers
1263 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1264
1265 Ok(Response::from_parts(response_parts, response_body))
1266 }
1267 } else {
1268 let is_websocket_request = is_upgrade_request(&request);
1269 let (request_parts, request_body) = request.into_parts();
1270 let request_parts_cloned = if combined_config["errorConfig"].is_array() {
1271 let mut request_parts_cloned = request_parts.clone();
1272 request_parts_cloned
1273 .headers
1274 .insert(header::CONTENT_LENGTH, HeaderValue::from_static("0"));
1275 Some(request_parts_cloned)
1276 } else {
1277 None
1279 };
1280 let request = Request::from_parts(request_parts, request_body);
1281 let mut request_data = RequestData::new(request, None, None, None);
1282 let mut latest_auth_data = None;
1283 let mut error_status_code = None;
1284 let mut executed_handlers = Vec::new();
1285 let mut handlers_iter: Box<
1286 dyn Iterator<Item = Box<dyn ServerModuleHandlers + Send + 'static>> + Send,
1287 > = Box::new(handlers_vec.into_iter());
1288 while let Some(mut handlers) = handlers_iter.next() {
1289 if is_websocket_request && handlers.does_websocket_requests(&combined_config, &socket_data) {
1290 let (request, _, _, _) = request_data.into_parts();
1291
1292 let client_ip = socket_data.remote_addr.ip();
1294 let custom_headers_yaml = combined_config["customHeaders"].clone();
1295 let request_uri = request.uri().to_owned();
1296 let request_headers = request.headers().to_owned();
1297
1298 let (original_response, websocket) = match hyper_tungstenite::upgrade(request, None) {
1299 Ok(data) => data,
1300 Err(err) => {
1301 error_logger
1302 .log(&format!("Error while upgrading WebSocket request: {}", err))
1303 .await;
1304
1305 let response = Response::builder()
1306 .status(StatusCode::INTERNAL_SERVER_ERROR)
1307 .body(
1308 Full::new(Bytes::from(generate_default_error_page(
1309 StatusCode::INTERNAL_SERVER_ERROR,
1310 None,
1311 )))
1312 .map_err(|e| match e {})
1313 .boxed(),
1314 )
1315 .unwrap_or_default();
1316
1317 if log_enabled {
1318 log_combined(
1319 &logger,
1320 socket_data.remote_addr.ip(),
1321 None,
1322 log_method,
1323 log_request_path,
1324 log_protocol,
1325 response.status().as_u16(),
1326 match response.headers().get(header::CONTENT_LENGTH) {
1327 Some(header_value) => match header_value.to_str() {
1328 Ok(header_value) => match header_value.parse::<u64>() {
1329 Ok(content_length) => Some(content_length),
1330 Err(_) => response.body().size_hint().exact(),
1331 },
1332 Err(_) => response.body().size_hint().exact(),
1333 },
1334 None => response.body().size_hint().exact(),
1335 },
1336 log_referrer,
1337 log_user_agent,
1338 )
1339 .await;
1340 }
1341 let (mut response_parts, response_body) = response.into_parts();
1342 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1343 let custom_headers_hash_iter = custom_headers_hash.iter();
1344 for (header_name, header_value) in custom_headers_hash_iter {
1345 if let Some(header_name) = header_name.as_str() {
1346 if let Some(header_value) = header_value.as_str() {
1347 if !response_parts.headers.contains_key(header_name) {
1348 if let Ok(header_value) = HeaderValue::from_str(
1349 &header_value.replace("{path}", &sanitized_url_pathname),
1350 ) {
1351 if let Ok(header_name) = HeaderName::from_str(header_name) {
1352 response_parts.headers.insert(header_name, header_value);
1353 }
1354 }
1355 }
1356 }
1357 }
1358 }
1359 }
1360 if let Some(http3_alt_port) = http3_alt_port {
1361 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1362 Some(value) => {
1363 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1364 let header_value_new =
1365 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1366
1367 if header_value_old != header_value_new {
1368 HeaderValue::from_bytes(
1369 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1370 )
1371 } else {
1372 HeaderValue::from_bytes(header_value_old.as_bytes())
1373 }
1374 }
1375 None => HeaderValue::from_bytes(
1376 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1377 ),
1378 } {
1379 response_parts.headers.insert(header::ALT_SVC, header_value);
1380 }
1381 }
1382 response_parts
1383 .headers
1384 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1385
1386 return Ok(Response::from_parts(response_parts, response_body));
1387 }
1388 };
1389
1390 tokio::spawn(async move {
1391 let result = handlers
1392 .websocket_request_handler(
1393 websocket,
1394 &request_uri,
1395 &request_headers,
1396 &combined_config,
1397 &socket_data,
1398 &error_logger,
1399 )
1400 .await;
1401 match result {
1402 Ok(_) => (),
1403 Err(err) => {
1404 error_logger
1405 .log(&format!("Unexpected error for WebSocket request: {}", err))
1406 .await;
1407 }
1408 }
1409 });
1410
1411 let response = original_response.map(|body| body.map_err(|err| match err {}).boxed());
1412
1413 if log_enabled {
1414 log_combined(
1415 &logger,
1416 client_ip,
1417 None,
1418 log_method,
1419 log_request_path,
1420 log_protocol,
1421 response.status().as_u16(),
1422 match response.headers().get(header::CONTENT_LENGTH) {
1423 Some(header_value) => match header_value.to_str() {
1424 Ok(header_value) => match header_value.parse::<u64>() {
1425 Ok(content_length) => Some(content_length),
1426 Err(_) => response.body().size_hint().exact(),
1427 },
1428 Err(_) => response.body().size_hint().exact(),
1429 },
1430 None => response.body().size_hint().exact(),
1431 },
1432 log_referrer,
1433 log_user_agent,
1434 )
1435 .await;
1436 }
1437
1438 let (mut response_parts, response_body) = response.into_parts();
1439 if let Some(custom_headers_hash) = custom_headers_yaml.as_hash() {
1440 let custom_headers_hash_iter = custom_headers_hash.iter();
1441 for (header_name, header_value) in custom_headers_hash_iter {
1442 if let Some(header_name) = header_name.as_str() {
1443 if let Some(header_value) = header_value.as_str() {
1444 if !response_parts.headers.contains_key(header_name) {
1445 if let Ok(header_value) =
1446 HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1447 {
1448 if let Ok(header_name) = HeaderName::from_str(header_name) {
1449 response_parts.headers.insert(header_name, header_value);
1450 }
1451 }
1452 }
1453 }
1454 }
1455 }
1456 }
1457 if let Some(http3_alt_port) = http3_alt_port {
1458 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1459 Some(value) => {
1460 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1461 let header_value_new =
1462 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1463
1464 if header_value_old != header_value_new {
1465 HeaderValue::from_bytes(
1466 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1467 )
1468 } else {
1469 HeaderValue::from_bytes(header_value_old.as_bytes())
1470 }
1471 }
1472 None => HeaderValue::from_bytes(
1473 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1474 ),
1475 } {
1476 response_parts.headers.insert(header::ALT_SVC, header_value);
1477 }
1478 }
1479 response_parts
1480 .headers
1481 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1482
1483 return Ok(Response::from_parts(response_parts, response_body));
1484 }
1485
1486 let response_result = match is_proxy_request {
1487 true => {
1488 handlers
1489 .proxy_request_handler(request_data, &combined_config, &socket_data, &error_logger)
1490 .await
1491 }
1492 false => {
1493 handlers
1494 .request_handler(request_data, &combined_config, &socket_data, &error_logger)
1495 .await
1496 }
1497 };
1498
1499 executed_handlers.push(handlers);
1500 match response_result {
1501 Ok(response) => {
1502 let (
1503 request_option,
1504 auth_data,
1505 original_url,
1506 response,
1507 status,
1508 headers,
1509 new_remote_address,
1510 parallel_fn,
1511 ) = response.into_parts();
1512 latest_auth_data = auth_data.clone();
1513 if let Some(new_remote_address) = new_remote_address {
1514 socket_data.remote_addr = new_remote_address;
1515 };
1516 if let Some(parallel_fn) = parallel_fn {
1517 tokio::spawn(parallel_fn);
1522 }
1523 match response {
1524 Some(response) => {
1525 let (mut response_parts, response_body) = response.into_parts();
1526 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1527 let custom_headers_hash_iter = custom_headers_hash.iter();
1528 for (header_name, header_value) in custom_headers_hash_iter {
1529 if let Some(header_name) = header_name.as_str() {
1530 if let Some(header_value) = header_value.as_str() {
1531 if !response_parts.headers.contains_key(header_name) {
1532 if let Ok(header_value) = HeaderValue::from_str(
1533 &header_value.replace("{path}", &sanitized_url_pathname),
1534 ) {
1535 if let Ok(header_name) = HeaderName::from_str(header_name) {
1536 response_parts.headers.insert(header_name, header_value);
1537 }
1538 }
1539 }
1540 }
1541 }
1542 }
1543 }
1544 if let Some(http3_alt_port) = http3_alt_port {
1545 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1546 Some(value) => {
1547 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1548 let header_value_new =
1549 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1550
1551 if header_value_old != header_value_new {
1552 HeaderValue::from_bytes(
1553 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1554 )
1555 } else {
1556 HeaderValue::from_bytes(header_value_old.as_bytes())
1557 }
1558 }
1559 None => HeaderValue::from_bytes(
1560 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1561 ),
1562 } {
1563 response_parts.headers.insert(header::ALT_SVC, header_value);
1564 }
1565 }
1566 response_parts
1567 .headers
1568 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1569
1570 let mut response = Response::from_parts(response_parts, response_body);
1571
1572 while let Some(mut executed_handler) = executed_handlers.pop() {
1573 let response_status = match is_proxy_request {
1574 true => {
1575 executed_handler
1576 .proxy_response_modifying_handler(response)
1577 .await
1578 }
1579 false => executed_handler.response_modifying_handler(response).await,
1580 };
1581 response = match response_status {
1582 Ok(response) => response,
1583 Err(err) => {
1584 if error_log_enabled {
1585 logger
1586 .send(LogMessage::new(
1587 format!("Unexpected error while serving a request: {}", err),
1588 true,
1589 ))
1590 .await
1591 .unwrap_or_default();
1592 }
1593
1594 let response = generate_error_response(
1595 StatusCode::INTERNAL_SERVER_ERROR,
1596 &combined_config,
1597 &headers,
1598 )
1599 .await;
1600 if log_enabled {
1601 log_combined(
1602 &logger,
1603 socket_data.remote_addr.ip(),
1604 auth_data,
1605 log_method,
1606 log_request_path,
1607 log_protocol,
1608 response.status().as_u16(),
1609 match response.headers().get(header::CONTENT_LENGTH) {
1610 Some(header_value) => match header_value.to_str() {
1611 Ok(header_value) => match header_value.parse::<u64>() {
1612 Ok(content_length) => Some(content_length),
1613 Err(_) => response.body().size_hint().exact(),
1614 },
1615 Err(_) => response.body().size_hint().exact(),
1616 },
1617 None => response.body().size_hint().exact(),
1618 },
1619 log_referrer,
1620 log_user_agent,
1621 )
1622 .await;
1623 }
1624 let (mut response_parts, response_body) = response.into_parts();
1625 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1626 let custom_headers_hash_iter = custom_headers_hash.iter();
1627 for (header_name, header_value) in custom_headers_hash_iter {
1628 if let Some(header_name) = header_name.as_str() {
1629 if let Some(header_value) = header_value.as_str() {
1630 if !response_parts.headers.contains_key(header_name) {
1631 if let Ok(header_value) = HeaderValue::from_str(
1632 &header_value.replace("{path}", &sanitized_url_pathname),
1633 ) {
1634 if let Ok(header_name) = HeaderName::from_str(header_name) {
1635 response_parts.headers.insert(header_name, header_value);
1636 }
1637 }
1638 }
1639 }
1640 }
1641 }
1642 }
1643 if let Some(http3_alt_port) = http3_alt_port {
1644 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1645 Some(value) => {
1646 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1647 let header_value_new =
1648 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1649
1650 if header_value_old != header_value_new {
1651 HeaderValue::from_bytes(
1652 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1653 )
1654 } else {
1655 HeaderValue::from_bytes(header_value_old.as_bytes())
1656 }
1657 }
1658 None => HeaderValue::from_bytes(
1659 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
1660 .as_bytes(),
1661 ),
1662 } {
1663 response_parts.headers.insert(header::ALT_SVC, header_value);
1664 }
1665 }
1666 response_parts
1667 .headers
1668 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1669
1670 return Ok(Response::from_parts(response_parts, response_body));
1671 }
1672 };
1673 }
1674
1675 if log_enabled {
1676 log_combined(
1677 &logger,
1678 socket_data.remote_addr.ip(),
1679 auth_data,
1680 log_method,
1681 log_request_path,
1682 log_protocol,
1683 response.status().as_u16(),
1684 match response.headers().get(header::CONTENT_LENGTH) {
1685 Some(header_value) => match header_value.to_str() {
1686 Ok(header_value) => match header_value.parse::<u64>() {
1687 Ok(content_length) => Some(content_length),
1688 Err(_) => response.body().size_hint().exact(),
1689 },
1690 Err(_) => response.body().size_hint().exact(),
1691 },
1692 None => response.body().size_hint().exact(),
1693 },
1694 log_referrer,
1695 log_user_agent,
1696 )
1697 .await;
1698 }
1699
1700 return Ok(response);
1701 }
1702 None => match status {
1703 Some(status) => {
1704 let request = if let Some(request) = request_option {
1705 Some(request)
1706 } else {
1707 request_parts_cloned.clone().map(|request_parts_cloned| {
1708 Request::from_parts(
1709 request_parts_cloned,
1710 Empty::new().map_err(|e| match e {}).boxed(),
1711 )
1712 })
1713 };
1714 if let Some(request) = request {
1715 if let Some(combined_error_config) =
1716 combine_error_config(&combined_config, status.as_u16())
1717 {
1718 combined_config = combined_error_config;
1719 error_status_code = Some(status);
1720 handlers_iter = Box::new(executed_handlers.into_iter().chain(handlers_iter));
1721 executed_handlers = Vec::new();
1722 request_data =
1723 RequestData::new(request, auth_data, original_url, error_status_code);
1724 continue;
1725 }
1726 }
1727 let response = generate_error_response(status, &combined_config, &headers).await;
1728 let (mut response_parts, response_body) = response.into_parts();
1729 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1730 let custom_headers_hash_iter = custom_headers_hash.iter();
1731 for (header_name, header_value) in custom_headers_hash_iter {
1732 if let Some(header_name) = header_name.as_str() {
1733 if let Some(header_value) = header_value.as_str() {
1734 if !response_parts.headers.contains_key(header_name) {
1735 if let Ok(header_value) = HeaderValue::from_str(
1736 &header_value.replace("{path}", &sanitized_url_pathname),
1737 ) {
1738 if let Ok(header_name) = HeaderName::from_str(header_name) {
1739 response_parts.headers.insert(header_name, header_value);
1740 }
1741 }
1742 }
1743 }
1744 }
1745 }
1746 }
1747 if let Some(http3_alt_port) = http3_alt_port {
1748 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1749 Some(value) => {
1750 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1751 let header_value_new =
1752 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1753
1754 if header_value_old != header_value_new {
1755 HeaderValue::from_bytes(
1756 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1757 )
1758 } else {
1759 HeaderValue::from_bytes(header_value_old.as_bytes())
1760 }
1761 }
1762 None => HeaderValue::from_bytes(
1763 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
1764 .as_bytes(),
1765 ),
1766 } {
1767 response_parts.headers.insert(header::ALT_SVC, header_value);
1768 }
1769 }
1770 response_parts
1771 .headers
1772 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1773
1774 let mut response = Response::from_parts(response_parts, response_body);
1775
1776 while let Some(mut executed_handler) = executed_handlers.pop() {
1777 let response_status = match is_proxy_request {
1778 true => {
1779 executed_handler
1780 .proxy_response_modifying_handler(response)
1781 .await
1782 }
1783 false => executed_handler.response_modifying_handler(response).await,
1784 };
1785 response = match response_status {
1786 Ok(response) => response,
1787 Err(err) => {
1788 if error_log_enabled {
1789 logger
1790 .send(LogMessage::new(
1791 format!("Unexpected error while serving a request: {}", err),
1792 true,
1793 ))
1794 .await
1795 .unwrap_or_default();
1796 }
1797
1798 let response = generate_error_response(
1799 StatusCode::INTERNAL_SERVER_ERROR,
1800 &combined_config,
1801 &headers,
1802 )
1803 .await;
1804 if log_enabled {
1805 log_combined(
1806 &logger,
1807 socket_data.remote_addr.ip(),
1808 auth_data,
1809 log_method,
1810 log_request_path,
1811 log_protocol,
1812 response.status().as_u16(),
1813 match response.headers().get(header::CONTENT_LENGTH) {
1814 Some(header_value) => match header_value.to_str() {
1815 Ok(header_value) => match header_value.parse::<u64>() {
1816 Ok(content_length) => Some(content_length),
1817 Err(_) => response.body().size_hint().exact(),
1818 },
1819 Err(_) => response.body().size_hint().exact(),
1820 },
1821 None => response.body().size_hint().exact(),
1822 },
1823 log_referrer,
1824 log_user_agent,
1825 )
1826 .await;
1827 }
1828 let (mut response_parts, response_body) = response.into_parts();
1829 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash()
1830 {
1831 let custom_headers_hash_iter = custom_headers_hash.iter();
1832 for (header_name, header_value) in custom_headers_hash_iter {
1833 if let Some(header_name) = header_name.as_str() {
1834 if let Some(header_value) = header_value.as_str() {
1835 if !response_parts.headers.contains_key(header_name) {
1836 if let Ok(header_value) = HeaderValue::from_str(
1837 &header_value.replace("{path}", &sanitized_url_pathname),
1838 ) {
1839 if let Ok(header_name) = HeaderName::from_str(header_name) {
1840 response_parts.headers.insert(header_name, header_value);
1841 }
1842 }
1843 }
1844 }
1845 }
1846 }
1847 }
1848 if let Some(http3_alt_port) = http3_alt_port {
1849 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC)
1850 {
1851 Some(value) => {
1852 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1853 let header_value_new =
1854 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1855
1856 if header_value_old != header_value_new {
1857 HeaderValue::from_bytes(
1858 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1859 )
1860 } else {
1861 HeaderValue::from_bytes(header_value_old.as_bytes())
1862 }
1863 }
1864 None => HeaderValue::from_bytes(
1865 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
1866 .as_bytes(),
1867 ),
1868 } {
1869 response_parts.headers.insert(header::ALT_SVC, header_value);
1870 }
1871 }
1872 response_parts
1873 .headers
1874 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1875
1876 return Ok(Response::from_parts(response_parts, response_body));
1877 }
1878 };
1879 }
1880
1881 if log_enabled {
1882 log_combined(
1883 &logger,
1884 socket_data.remote_addr.ip(),
1885 auth_data,
1886 log_method,
1887 log_request_path,
1888 log_protocol,
1889 response.status().as_u16(),
1890 match response.headers().get(header::CONTENT_LENGTH) {
1891 Some(header_value) => match header_value.to_str() {
1892 Ok(header_value) => match header_value.parse::<u64>() {
1893 Ok(content_length) => Some(content_length),
1894 Err(_) => response.body().size_hint().exact(),
1895 },
1896 Err(_) => response.body().size_hint().exact(),
1897 },
1898 None => response.body().size_hint().exact(),
1899 },
1900 log_referrer,
1901 log_user_agent,
1902 )
1903 .await;
1904 }
1905 return Ok(response);
1906 }
1907 None => match request_option {
1908 Some(request) => {
1909 request_data =
1910 RequestData::new(request, auth_data, original_url, error_status_code);
1911 continue;
1912 }
1913 None => {
1914 break;
1915 }
1916 },
1917 },
1918 }
1919 }
1920 Err(err) => {
1921 let response =
1922 generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, &combined_config, &None)
1923 .await;
1924
1925 let (mut response_parts, response_body) = response.into_parts();
1926 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1927 let custom_headers_hash_iter = custom_headers_hash.iter();
1928 for (header_name, header_value) in custom_headers_hash_iter {
1929 if let Some(header_name) = header_name.as_str() {
1930 if let Some(header_value) = header_value.as_str() {
1931 if !response_parts.headers.contains_key(header_name) {
1932 if let Ok(header_value) = HeaderValue::from_str(
1933 &header_value.replace("{path}", &sanitized_url_pathname),
1934 ) {
1935 if let Ok(header_name) = HeaderName::from_str(header_name) {
1936 response_parts.headers.insert(header_name, header_value);
1937 }
1938 }
1939 }
1940 }
1941 }
1942 }
1943 }
1944 if let Some(http3_alt_port) = http3_alt_port {
1945 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1946 Some(value) => {
1947 let header_value_old = String::from_utf8_lossy(value.as_bytes());
1948 let header_value_new =
1949 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
1950
1951 if header_value_old != header_value_new {
1952 HeaderValue::from_bytes(
1953 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
1954 )
1955 } else {
1956 HeaderValue::from_bytes(header_value_old.as_bytes())
1957 }
1958 }
1959 None => HeaderValue::from_bytes(
1960 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1961 ),
1962 } {
1963 response_parts.headers.insert(header::ALT_SVC, header_value);
1964 }
1965 }
1966 response_parts
1967 .headers
1968 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1969
1970 let mut response = Response::from_parts(response_parts, response_body);
1971
1972 while let Some(mut executed_handler) = executed_handlers.pop() {
1973 let response_status = match is_proxy_request {
1974 true => {
1975 executed_handler
1976 .proxy_response_modifying_handler(response)
1977 .await
1978 }
1979 false => executed_handler.response_modifying_handler(response).await,
1980 };
1981 response = match response_status {
1982 Ok(response) => response,
1983 Err(err) => {
1984 if error_log_enabled {
1985 logger
1986 .send(LogMessage::new(
1987 format!("Unexpected error while serving a request: {}", err),
1988 true,
1989 ))
1990 .await
1991 .unwrap_or_default();
1992 }
1993
1994 let response = generate_error_response(
1995 StatusCode::INTERNAL_SERVER_ERROR,
1996 &combined_config,
1997 &None,
1998 )
1999 .await;
2000 if log_enabled {
2001 log_combined(
2002 &logger,
2003 socket_data.remote_addr.ip(),
2004 latest_auth_data,
2005 log_method,
2006 log_request_path,
2007 log_protocol,
2008 response.status().as_u16(),
2009 match response.headers().get(header::CONTENT_LENGTH) {
2010 Some(header_value) => match header_value.to_str() {
2011 Ok(header_value) => match header_value.parse::<u64>() {
2012 Ok(content_length) => Some(content_length),
2013 Err(_) => response.body().size_hint().exact(),
2014 },
2015 Err(_) => response.body().size_hint().exact(),
2016 },
2017 None => response.body().size_hint().exact(),
2018 },
2019 log_referrer,
2020 log_user_agent,
2021 )
2022 .await;
2023 }
2024 let (mut response_parts, response_body) = response.into_parts();
2025 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
2026 let custom_headers_hash_iter = custom_headers_hash.iter();
2027 for (header_name, header_value) in custom_headers_hash_iter {
2028 if let Some(header_name) = header_name.as_str() {
2029 if let Some(header_value) = header_value.as_str() {
2030 if !response_parts.headers.contains_key(header_name) {
2031 if let Ok(header_value) = HeaderValue::from_str(
2032 &header_value.replace("{path}", &sanitized_url_pathname),
2033 ) {
2034 if let Ok(header_name) = HeaderName::from_str(header_name) {
2035 response_parts.headers.insert(header_name, header_value);
2036 }
2037 }
2038 }
2039 }
2040 }
2041 }
2042 }
2043 if let Some(http3_alt_port) = http3_alt_port {
2044 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
2045 Some(value) => {
2046 let header_value_old = String::from_utf8_lossy(value.as_bytes());
2047 let header_value_new =
2048 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
2049
2050 if header_value_old != header_value_new {
2051 HeaderValue::from_bytes(
2052 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
2053 )
2054 } else {
2055 HeaderValue::from_bytes(header_value_old.as_bytes())
2056 }
2057 }
2058 None => HeaderValue::from_bytes(
2059 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
2060 .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 =
2140 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
2141
2142 if header_value_old != header_value_new {
2143 HeaderValue::from_bytes(
2144 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
2145 )
2146 } else {
2147 HeaderValue::from_bytes(header_value_old.as_bytes())
2148 }
2149 }
2150 None => HeaderValue::from_bytes(
2151 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
2152 ),
2153 } {
2154 response_parts.headers.insert(header::ALT_SVC, header_value);
2155 }
2156 }
2157 response_parts
2158 .headers
2159 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
2160
2161 let mut response = Response::from_parts(response_parts, response_body);
2162
2163 while let Some(mut executed_handler) = executed_handlers.pop() {
2164 let response_status = match is_proxy_request {
2165 true => {
2166 executed_handler
2167 .proxy_response_modifying_handler(response)
2168 .await
2169 }
2170 false => executed_handler.response_modifying_handler(response).await,
2171 };
2172 response = match response_status {
2173 Ok(response) => response,
2174 Err(err) => {
2175 if error_log_enabled {
2176 logger
2177 .send(LogMessage::new(
2178 format!("Unexpected error while serving a request: {}", err),
2179 true,
2180 ))
2181 .await
2182 .unwrap_or_default();
2183 }
2184
2185 let response =
2186 generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, &combined_config, &None)
2187 .await;
2188 if log_enabled {
2189 log_combined(
2190 &logger,
2191 socket_data.remote_addr.ip(),
2192 latest_auth_data,
2193 log_method,
2194 log_request_path,
2195 log_protocol,
2196 response.status().as_u16(),
2197 match response.headers().get(header::CONTENT_LENGTH) {
2198 Some(header_value) => match header_value.to_str() {
2199 Ok(header_value) => match header_value.parse::<u64>() {
2200 Ok(content_length) => Some(content_length),
2201 Err(_) => response.body().size_hint().exact(),
2202 },
2203 Err(_) => response.body().size_hint().exact(),
2204 },
2205 None => response.body().size_hint().exact(),
2206 },
2207 log_referrer,
2208 log_user_agent,
2209 )
2210 .await;
2211 }
2212 let (mut response_parts, response_body) = response.into_parts();
2213 if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
2214 let custom_headers_hash_iter = custom_headers_hash.iter();
2215 for (header_name, header_value) in custom_headers_hash_iter {
2216 if let Some(header_name) = header_name.as_str() {
2217 if let Some(header_value) = header_value.as_str() {
2218 if !response_parts.headers.contains_key(header_name) {
2219 if let Ok(header_value) = HeaderValue::from_str(
2220 &header_value.replace("{path}", &sanitized_url_pathname),
2221 ) {
2222 if let Ok(header_name) = HeaderName::from_str(header_name) {
2223 response_parts.headers.insert(header_name, header_value);
2224 }
2225 }
2226 }
2227 }
2228 }
2229 }
2230 }
2231 if let Some(http3_alt_port) = http3_alt_port {
2232 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
2233 Some(value) => {
2234 let header_value_old = String::from_utf8_lossy(value.as_bytes());
2235 let header_value_new =
2236 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port);
2237
2238 if header_value_old != header_value_new {
2239 HeaderValue::from_bytes(
2240 format!("{}, {}", header_value_old, header_value_new).as_bytes(),
2241 )
2242 } else {
2243 HeaderValue::from_bytes(header_value_old.as_bytes())
2244 }
2245 }
2246 None => HeaderValue::from_bytes(
2247 format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
2248 ),
2249 } {
2250 response_parts.headers.insert(header::ALT_SVC, header_value);
2251 }
2252 }
2253 response_parts
2254 .headers
2255 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
2256
2257 return Ok(Response::from_parts(response_parts, response_body));
2258 }
2259 };
2260 }
2261
2262 if log_enabled {
2263 log_combined(
2264 &logger,
2265 socket_data.remote_addr.ip(),
2266 latest_auth_data,
2267 log_method,
2268 log_request_path,
2269 log_protocol,
2270 response.status().as_u16(),
2271 match response.headers().get(header::CONTENT_LENGTH) {
2272 Some(header_value) => match header_value.to_str() {
2273 Ok(header_value) => match header_value.parse::<u64>() {
2274 Ok(content_length) => Some(content_length),
2275 Err(_) => response.body().size_hint().exact(),
2276 },
2277 Err(_) => response.body().size_hint().exact(),
2278 },
2279 None => response.body().size_hint().exact(),
2280 },
2281 log_referrer,
2282 log_user_agent,
2283 )
2284 .await;
2285 }
2286 Ok(response)
2287 }
2288}
2289
2290#[allow(clippy::too_many_arguments)]
2291pub async fn request_handler(
2292 request: Request<BoxBody<Bytes, std::io::Error>>,
2293 remote_address: SocketAddr,
2294 local_address: SocketAddr,
2295 encrypted: bool,
2296 config: Arc<Yaml>,
2297 logger: Sender<LogMessage>,
2298 handlers_vec: Vec<Box<dyn ServerModuleHandlers + Send>>,
2299 acme_http01_resolver_option: Option<Arc<ResolvesServerCertAcme>>,
2300 http3_alt_port: Option<u16>,
2301) -> Result<Response<BoxBody<Bytes, std::io::Error>>, anyhow::Error> {
2302 let timeout_yaml = &config["global"]["timeout"];
2303 if timeout_yaml.is_null() {
2304 request_handler_wrapped(
2305 request,
2306 remote_address,
2307 local_address,
2308 encrypted,
2309 config,
2310 logger,
2311 handlers_vec,
2312 acme_http01_resolver_option,
2313 http3_alt_port,
2314 )
2315 .await
2316 .map_err(|e| anyhow::anyhow!(e))
2317 } else {
2318 let timeout_millis = timeout_yaml.as_i64().unwrap_or(300000) as u64;
2319 match timeout(
2320 Duration::from_millis(timeout_millis),
2321 request_handler_wrapped(
2322 request,
2323 remote_address,
2324 local_address,
2325 encrypted,
2326 config,
2327 logger,
2328 handlers_vec,
2329 acme_http01_resolver_option,
2330 http3_alt_port,
2331 ),
2332 )
2333 .await
2334 {
2335 Ok(response) => response.map_err(|e| anyhow::anyhow!(e)),
2336 Err(_) => Err(anyhow::anyhow!("The client or server has timed out")),
2337 }
2338 }
2339}