Merge pull request #565 from betrusted-io/nettype

Nettype - facility to "type" data retrieved from a URL
This commit is contained in:
bunnie 2024-07-14 01:49:22 +08:00 committed by GitHub
commit 4cfcc7ebd3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 71 additions and 5 deletions

View file

@ -484,12 +484,19 @@ impl Modals {
/// frequent updates. For example, instead of once every iteration of a loop, once every ten
/// iterations. This will improve performance of the code and reduce UI churn as well. If this is not
/// possible, you can add a sleep by doing something like the code below. This will reduce the rate at
/// which your loop runs, as well as at which the UI updates. Example:
/// `std::thread::sleep(std::time::Duration::from_millis(100));`
///
/// which your loop runs, as well as at which the UI updates.
/// ```
/// std::thread::sleep(std::time::Duration::from_millis(100)); // This comment needed to pass formatting checks
/// ```
/// - An alternative "softer" solution is to call yield. This will cause the producer to yield its time
/// slice to other processes in the OS, which can give the progress bar a chance to catch up. Example:
/// `xous::yield_slice();`
/// slice to other processes in the OS, which can give the progress bar a chance to catch up.
/// ```
/// xous::yield_slice(); // This comment needed to pass formatting checks
/// ```
/// The comments above are necessary because rustfmt puts trailing whitespace after the code if there
/// isn't a comment. We have a requirement to have no trailing whitespace *and* for code to be
/// auto-formatted. So, the dummy comment is there simply to resolve the two conflicting requirements
/// in the face of a buggy rust format (as of 1.81).
///
/// # Example
/// ```

View file

@ -153,4 +153,5 @@ rand-api = []
locktests = [
] # for debugging some specific `std` tests cherry-picked out of the test suite
simple-tls = ["rustls", "webpki-roots"]
nettype = [] # takes a file from a URL and emits it as keystrokes
default = [] # "debugprint"

View file

@ -151,6 +151,64 @@ impl<'a> ShellCmdApi<'a> for Usb {
write!(ret, "USB debug port unlocked: portions of the device are readable via USB!")
.unwrap();
}
#[cfg(feature = "nettype")]
"nettype" => {
use std::io::{Read, Write};
use std::net::TcpStream;
use std::time::Duration;
if let Some(url) = tokens.next() {
match url.split_once('/') {
Some((host, path)) => match TcpStream::connect((host, 80)) {
Ok(mut stream) => {
stream.set_read_timeout(Some(Duration::from_millis(10_000))).unwrap();
stream.set_write_timeout(Some(Duration::from_millis(10_000))).unwrap();
log::info!("sending GET request");
match write!(stream, "GET /{} HTTP/1.1\r\n", path) {
Ok(_) => log::trace!("sent GET"),
Err(e) => {
log::error!("GET err {:?}", e);
write!(ret, "Error sending GET: {:?}", e).unwrap();
}
}
write!(
stream,
"Host: {}\r\nAccept: */*\r\nUser-Agent: Precursor/0.9.16\r\n",
host
)
.expect("stream error");
write!(stream, "Connection: close\r\n").expect("stream error");
write!(stream, "\r\n").expect("stream error");
log::info!("fetching response....");
let mut buf = [0u8; 4096];
match stream.read(&mut buf) {
Ok(len) => {
let s = std::string::String::from_utf8_lossy(
&buf[..len.min(buf.len())],
);
let mut parts = s.splitn(2, "\r\n\r\n");
let _header = parts.next().unwrap_or("");
let body = parts.next().unwrap_or("");
match self.usb_dev.send_str(&body) {
Ok(n) => write!(ret, "Sent {} chars", n).unwrap(),
Err(_e) => {
write!(ret, "Can't send: are we connected to a host?")
.unwrap()
}
}
}
Err(e) => {
write!(ret, "Didn't get response from host: {:?}", e).unwrap()
}
}
}
Err(e) => write!(ret, "Couldn't connect to {}:80: {:?}", host, e).unwrap(),
},
_ => write!(ret, "Usage: nettype bunniefoo.com/bunnie/test.txt").unwrap(),
}
} else {
write!(ret, "Usage: nettype bunniefoo.com/bunnie/test.txt").unwrap();
}
}
_ => {
write!(ret, "{}", helpstring).unwrap();
}