blob: 8fda20eaeaf80236105ac87c61efbd92f5e6a3ba [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use fuchsia_async as fasync;
use fuchsia_sync::RwLock;
use futures::{FutureExt as _, TryStreamExt as _};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
use std::net::{IpAddr, Ipv6Addr, SocketAddr};
use std::sync::Arc;
use sl4f_lib::server::sl4f::{serve, Sl4f, Sl4fClients};
use sl4f_lib::server::sl4f_executor::run_fidl_loop;
// Config, flexible for any ip/port combination
const SERVER_PORT: u16 = 80;
#[fuchsia::main(logging_tags = ["sl4f"])]
async fn main() {
tracing::info!(" Starting sl4f server");
// State for clients that utilize the /init endpoint
let sl4f_clients = Arc::new(RwLock::new(Sl4fClients::new()));
// State for facades
let sl4f = Sl4f::new(Arc::clone(&sl4f_clients)).expect("failed to create SL4F");
let sl4f = Arc::new(sl4f);
let addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), SERVER_PORT);
tracing::info!("Now listening on: {:?}", addr);
let listener = fasync::net::TcpListener::bind(&addr).expect("bind");
let listener = listener
.accept_stream()
.map_ok(|(stream, _): (_, SocketAddr)| fuchsia_hyper::TcpStream { stream });
// Create channel for communication between http server and FIDL. This once bridged a sync/async
// gap, but no longer does. It would be good to refactor this away.
let (sender, async_receiver) = async_channel::unbounded();
let make_svc = make_service_fn(move |_: &fuchsia_hyper::TcpStream| {
let sender = sender.clone();
let sl4f_clients = Arc::clone(&sl4f_clients);
futures::future::ok::<_, Infallible>(service_fn(move |request| {
serve(request, Arc::clone(&sl4f_clients), sender.clone()).map(Ok::<_, Infallible>)
}))
});
let server = hyper::Server::builder(hyper::server::accept::from_stream(listener))
.executor(fuchsia_hyper::Executor)
.serve(make_svc);
futures::select! {
res = server.fuse() => panic!("HTTP server died: {:?}", res),
() = run_fidl_loop(sl4f, async_receiver).fuse() => panic!("FIDL handler died")
}
}