about summary refs log tree commit diff
path: root/pkgs/profpatsch/xdg-open/read-http.rs
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2020-07-03 13:11:03 +0200
committerProfpatsch <mail@profpatsch.de>2020-07-06 20:13:42 +0200
commit97f05263ef490a063a33733d7ea607411a097df8 (patch)
treef1617705e22437c908459e1de059993bcab09ed3 /pkgs/profpatsch/xdg-open/read-http.rs
parente409df3861f48de44d0e37277ce007e348a7a0dc (diff)
pkgs/profpatsch/xdg-open: Prepare decoding http urls
I want to be able to open http(s) links that are e.g. images directly
in the right application. Aka web urls should be transparent, instead
of always opening everthing in the browser.

This adds some silly ways of connecting to the server and parsing
out the headers, in order to fetch the content-type.
Diffstat (limited to 'pkgs/profpatsch/xdg-open/read-http.rs')
-rw-r--r--pkgs/profpatsch/xdg-open/read-http.rs56
1 files changed, 56 insertions, 0 deletions
diff --git a/pkgs/profpatsch/xdg-open/read-http.rs b/pkgs/profpatsch/xdg-open/read-http.rs
new file mode 100644
index 00000000..9fe8d6a9
--- /dev/null
+++ b/pkgs/profpatsch/xdg-open/read-http.rs
@@ -0,0 +1,56 @@
+extern crate httparse;
+extern crate netencode;
+
+use std::os::unix::io::FromRawFd;
+use std::io::Read;
+use std::io::Write;
+
+use netencode::{encode, U};
+
+fn main() -> std::io::Result<()> {
+
+    fn die<T: std::fmt::Display>(msg: T) {
+        eprintln!("{}", msg);
+        std::process::exit(1);
+    }
+
+    // max header size chosen arbitrarily
+    let mut headers = [httparse::EMPTY_HEADER; 128];
+    let mut resp = httparse::Response::new(&mut headers);
+    let mut buf = vec![];
+    std::io::stdin().read_to_end(&mut buf)?;
+    let res = resp.parse(&mut buf);
+    match res {
+        Err(err) => die(format!("http response error: {:?}", err)),
+        Ok(_start_of_body) => {
+            match resp.code {
+                Some(code) => write_dict(code, resp.reason, resp.headers)?,
+                None => die(format!("no http status"))
+            }
+        }
+    };
+    Ok(())
+}
+
+fn write_dict<'buf>(code: u16, reason: Option<&'buf str>, headers: &mut [httparse::Header<'buf>]) -> std::io::Result<()> {
+    let mut http = vec![
+        ("status", Box::new(U::N6(code as u64))),
+    ];
+
+    if let Some(t) = reason {
+        http.push(("status-text", Box::new(U::Text(t.as_bytes()))))
+    };
+
+    http.push(("headers", Box::new(U::Record(
+        headers.iter_mut().map(
+            |httparse::Header { name, value }|
+            (*name,
+             Box::new(U::Binary(value)))
+        ).collect::<Vec<_>>()
+    ))));
+
+    encode(
+        &mut std::io::stdout(),
+        U::Record(http)
+    )
+}