Browse Source

Embed static files in binary

master
Dylan Baker 3 years ago
parent
commit
821164ea31
6 changed files with 84 additions and 10 deletions
  1. 34
    0
      Cargo.lock
  2. 1
    0
      oslo-lib/Cargo.toml
  3. 1
    0
      oslo-lib/src/lib.rs
  4. 2
    2
      oslo-lib/src/middleware.rs
  5. 43
    3
      oslo-lib/src/routes.rs
  6. 3
    5
      oslo-lib/src/templates.rs

+ 34
- 0
Cargo.lock View File

@@ -1008,6 +1008,7 @@ dependencies = [
1008 1008
  "dotenv",
1009 1009
  "lazy_static",
1010 1010
  "pulldown-cmark",
1011
+ "rust-embed",
1011 1012
  "serde",
1012 1013
  "serde_json",
1013 1014
  "tera",
@@ -1245,6 +1246,39 @@ version = "0.2.0"
1245 1246
 source = "registry+https://github.com/rust-lang/crates.io-index"
1246 1247
 checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e"
1247 1248
 
1249
+[[package]]
1250
+name = "rust-embed"
1251
+version = "5.9.0"
1252
+source = "registry+https://github.com/rust-lang/crates.io-index"
1253
+checksum = "2fe1fe6aac5d6bb9e1ffd81002340363272a7648234ec7bdfac5ee202cb65523"
1254
+dependencies = [
1255
+ "rust-embed-impl",
1256
+ "rust-embed-utils",
1257
+ "walkdir",
1258
+]
1259
+
1260
+[[package]]
1261
+name = "rust-embed-impl"
1262
+version = "5.9.0"
1263
+source = "registry+https://github.com/rust-lang/crates.io-index"
1264
+checksum = "3ed91c41c42ef7bf687384439c312e75e0da9c149b0390889b94de3c7d9d9e66"
1265
+dependencies = [
1266
+ "proc-macro2",
1267
+ "quote",
1268
+ "rust-embed-utils",
1269
+ "syn",
1270
+ "walkdir",
1271
+]
1272
+
1273
+[[package]]
1274
+name = "rust-embed-utils"
1275
+version = "5.1.0"
1276
+source = "registry+https://github.com/rust-lang/crates.io-index"
1277
+checksum = "2a512219132473ab0a77b52077059f1c47ce4af7fbdc94503e9862a34422876d"
1278
+dependencies = [
1279
+ "walkdir",
1280
+]
1281
+
1248 1282
 [[package]]
1249 1283
 name = "rustc-demangle"
1250 1284
 version = "0.1.16"

+ 1
- 0
oslo-lib/Cargo.toml View File

@@ -12,6 +12,7 @@ chrono = { version = "0.4", features = ["serde", "rustc-serialize"] }
12 12
 dotenv = "0.15.0"
13 13
 lazy_static = "1.4.0"
14 14
 pulldown-cmark = { version = "0.7", default-features = false }
15
+rust-embed = "5.9.0"
15 16
 serde = "1.0.115"
16 17
 serde_json = "1.0.57"
17 18
 tera = "1.5.0"

+ 1
- 0
oslo-lib/src/lib.rs View File

@@ -29,6 +29,7 @@ pub async fn build_app() -> Result<tide::Server<State>, tide::Error> {
29 29
     app.with(session());
30 30
 
31 31
     app.at("/").get(routes::index);
32
+    app.at("/static/:filename").get(routes::static_file);
32 33
     app.at("/posts")
33 34
         .with(require_auth)
34 35
         .post(routes::create_post);

+ 2
- 2
oslo-lib/src/middleware.rs View File

@@ -61,7 +61,7 @@ pub async fn errors(mut res: Response) -> Result<Response> {
61 61
             } else {
62 62
                 StatusCode::InternalServerError
63 63
             };
64
-            let body: String = templates::render_template("error.html", &context)?;
64
+            let body: String = templates::render_template("error.html", context)?;
65 65
             res.set_body(body);
66 66
             res.set_status(status);
67 67
             res.set_content_type(mime::HTML);
@@ -69,7 +69,7 @@ pub async fn errors(mut res: Response) -> Result<Response> {
69 69
         None => match res.status() {
70 70
             StatusCode::NotFound => {
71 71
                 context.insert("error", "Page not found");
72
-                res.set_body(templates::render_template("error.html", &context)?);
72
+                res.set_body(templates::render_template("error.html", context)?);
73 73
                 res.set_content_type(mime::HTML);
74 74
             }
75 75
             _ => {}

+ 43
- 3
oslo-lib/src/routes.rs View File

@@ -1,8 +1,9 @@
1 1
 use chrono::prelude::Local;
2
+use rust_embed::RustEmbed;
2 3
 use serde::{Deserialize, Serialize};
3 4
 use tera::Context;
4
-use tide::convert::json;
5
-use tide::http::mime;
5
+use tide::{convert::json, http::Mime};
6
+use tide::{http::mime, Body};
6 7
 use tide::{Redirect, Request, Response, Result, StatusCode};
7 8
 
8 9
 use std::env;
@@ -103,6 +104,37 @@ pub async fn logout(mut req: Request<State>) -> Result {
103 104
     Ok(Redirect::new("/").into())
104 105
 }
105 106
 
107
+#[derive(RustEmbed)]
108
+#[folder = "../static"]
109
+struct Asset;
110
+
111
+pub async fn static_file(req: Request<State>) -> Result {
112
+    let filename: String = req.param("filename")?;
113
+    match Asset::get(&filename) {
114
+        Some(file) => {
115
+            let content_type = if filename.ends_with(".css") {
116
+                mime::CSS
117
+            } else if filename.ends_with("js") {
118
+                mime::JAVASCRIPT
119
+            } else if filename.ends_with("otf") {
120
+                mime::Mime::from("font/opentype")
121
+            } else {
122
+                mime::PLAIN
123
+            };
124
+
125
+            render_static_response(file.to_vec(), content_type)
126
+        }
127
+        None => {
128
+            let res = Response::builder(StatusCode::NotFound)
129
+                .body("404 not found")
130
+                .content_type(mime::PLAIN)
131
+                .build();
132
+
133
+            Ok(res)
134
+        }
135
+    }
136
+}
137
+
106 138
 pub fn render_html_response(
107 139
     template: &str,
108 140
     context: &Context,
@@ -115,7 +147,7 @@ pub fn render_html_response(
115 147
     context.insert("login_path", login_path);
116 148
     context.extend(prepare_flash_messages(req));
117 149
 
118
-    let html = render_template(template, &context)?;
150
+    let html = render_template(template, context)?;
119 151
 
120 152
     let res = Response::builder(StatusCode::Ok)
121 153
         .body(html)
@@ -133,6 +165,14 @@ pub fn render_json_response(json: serde_json::Value) -> Result<Response> {
133 165
 
134 166
     Ok(res)
135 167
 }
168
+pub fn render_static_response(contents: Vec<u8>, content_type: Mime) -> Result<Response> {
169
+    let res = Response::builder(StatusCode::Ok)
170
+        .body(Body::from_bytes(contents))
171
+        .content_type(content_type)
172
+        .build();
173
+
174
+    Ok(res)
175
+}
136 176
 
137 177
 fn redirect(path: &str) -> Result<Response> {
138 178
     Ok(Redirect::new(path).into())

+ 3
- 5
oslo-lib/src/templates.rs View File

@@ -4,19 +4,17 @@ use tide::Result;
4 4
 
5 5
 lazy_static! {
6 6
     pub static ref TEMPLATES: Tera = {
7
-        let mut tera = match Tera::new("templates/**/*.html") {
7
+        match Tera::new("templates/**/*.html") {
8 8
             Ok(t) => t,
9 9
             Err(e) => {
10 10
                 println!("Parsing error(s): {}", e);
11 11
                 ::std::process::exit(1);
12 12
             }
13
-        };
14
-        tera.autoescape_on(vec!["html", ".sql"]);
15
-        tera
13
+        }
16 14
     };
17 15
 }
18 16
 
19
-pub fn render_template(template: &str, context: &Context) -> Result<String> {
17
+pub fn render_template(template: &str, context: Context) -> Result<String> {
20 18
     let html = TEMPLATES.render(template, &context)?;
21 19
     Ok(html)
22 20
 }

Loading…
Cancel
Save