blob: f368f6c89f6313cfbfda2a6660d04582f2aaddb6 [file] [log] [blame]
// Copyright 2017 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.
#![deny(warnings)]
#![feature(async_await, await_macro, futures_api)]
use {
failure::{Error, ResultExt},
fidl_fuchsia_net_oldhttp as http,
fuchsia_app as component,
fuchsia_async as fasync,
fuchsia_zircon as zx,
futures::io::{AllowStdIo, AsyncReadExt},
};
fn print_headers(resp: &http::UrlResponse) {
println!(">>> Headers <<<");
if let Some(status) = &resp.status_line {
println!(" {}", status);
}
if let Some(hdrs) = &resp.headers {
for hdr in hdrs {
println!(" {}={}", hdr.name, hdr.value);
}
}
}
fn main() -> Result<(), Error> {
let url = match std::env::args().nth(1) {
Some(url) => {
if url.find("://").is_none() {
["http://", &url].concat()
} else {
url
}
}
None => {
println!("usage: {} <url>", std::env::args().nth(0).unwrap());
return Ok(());
}
};
// Set up async executor
let mut exec = fasync::Executor::new()?;
//// Run the future to completion
exec.run_singlethreaded(http_get(url))
}
/// Connects to the http service, sends a url request, and prints the response.
async fn http_get(url: String) -> Result<(), Error> {
// Connect to the http service
let net = component::client::connect_to_service::<http::HttpServiceMarker>()?;
// Create a UrlLoader instance
let (s, p) = zx::Channel::create().context("failed to create zx channel")?;
let proxy = fasync::Channel::from_channel(p).context("failed to make async channel")?;
let loader_server = fidl::endpoints::ServerEnd::<http::UrlLoaderMarker>::new(s);
net.create_url_loader(loader_server)?;
// Send the UrlRequest to fetch the webpage
let mut req = http::UrlRequest {
url: url,
method: String::from("GET"),
headers: None,
body: None,
response_body_buffer_size: 0,
auto_follow_redirects: true,
cache_mode: http::CacheMode::Default,
response_body_mode: http::ResponseBodyMode::Stream,
};
let loader_proxy = http::UrlLoaderProxy::new(proxy);
let resp = await!(loader_proxy.start(&mut req))?;
if let Some(e) = resp.error {
let code = e.code;
println!("Got error: {} ({})",
code,
e.description.unwrap_or("".into()));
return Ok(());
}
print_headers(&resp);
let mut socket = match resp.body.map(|x| *x) {
Some(http::UrlBody::Stream(s)) => fasync::Socket::from_socket(s)?,
_ => return Err(Error::from(zx::Status::BAD_STATE)),
};
// stdout is blocking, but we'll pretend it's okay
println!(">>> Body <<<");
// Copy the bytes from the socket to stdout
let mut stdio = AllowStdIo::new(std::io::stdout());
await!(socket.copy_into(&mut stdio))?;
println!("\n>>> EOF <<<");
Ok(())
}