In the context of a HTTP/S proxy, I want to manipulate and change a Response type using the hyper library. I'm having trouble doing this because it seems no matter how I read it, it gets dropped because I'm unable to clone it.
error[E0599]: no method named `clone` found for struct `Response` in the current scope
--> examples/log.rs:33:23
|
33 | let bod = res.clone().into_body();
| ^^^^^ method not found in `Response<Body>`
For more information about this error, try `rustc --explain E0599`.
error: could not compile `hudsucker` due to previous error
I'm using the hudsucker crate (which uses hyper). Here is my modified version of the example log
in the github repo.
use hudsucker::{
async_trait::async_trait,
certificate_authority::RcgenAuthority,
hyper::{Body, Request, Response},
tokio_tungstenite::tungstenite::Message,
*,
};
use rustls_pemfile as pemfile;
use std::net::SocketAddr;
use tracing::*;
async fn shutdown_signal() {
tokio::signal::ctrl_c()
.await
.expect("Failed to install CTRL+C signal handler");
}
#[derive(Clone)]
struct LogHandler;
#[async_trait]
impl HttpHandler for LogHandler {
async fn handle_request(
&mut self,
_ctx: &HttpContext,
req: Request<Body>,
) -> RequestOrResponse {
//println!("{:?}", req);
req.into()
}
async fn handle_response(&mut self, _ctx: &HttpContext, mut res: Response<Body>) -> Response<Body> {
let bod = res.clone().into_body();
// println!("{:?}", hyper::body::to_bytes(bod).await);
println!("{:?}", bod);
res
}
}
#[async_trait]
impl WebSocketHandler for LogHandler {
async fn handle_message(&mut self, _ctx: &WebSocketContext, msg: Message) -> Option<Message> {
//println!("{:?}", msg);
Some(msg)
}
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let mut private_key_bytes: &[u8] = include_bytes!("ca/hudsucker.key");
let mut ca_cert_bytes: &[u8] = include_bytes!("ca/hudsucker.cer");
let private_key = rustls::PrivateKey(
pemfile::pkcs8_private_keys(&mut private_key_bytes)
.expect("Failed to parse private key")
.remove(0),
);
let ca_cert = rustls::Certificate(
pemfile::certs(&mut ca_cert_bytes)
.expect("Failed to parse CA certificate")
.remove(0),
);
let ca = RcgenAuthority::new(private_key, ca_cert, 1_000)
.expect("Failed to create Certificate Authority");
let proxy = Proxy::builder()
.with_addr(SocketAddr::from(([127, 0, 0, 1], 3000)))
.with_rustls_client()
.with_ca(ca)
.with_http_handler(LogHandler)
.with_websocket_handler(LogHandler)
.build();
if let Err(e) = proxy.start(shutdown_signal()).await {
error!("{}", e);
}
}
I'm not to familiar with how the Body bytes work, would I be cloning that and sending a new body with modified bytes?