in rust-runtime/aws-smithy-client/src/dvr/record.rs [156:215]
fn call(&mut self, mut req: http::Request<SdkBody>) -> Self::Future {
let event_id = self.next_id();
// A request has two 3 phases:
// 1. A "Request" phase. This is initial HTTP request, headers, & URI
// 2. A body phase. This may contain multiple data segments.
// 3. A finalization phase. An EOF of some sort is sent on the body to indicate that
// the channel should be closed.
// Phase 1: the initial http request
self.data.lock().unwrap().push(Event {
connection_id: event_id,
action: Action::Request {
request: dvr::Request::from(&req),
},
});
// Phase 2: Swap out the real request body for one that will log all traffic that passes
// through it
// This will also handle phase three when the request body runs out of data.
record_body(
req.body_mut(),
event_id,
Direction::Request,
self.data.clone(),
);
let events = self.data.clone();
// create a channel we'll use to stream the data while reading it
let resp_fut = self.inner.call(req);
let fut = async move {
let resp = resp_fut.await;
match resp {
Ok(resp) => {
// wrap the hyper body in an SDK body
let mut resp = resp.map(|body| body.into());
// push the initial response event
events.lock().unwrap().push(Event {
connection_id: event_id,
action: Action::Response {
response: Ok(dvr::Response::from(&resp)),
},
});
// instrument the body and record traffic
record_body(resp.body_mut(), event_id, Direction::Response, events);
Ok(resp)
}
Err(e) => {
events.lock().unwrap().push(Event {
connection_id: event_id,
action: Action::Response {
response: Err(Error(format!("{}", &e))),
},
});
Err(e)
}
}
};
Box::pin(fut)
}