use hyper::http::{Request, Response, StatusCode};
use hyper::service::Service;
use core::task::{Context, Poll};
use core::future::Future;
use std::pin::Pin;
#[derive(Clone)]
pub struct CustomTransporter;
impl CustomTransporter {
pub fn new() -> CustomTransporter {
CustomTransporter{}
}
}
impl Service<hyper::Uri> for CustomTransporter {
type Response = Response<Vec<u8>>;
type Error = hyper::http::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: hyper::Uri) -> Self::Future {
// create the body
let body: Vec<u8> = "hello, world!\n"
.as_bytes()
.to_owned();
// Create the HTTP response
let resp = Response::builder()
.status(StatusCode::OK)
.body(body)
.expect("Unable to create `http::Response`");
// create a response in a future.
let fut = async {
Ok(resp)
};
// Return the response as an immediate future
Box::pin(fut)
}
}
but then on
let connector = CustomTransporter::new();
let client = Client::builder().build(connector);
on the build call, I get
the trait bound `hyper::Response<std::vec::Vec<u8>>: tokio::io::AsyncRead` is not satisfied
the trait `tokio::io::AsyncRead` is not implemented for `hyper::Response<std::vec::Vec<u8>>`
note: required because of the requirements on the impl of `hyper::client::connect::Connect` for `custom_req::CustomTransporter`rustc(E0277)
Here's my custom transporter with a Response of type std::io::Cursor
use hyper::http::{Request, Response, StatusCode};
use hyper::service::Service;
use hyper::client::connect::Connect;
use core::task::{Context, Poll};
use core::future::Future;
use std::pin::Pin;
use std::io::Cursor;
#[derive(Clone)]
pub struct CustomTransporter;
impl CustomTransporter {
pub fn new() -> CustomTransporter {
CustomTransporter{}
}
}
impl Service<hyper::Uri> for CustomTransporter {
type Response = Cursor<std::vec::Vec<u8>>;
type Error = hyper::http::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: hyper::Uri) -> Self::Future {
// create the body
let body: Vec<u8> = "hello, world!\n"
.as_bytes()
.to_owned();
// Create the HTTP response
let resp = Cursor::new(body.to_vec());
// create a response in a future.
let fut = async {
Ok(resp)
};
// Return the response as an immediate future
Box::pin(fut)
}
}
Then I call like this:
let connector = CustomTransporter::new();
let client = Client::builder().build(connector);
let mut res = client.get(url).await?;
and I get
error[E0277]: the trait bound `std::io::Cursor<Vec<u8>>: hyper::client::connect::Connection` is not satisfied
--> src/main.rs:42:36
|
42 | let client = Client::builder().build(connector);
| ^^^^^ the trait `hyper::client::connect::Connection` is not implemented for `std::io::Cursor<Vec<u8>>`
|
= note: required because of the requirements on the impl of `hyper::client::connect::Connect` for `CustomTransporter`
error[E0277]: the trait bound `std::io::Cursor<Vec<u8>>: hyper::client::connect::Connection` is not satisfied
--> src/main.rs:42:36
|
42 | let client = Client::builder().build(connector);
| ^^^^^ the trait `hyper::client::connect::Connection` is not implemented for `std::io::Cursor<Vec<u8>>`
and I cannot implement Connection for Cursor<Vec<u8>>
use hyper::http::{Request, Response, StatusCode};
use hyper::service::Service;
use hyper::client::connect::Connect;
use core::task::{Context, Poll};
use core::future::Future;
use std::pin::Pin;
use std::io::Cursor;
use hyper::client::connect::{Connection, Connected};
use tokio::io::{AsyncRead, AsyncWrite};
#[derive(Clone)]
pub struct CustomTransporter;
unsafe impl Send for CustomTransporter {}
impl CustomTransporter {
pub fn new() -> CustomTransporter {
CustomTransporter{}
}
}
impl Connection for CustomTransporter {
fn connected(&self) -> Connected {
Connected::new()
}
}
struct CustomResponse {
w: Cursor<Vec<u8>>
}
impl Connection for CustomResponse {
fn connected(&self) -> Connected {
Connected::new()
}
}
impl AsyncRead for CustomResponse {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut tokio::io::ReadBuf<'_>
) -> Poll<std::io::Result<()>> {
self.w.poll_read(cx, buf)
}
}
impl AsyncWrite for CustomResponse {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize, std::io::Error>>{
let v = vec!();
self.w.poll_write(cf, buf);
}
fn poll_flush(
self: Pin<&mut Self>,
cx: &mut Context<'_>
) -> Poll<Result<(), std::io::Error>> {
self.w.poll_flush(cx)
}
fn poll_shutdown(
self: Pin<&mut Self>,
cx: &mut Context<'_>
) -> Poll<Result<(), std::io::Error>>
{
self.w.poll_shutdown(cx)
}
}
impl Service<hyper::Uri> for CustomTransporter {
type Response = CustomResponse;
type Error = hyper::http::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: hyper::Uri) -> Self::Future {
// create the body
let body: Vec<u8> = "hello, world!\n"
.as_bytes()
.to_owned();
// Create the HTTP response
let resp = CustomResponse{
w: Cursor::new(body.to_vec())
};
// create a response in a future.
let fut = async {
Ok(resp)
};
// Return the response as an immediate future
Box::pin(fut)
}
}
it asked me for AsyncWrite also. I don't understand why the Response must implement AsyncWrite since it's supposed to be read, not written to. Do you have an idea?
Anyways, I get problems on forwarding all these calls to std::Cursor:
error[E0599]: no method named `poll_flush` found for struct `std::io::Cursor<Vec<u8>>` in the current scope
--> src/custom_req.rs:61:16
|
61 | self.w.poll_flush(cx)
| ^^^^^^^^^^ method not found in `std::io::Cursor<Vec<u8>>`
error[E0599]: no method named `poll_shutdown` found for struct `std::io::Cursor<Vec<u8>>` in the current scope
--> src/custom_req.rs:69:16
|
69 | self.w.poll_shutdown(cx)
| ^^^^^^^^^^^^^ method not found in `std::io::Cursor<Vec<u8>>`
Why I cannot call these functions, if std::Cursor does implement them?