ferron/modules/
x_forwarded_for.rs1use std::error::Error;
2use std::net::{IpAddr, SocketAddr};
3
4use crate::ferron_common::{
5 ErrorLogger, HyperResponse, RequestData, ResponseData, ServerConfig, ServerModule,
6 ServerModuleHandlers, SocketData,
7};
8use crate::ferron_common::{HyperUpgraded, WithRuntime};
9use async_trait::async_trait;
10use hyper::StatusCode;
11use hyper_tungstenite::HyperWebsocket;
12use tokio::runtime::Handle;
13
14struct XForwardedForModule;
15
16pub fn server_module_init(
17) -> Result<Box<dyn ServerModule + Send + Sync>, Box<dyn Error + Send + Sync>> {
18 Ok(Box::new(XForwardedForModule::new()))
19}
20
21impl XForwardedForModule {
22 fn new() -> Self {
23 Self
24 }
25}
26
27impl ServerModule for XForwardedForModule {
28 fn get_handlers(&self, handle: Handle) -> Box<dyn ServerModuleHandlers + Send> {
29 Box::new(XForwardedForModuleHandlers { handle })
30 }
31}
32struct XForwardedForModuleHandlers {
33 handle: Handle,
34}
35
36#[async_trait]
37impl ServerModuleHandlers for XForwardedForModuleHandlers {
38 async fn request_handler(
39 &mut self,
40 request: RequestData,
41 config: &ServerConfig,
42 socket_data: &SocketData,
43 _error_logger: &ErrorLogger,
44 ) -> Result<ResponseData, Box<dyn Error + Send + Sync>> {
45 WithRuntime::new(self.handle.clone(), async move {
46 if config["enableIPSpoofing"].as_bool() == Some(true) {
47 let hyper_request = request.get_hyper_request();
48
49 if let Some(x_forwarded_for_value) = hyper_request.headers().get("x-forwarded-for") {
50 let x_forwarded_for = x_forwarded_for_value.to_str()?;
51
52 let prepared_remote_ip_str = match x_forwarded_for.split(",").nth(0) {
53 Some(ip_address_str) => ip_address_str.replace(" ", ""),
54 None => {
55 return Ok(
56 ResponseData::builder(request)
57 .status(StatusCode::BAD_REQUEST)
58 .build(),
59 );
60 }
61 };
62
63 let prepared_remote_ip: IpAddr = match prepared_remote_ip_str.parse() {
64 Ok(ip_address) => ip_address,
65 Err(_) => {
66 return Ok(
67 ResponseData::builder(request)
68 .status(StatusCode::BAD_REQUEST)
69 .build(),
70 );
71 }
72 };
73
74 let new_socket_addr = SocketAddr::new(prepared_remote_ip, socket_data.remote_addr.port());
75
76 return Ok(
77 ResponseData::builder(request)
78 .new_remote_address(new_socket_addr)
79 .build(),
80 );
81 }
82
83 return Ok(ResponseData::builder(request).build());
84 }
85
86 Ok(ResponseData::builder(request).build())
87 })
88 .await
89 }
90
91 async fn proxy_request_handler(
92 &mut self,
93 request: RequestData,
94 _config: &ServerConfig,
95 _socket_data: &SocketData,
96 _error_logger: &ErrorLogger,
97 ) -> Result<ResponseData, Box<dyn Error + Send + Sync>> {
98 Ok(ResponseData::builder(request).build())
99 }
100
101 async fn response_modifying_handler(
102 &mut self,
103 response: HyperResponse,
104 ) -> Result<HyperResponse, Box<dyn Error + Send + Sync>> {
105 Ok(response)
106 }
107
108 async fn proxy_response_modifying_handler(
109 &mut self,
110 response: HyperResponse,
111 ) -> Result<HyperResponse, Box<dyn Error + Send + Sync>> {
112 Ok(response)
113 }
114
115 async fn connect_proxy_request_handler(
116 &mut self,
117 _upgraded_request: HyperUpgraded,
118 _connect_address: &str,
119 _config: &ServerConfig,
120 _socket_data: &SocketData,
121 _error_logger: &ErrorLogger,
122 ) -> Result<(), Box<dyn Error + Send + Sync>> {
123 Ok(())
124 }
125
126 fn does_connect_proxy_requests(&mut self) -> bool {
127 false
128 }
129
130 async fn websocket_request_handler(
131 &mut self,
132 _websocket: HyperWebsocket,
133 _uri: &hyper::Uri,
134 _config: &ServerConfig,
135 _socket_data: &SocketData,
136 _error_logger: &ErrorLogger,
137 ) -> Result<(), Box<dyn Error + Send + Sync>> {
138 Ok(())
139 }
140
141 fn does_websocket_requests(&mut self, _config: &ServerConfig, _socket_data: &SocketData) -> bool {
142 false
143 }
144}