diff options
| author | Yuval Adam <_@yuv.al> | 2018-07-17 22:59:24 +0300 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2018-07-17 22:59:24 +0300 |
| commit | c3ea11e82d856817d123ea4a9a9d3576b17817a7 (patch) | |
| tree | 6554caa4d5ba3ad1729bad37420e136139714d42 | |
| parent | f0508f43937f1ec8b46d1428602c333f615aa607 (diff) | |
First round of runtime refactoring
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | src/main.rs | 28 | ||||
| -rw-r--r-- | src/notify.rs | 25 | ||||
| -rw-r--r-- | src/serve.rs | 2 | ||||
| -rw-r--r-- | src/upnp.rs | 8 |
6 files changed, 51 insertions, 16 deletions
@@ -433,6 +433,7 @@ dependencies = [ "indoc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "termios 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-fs 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -16,4 +16,5 @@ indoc = "0.2" regex = "1" termios = "0.3.0" tokio-fs = "0.1.2" -tokio-io = "0.1.7"
\ No newline at end of file +tokio-io = "0.1.7" +tokio = "0.1.7" diff --git a/src/main.rs b/src/main.rs index a56c7fd..2b4826f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,10 @@ extern crate indoc; extern crate clap; extern crate colored; +extern crate tokio; +extern crate hyper; +extern crate futures; + use colored::*; use clap::{Arg, App}; use std::path::Path; @@ -12,9 +16,15 @@ use std::process; use std::thread; use std::sync::mpsc; +use hyper::Server; +use hyper::service::service_fn; +use tokio::runtime::Runtime; +use futures::Future; + mod cli; mod upnp; mod serve; +mod notify; fn main() { let app = App::new(env!("CARGO_PKG_NAME")) @@ -48,14 +58,20 @@ fn main() { process::exit(1); } + let addr = "0.0.0.0:51497".parse().unwrap(); - let _http = thread::spawn(move || { - serve::run(); - }); + let server = Server::bind(&addr) + .serve(|| service_fn(serve::response_examples)) + .map_err(|e| eprintln!("server error: {}", e)); - let _udp = thread::spawn(move || { - upnp::discover(); - }); + println!("Listening on http://{}", addr); + + let mut rt = Runtime::new().unwrap(); + rt.spawn(server); + + // let _udp = thread::spawn(move || { + // upnp::discover(); + // }); let (tx, rx) = mpsc::channel(); let child = thread::spawn(move || { diff --git a/src/notify.rs b/src/notify.rs index 60821cd..0d0877d 100644 --- a/src/notify.rs +++ b/src/notify.rs @@ -1,3 +1,10 @@ +extern crate hyper; +extern crate futures; + +use self::hyper::{Method, Request, Uri}; +use self::hyper::header::HeaderValue; +use self::hyper::body::Body; + const SOAP_ACTION_PREFIX: &'static str = "urn:schemas-upnp-org:service:AVTransport:1#"; const ACTION_SET_URI: &'static str = "SetAVTransportURI"; const ACTION_PLAY: &'static str = "Play"; @@ -35,3 +42,21 @@ const BODY_STOP: &'static str = r#" </u:Stop> </s:Body> </s:Envelope>"#; + + +pub fn build_request(body: &'static str, action: &str) { + let uri: Uri = "http://10.5.1.201:38400/serviceControl/AVTransport".parse().unwrap(); + let mut req = Request::new(Body::from(body)); + *req.method_mut() = Method::POST; + *req.uri_mut() = uri.clone(); + req.headers_mut().insert("content-type", HeaderValue::from_str("text/xml").unwrap()); + req.headers_mut().insert("SOAPACTION", HeaderValue::from_str(action).unwrap()); +} + +pub fn set_uri() { + build_request(BODY_SET_URI, "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI") +} + +pub fn play() { + build_request(BODY_PLAY, "urn:schemas-upnp-org:service:AVTransport:1#Play") +} diff --git a/src/serve.rs b/src/serve.rs index ad7ee0f..9ff51a2 100644 --- a/src/serve.rs +++ b/src/serve.rs @@ -25,7 +25,7 @@ pub fn run() { type ResponseFuture = Box<Future<Item=Response<Body>, Error=io::Error> + Send>; -fn response_examples(req: Request<Body>) -> ResponseFuture { +pub fn response_examples(req: Request<Body>) -> ResponseFuture { match (req.method(), req.uri().path()) { (&Method::GET, "/0") => { simple_file_send("/home/yuval/Videos/0") diff --git a/src/upnp.rs b/src/upnp.rs index 7a228b6..8eeac00 100644 --- a/src/upnp.rs +++ b/src/upnp.rs @@ -49,26 +49,18 @@ fn fetch_url(url: hyper::Uri) -> impl Future<Item=(), Error=()> { let client = Client::new(); client - // Fetch the url... .get(url) - // And then, if we get a response back... .and_then(|res| { println!("Response: {}", res.status()); println!("Headers: {:#?}", res.headers()); - - // The body is a stream, and for_each returns a new Future - // when the stream is finished, and calls the closure on - // each chunk of the body... res.into_body().for_each(|chunk| { io::stdout().write_all(&chunk) .map_err(|e| panic!("example expects stdout is open, error={}", e)) }) }) - // If all good, just tell the user... .map(|_| { println!("\n\nDone."); }) - // If there was an error, let the user know... .map_err(|err| { eprintln!("Error {}", err); }) |
