summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml3
-rw-r--r--src/main.rs28
-rw-r--r--src/notify.rs25
-rw-r--r--src/serve.rs2
-rw-r--r--src/upnp.rs8
6 files changed, 51 insertions, 16 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 81d1427..bc65b8e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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)",
]
diff --git a/Cargo.toml b/Cargo.toml
index e8b5602..d397f99 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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);
})