|
1 | 1 | use actix_web::web; |
2 | 2 | use base64::{Engine, prelude::BASE64_STANDARD}; |
3 | | -use mongodb::bson::{Bson, to_bson}; |
4 | 3 | #[cfg(feature = "observe")] |
5 | 4 | use mongodb::bson; |
| 5 | +use mongodb::bson::{Bson, to_bson}; |
6 | 6 | use rand::{Rng, rng}; |
7 | 7 | use serde::Deserialize; |
8 | 8 | use tera::Context; |
@@ -218,21 +218,34 @@ pub mod forwarding { |
218 | 218 |
|
219 | 219 | use crate::errors::{BridgeError, Result}; |
220 | 220 |
|
| 221 | + /// Configuration that is passed to the forward function takes the following parameters. |
| 222 | + /// inference filters out Auth specific headers to the proxy forward |
| 223 | + /// pack_cookies packs cookies to be compatible for http protocol older than 2 |
| 224 | + /// updated_cookie will forward back to client any updated cookies |
| 225 | + #[derive(Default)] |
| 226 | + pub struct Config<'a> { |
| 227 | + pub inference: bool, |
| 228 | + pub pack_cookies: bool, |
| 229 | + pub updated_cookie: Option<Cookie<'a>>, |
| 230 | + } |
| 231 | + |
221 | 232 | // No inline needed... generic are inherently inlined |
222 | | - #[allow(clippy::too_many_arguments)] |
223 | 233 | pub async fn forward<T>( |
224 | 234 | req: HttpRequest, |
225 | 235 | mut payload: web::Payload, |
226 | 236 | method: Method, |
227 | 237 | peer_addr: Option<PeerAddr>, |
228 | 238 | client: web::Data<reqwest::Client>, |
229 | 239 | new_url: T, |
230 | | - updated_cookie: Option<Cookie<'_>>, |
231 | | - inference: bool, |
| 240 | + config: Config<'_>, |
232 | 241 | ) -> Result<HttpResponse> |
233 | 242 | where |
234 | 243 | T: AsRef<str> + Send + Sync, |
235 | 244 | { |
| 245 | + let inference = config.inference; |
| 246 | + let pack_cookies = config.pack_cookies; |
| 247 | + let updated_cookie = config.updated_cookie; |
| 248 | + |
236 | 249 | let (tx, rx) = mpsc::channel(128); |
237 | 250 |
|
238 | 251 | actix_web::rt::spawn(async move { |
@@ -292,6 +305,27 @@ pub mod forwarding { |
292 | 305 | ); |
293 | 306 | } |
294 | 307 |
|
| 308 | + // find all the cookie header and pack them delimited by ";" |
| 309 | + if pack_cookies { |
| 310 | + let mut cookies = String::new(); |
| 311 | + for (header_name, header_value) in req.headers().iter() { |
| 312 | + if header_name.as_str().to_lowercase() == "cookie" { |
| 313 | + if let Ok(value) = header_value.to_str() { |
| 314 | + if !cookies.is_empty() { |
| 315 | + cookies.push(';'); |
| 316 | + } |
| 317 | + cookies.push_str(value); |
| 318 | + } |
| 319 | + } |
| 320 | + } |
| 321 | + if !cookies.is_empty() { |
| 322 | + headers.insert( |
| 323 | + ReqwestHeaderName::from_static("cookie"), |
| 324 | + ReqwestHeaderValue::from_str(&cookies).unwrap(), |
| 325 | + ); |
| 326 | + } |
| 327 | + } |
| 328 | + |
295 | 329 | let forwarded_req = forwarded_req.headers(headers); |
296 | 330 |
|
297 | 331 | let res = forwarded_req.send().await.map_err(|e| { |
|
0 commit comments