Hyper: return boxed future from inner future

The following code errors with "expected struct std::boxed::Box, found struct hyper::Response". How can I correctly return a response from the inner result future?


extern crate futures;
extern crate hyper;
extern crate tokio;

use futures::future;

use hyper::{Body, Request, Response, Server, StatusCode, Method};
use hyper::rt::{self, Future};
use hyper::service::service_fn;

use tokio::net::TcpStream;

type BoxFut = Box<Future<Item=Response<Body>, Error=hyper::Error> + Send>;

/// Our server HTTP handler to initiate HTTP upgrades.
fn server_upgrade(req: Request<Body>) -> BoxFut {
    let mut res = Response::new(Body::empty());

    // Send a 400 to any request that is not CONNECT
    if req.method() != Method::CONNECT {
        *res.status_mut() = StatusCode::BAD_REQUEST;
        return Box::new(future::ok(res));
    }

    println!("New CONNECT request to {}", req.uri());
    let address = "127.0.0.1:17000".parse().unwrap();
    let upstream_connection = TcpStream::connect(&address).and_then(|stream| {
        println!("created stream");
        Ok(stream)
    });

    let result = upstream_connection
        .map(|upstream| {
            *res.status_mut() = StatusCode::OK;
            Box::new(future::ok(res))
        })
        .or_else(|err| {
            *res.status_mut() = StatusCode::GATEWAY_TIMEOUT;
            Ok(Box::new(future::ok(res)))
        });

    Box::new(result)
}

fn main() {
    let addr = ([127, 0, 0, 1], 49483).into();

    let server = Server::bind(&addr)
        .serve(|| service_fn(server_upgrade))
        .map_err(|e| eprintln!("server error: {}", e));

    println!("Running on {}", addr);

    rt::run(server);
}

OK, figured it out on my own. You have to return directly a hyper response in the inner future:

    let result = upstream_connection
        .map(|upstream| {
            *res.status_mut() = StatusCode::OK;
            res
        })
        .or_else(|_err| {
            let mut res = Response::new(Body::empty());
            *res.status_mut() = StatusCode::GATEWAY_TIMEOUT;
            Ok(res)
        });

    Box::new(result)

The error message is very misleading in this case, though.