chiark / gitweb /
deployment note, copy to see-test read for hacking main
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 17 May 2020 12:36:28 +0000 (13:36 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 17 May 2020 12:36:28 +0000 (13:36 +0100)
src/bin/ssetest.rs [new file with mode: 0644]
templates/script.js

diff --git a/src/bin/ssetest.rs b/src/bin/ssetest.rs
new file mode 100644 (file)
index 0000000..6caaca9
--- /dev/null
@@ -0,0 +1,88 @@
+
+#![feature(proc_macro_hygiene, decl_macro)]
+
+#[macro_use] extern crate rocket;
+
+extern crate rocket_contrib; // why do we need this ?
+extern crate serde;
+extern crate thiserror;
+extern crate anyhow;
+
+#[path="../imports.rs"]
+mod imports;
+use imports::*;
+
+type RE = E;
+
+#[derive(Serialize,Debug)]
+struct TestRenderContext { }
+
+#[get("/")]
+fn index() -> Result<Template,RE> {
+  let c = TestRenderContext { };
+  Ok(Template::render("test",&c))
+}
+
+const RESOURCES : &[&'static str] = &["script.js", "style.css"];
+
+#[derive(Debug)]
+struct CheckedResourceLeaf { pub safe : &'static str }
+#[derive(Error,Debug)]
+#[error("not a valid resource path")]
+struct UnknownResource{}
+
+impl<'r> FromParam<'r> for CheckedResourceLeaf {
+  type Error = UnknownResource;
+  fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
+    for &safe in RESOURCES {
+      if safe == param.as_str() { return Ok(CheckedResourceLeaf{ safe }) }
+    }
+    Err(UnknownResource{})
+  }
+}
+
+type TestCounter = BufReader<TestCounterInner>;
+#[derive(Debug)]
+struct TestCounterInner { next : usize, }
+impl Read for TestCounterInner {
+  fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+    thread::sleep(Duration::from_millis(500));
+    let data = format!("data: {}\n\n", self.next);
+    self.next += 1;
+    buf[0..data.len()].copy_from_slice(data.as_bytes());
+    Ok(buf.len())
+  }
+}
+
+#[get("/updates")]
+fn updates() -> impl response::Responder<'static> {
+  let tc = TestCounterInner { next : 0 };
+  let tc = BufReader::new(tc);
+  let ch = response::Stream::chunked(tc, 1);
+  let ct = ContentType::parse_flexible("text/event-stream; charset=utf-8").
+    unwrap();
+  response::content::Content(ct,ch)
+}  
+
+#[get("/<leaf>")]
+fn resource(leaf : CheckedResourceLeaf) -> io::Result<NamedFile> {
+  let template_dir = "templates"; // xxx
+  NamedFile::open(format!("{}/{}", template_dir, leaf.safe))
+}  
+
+fn main() {
+  let helmet = SpaceHelmet::default()
+    .enable(NoSniff::Enable)
+    .enable(Frame::Deny)
+    .enable(Referrer::NoReferrer);
+
+  rocket::ignite()
+    .attach(helmet)
+    .attach(Template::fairing())
+    .mount("/", routes![
+      index,
+      resource,
+      updates,
+    ])
+    .launch();
+}
index bb72ad5b33bf361cd0d1afdc265c85dab2ba32ae..f2cf6f7046c2a2c77a3059a23f77ae0bee26623b 100644 (file)
@@ -1,5 +1,7 @@
 //
 
+// xxx deployment note: need a whole bunch of domains for SSE conn limit
+
 status_node = document.getElementById('spong');
 status_node.innerHTML = 'js-done'