1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::str::FromStr;
use esi::{ExecutionContext, transform_esi_string};
use fastly::{Request, Response, http::{Url, header}};
pub struct FastlyRequestHandler {
original_req: Request
}
impl FastlyRequestHandler {
fn from_request(req: Request) -> FastlyRequestHandler {
FastlyRequestHandler {
original_req: req
}
}
}
impl ExecutionContext for FastlyRequestHandler {
fn send_request(&self, req: esi::Request) -> Result<esi::Response, esi::Error> {
println!("Sending request: {:?}", req);
let mut bereq = self.original_req.clone_without_body().with_url(&req.url);
let parsed_url = Url::from_str(&req.url).unwrap();
let backend = parsed_url.host_str().unwrap();
bereq.set_header(header::HOST, backend);
let mut beresp = match bereq.send(backend) {
Ok(resp) => resp,
Err(_) => panic!("Error sending ESI include request to backend {}", backend)
};
if beresp.get_status().as_u16() < 200 || beresp.get_status().as_u16() > 299 {
return Err(esi::Error::from_message(&format!("{}: {}", beresp.get_status(), beresp.take_body_str())));
}
let resp = esi::Response {
body: String::from(beresp.take_body_str()),
status_code: beresp.get_status().as_u16()
};
println!("Received response: {:?}", resp);
Ok(resp)
}
}
pub fn process_esi(req: Request, mut response: Response) -> Result<Response, fastly::Error> {
let req_handler = FastlyRequestHandler::from_request(req);
match transform_esi_string(response.take_body().into_string(), &req_handler) {
Ok(body) => response.set_body(body),
Err(err) => return Err(fastly::Error::msg(err.message)),
}
Ok(response)
}