Hi,
I'm trying to write an HTTP proxy with Hyper (0.11 new tokio version). When a request comes in a request to an upstream server is triggered with client.get() and the response should be forwarded as server response. Here is what I have so far:
extern crate hyper;
extern crate futures;
extern crate tokio_core;
use hyper::header::ContentLength;
use hyper::Client;
use hyper::server::{Http, Request, Response, Service};
use hyper::header::Host;
use std::error::Error;
use std::io::{self, Write};
use futures::{Future, Stream};
use tokio_core::reactor::Core;
struct Proxy {
upstream_port: u16,
}
impl Service for Proxy {
// boilerplate hooking up hyper's server types
type Request = Request;
type Response = Response;
type Error = hyper::Error;
// The future representing the eventual Response your call will
// resolve to. This can change to whatever Future you need.
type Future = futures::future::FutureResult<Self::Response, Self::Error>;
fn call(&self, request: Request) -> Self::Future {
let response = pipe_through(request, self.upstream_port);
futures::future::ok(response)
}
}
pub fn start_server(port: u16, upstream_port: u16) {
let address = "127.0.0.1:".to_owned() + &port.to_string();
println!("Listening on {}", address);
let addr = address.parse().unwrap();
let server = Http::new()
.bind(&addr, move || Ok(Proxy { upstream_port }))
.unwrap();
server.run().unwrap();
}
fn pipe_through(request: Request, upstream_port: u16) -> Response {
let mut response: Response = Response::new();
let mut core = Core::new().unwrap();
let client = Client::new(&core.handle());
let uri = "http://drupal-8.localhost".parse().unwrap();
let work = client
.get(uri)
.and_then(|upstream_response| {
println!("Response: {}", upstream_response.status());
upstream_response
.body()
.for_each(|chunk| {
response
.write_all(&chunk)
.map(|_| ())
.map_err(From::from)
})
});
core.run(work).unwrap();
response
}
fn main() {
let port: u16 = 9090;
let upstream_port: u16 = 80;
let _listening = rustnish::start_server(port, upstream_port);
}
This of course fails to compile with "no method named write_all
found for type hyper::Response
". How can I write chunks of data continuously to a server response object? Ideally I would stream through the client response, but I can't find the right methods I should use.
Thanks!