actix web example
1320
Cargo.lock
generated
|
@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0"
|
|||
[workspace]
|
||||
members = [
|
||||
".",
|
||||
"actix-example"
|
||||
"examples/actix-web"
|
||||
]
|
||||
|
||||
[lib]
|
||||
|
|
15
README.md
|
@ -1,8 +1,15 @@
|
|||
<div align="center">
|
||||
<h1>Cache Buster</h1>
|
||||
<img
|
||||
width="250px"
|
||||
class="greetings"
|
||||
src="./examples/actix-web/static/cachable/img/Spock_vulcan-salute.png"
|
||||
alt="logo image"
|
||||
/>
|
||||
<h1>
|
||||
Cache Buster
|
||||
</h1>
|
||||
<p>
|
||||
<strong>cache-buster - A library that aids in static file cache
|
||||
busting with SHA-256 hashes</strong>
|
||||
<strong>May your cache long live and prosper!</strong>
|
||||
</p>
|
||||
|
||||
[![Documentation](https://img.shields.io/badge/docs-master-blue)](https://realaravinth.github.io/cache-buster/cache_buster/index.html)
|
||||
|
@ -46,6 +53,6 @@ cache-buster = { version = "0.2", git = "https://github.com/realaravinth/cache-b
|
|||
|
||||
## Examples:
|
||||
|
||||
- See [acix-example](./actix-example)
|
||||
- See [acix-example](./examples/actix-web)
|
||||
- See [mCaptcha/guard](https://github.com/mCaptcha/guard) for use
|
||||
with [Sailfish](https://crates.io/crates/sailfish) template engine.
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
use cache_buster::Files;
|
||||
use cache_buster::CACHE_BUSTER_DATA_FILE;
|
||||
|
||||
fn main() {
|
||||
let files = Files::new(CACHE_BUSTER_DATA_FILE);
|
||||
|
||||
assert!(get_full_path_runner("../dist/log-out.svg", &files));
|
||||
assert!(get_full_path_runner(
|
||||
"../dist/a/b/c/d/s/d/svg/credit-card.svg",
|
||||
&files
|
||||
));
|
||||
|
||||
assert!(!get_full_path_runner("dist/log-out.svg", &files));
|
||||
assert!(!get_full_path_runner(
|
||||
"dist/a/b/c/d/s/d/svg/credit-card.svg",
|
||||
&files
|
||||
));
|
||||
}
|
||||
|
||||
fn get_full_path_runner(path: &str, files: &Files) -> bool {
|
||||
use std::path::Path;
|
||||
|
||||
if let Some(file) = files.get_full_path(path) {
|
||||
println!("{:?}", files.get(path));
|
||||
Path::new(file).exists()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "actix-example"
|
||||
name = "actix-web"
|
||||
version = "0.1.0"
|
||||
authors = ["realaravinth <realaravinth@batsense.net>"]
|
||||
edition = "2018"
|
||||
|
@ -8,8 +8,18 @@ build = "build.rs"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
cache-buster = { path = "../"}
|
||||
cache-buster = { path = "../../"}
|
||||
actix-web = "4.0.0-beta.8"
|
||||
rust-embed = "5.9.0"
|
||||
lazy_static = "1.4"
|
||||
mime = "0.3.16"
|
||||
pretty_env_logger = "0.4"
|
||||
log = "0.4"
|
||||
mime_guess = "2.0.3"
|
||||
|
||||
[build-dependencies]
|
||||
cache-buster = { path = "../"}
|
||||
cache-buster = { path = "../../"}
|
||||
mime = "0.3.16"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "2"
|
|
@ -6,11 +6,12 @@ fn main() {
|
|||
mime::IMAGE_SVG,
|
||||
mime::IMAGE_JPEG,
|
||||
mime::IMAGE_GIF,
|
||||
mime::TEXT_CSS,
|
||||
];
|
||||
|
||||
let config = BusterBuilder::default()
|
||||
.source("../dist")
|
||||
.result("./prod")
|
||||
.source("./static/cachable/")
|
||||
.result("./dist")
|
||||
.mime_types(types)
|
||||
.copy(true)
|
||||
.follow_links(true)
|
|
@ -0,0 +1,27 @@
|
|||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #22272e;
|
||||
color: #adbac7;
|
||||
max-width: 60%;
|
||||
margin: auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.greetings {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
margin: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.9rem;
|
||||
color: #adbac7;
|
||||
background-color: rgba(205, 217, 229, 0.15);
|
||||
border-radius: 6px;
|
||||
padding: 0.2em 0.4em;
|
||||
}
|
After Width: | Height: | Size: 211 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bell"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
|
After Width: | Height: | Size: 321 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-credit-card"><rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect><line x1="1" y1="10" x2="23" y2="10"></line></svg>
|
After Width: | Height: | Size: 329 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye-off"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
|
After Width: | Height: | Size: 460 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
|
After Width: | Height: | Size: 316 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
|
After Width: | Height: | Size: 473 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
|
After Width: | Height: | Size: 337 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-filter"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon></svg>
|
After Width: | Height: | Size: 290 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-github"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
|
After Width: | Height: | Size: 528 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-globe"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
|
After Width: | Height: | Size: 409 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
After Width: | Height: | Size: 365 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
|
After Width: | Height: | Size: 332 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-log-out"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
After Width: | Height: | Size: 367 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
|
After Width: | Height: | Size: 346 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
After Width: | Height: | Size: 281 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-settings"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
After Width: | Height: | Size: 1,011 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield-off"><path d="M19.69 14a6.9 6.9 0 0 0 .31-2V5l-8-3-3.16 1.18"></path><path d="M4.73 4.73L4 5v7c0 6 8 10 8 10a20.29 20.29 0 0 0 5.62-4.38"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
|
After Width: | Height: | Size: 405 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
|
After Width: | Height: | Size: 279 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tag"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7.01" y2="7"></line></svg>
|
After Width: | Height: | Size: 355 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-toggle-left"><rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="8" cy="12" r="3"></circle></svg>
|
After Width: | Height: | Size: 323 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-toggle-right"><rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="16" cy="12" r="3"></circle></svg>
|
After Width: | Height: | Size: 325 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>
|
After Width: | Height: | Size: 313 B |
1
examples/actix-web/src/cache_buster_data.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"map":{"./static/cachable/svg/file-text.svg":"./dist/svg/file-text.CF57DF252051E7E81C240D36AF1DB8A9DDAF282F9A5E8C338408FE88A6545A02.svg","./static/cachable/svg/credit-card.svg":"./dist/svg/credit-card.DF612AFE367A7B31410F2F6CD3C7B515B0F1889C0107EA695D840DFFA492E07D.svg","./static/cachable/svg/github.svg":"./dist/svg/github.FA9EB1C66F548EC2C7598B94BA6A17275E1EA383D42B6C83351A2388C773E621.svg","./static/cachable/svg/user.svg":"./dist/svg/user.B164ECD2C4A09DC5189F1F252487E2AC6A33646BEA67AF9C528CDA61FE5E146F.svg","./static/cachable/svg/toggle-right.svg":"./dist/svg/toggle-right.15BF49887941593CE3FE09FA73E3CAF1F4B1E8ABCB42A23D85B4FCBC24FDF5AA.svg","./static/cachable/svg/toggle-left.svg":"./dist/svg/toggle-left.E421950C5922E84015F0A86F272AE5637A2ED96E267D2C962543F5994E5D1172.svg","./static/cachable/svg/bell.svg":"./dist/svg/bell.9DA292704EE9907EFDB870F4510C97336977CA27FBFAAD83CF46F8E22D3828F7.svg","./static/cachable/svg/file.svg":"./dist/svg/file.F9E376D9F78FFD918D8D592A8B2D97EAAC14E638B5A7AE3C58DDB075375D8E0E.svg","./static/cachable/svg/shield-off.svg":"./dist/svg/shield-off.85394A6AD92D550F8EBA72AAB095E078E7A0E3359DF81174532C8D1AF53B5876.svg","./static/cachable/svg/eye-off.svg":"./dist/svg/eye-off.939360B335D1D35B57C3E2070129D14ABB168E4AC137B5BE4F6F8BD450B712F5.svg","./static/cachable/svg/log-out.svg":"./dist/svg/log-out.92AB4384FD41D9AFE4735C480361BB64789CD767B7DD0FF3C6F56287B3D4498E.svg","./static/cachable/svg/eye.svg":"./dist/svg/eye.9DE4D24D3C9B055D02B94A8AD65E8C0C644852381FDD131A64448B6DA7859167.svg","./static/cachable/svg/globe.svg":"./dist/svg/globe.44C2A069EBD637663E938ECE7B8E4EC2A8BDE049A8A044EC68D9CB69AE8C592E.svg","./static/cachable/svg/filter.svg":"./dist/svg/filter.6D5FBD96BA2E2020663AAC4994A991295917D73F3592C07EE103647B655A2275.svg","./static/cachable/svg/settings.svg":"./dist/svg/settings.910C6241743C9C694141971BE8E1C4016A1A5BF203E4E9D676D4CE93BD518F4C.svg","./static/cachable/svg/tag.svg":"./dist/svg/tag.E0BC111B8E81BBFC62B6A9E7E4AC162B7085A6543D995B7A0030CB7632901BD4.svg","./static/cachable/svg/moon.svg":"./dist/svg/moon.1E151D68949CA3B2DC7DE34BC25B7586E4175AC3BA7F56DDBB34227334EF7155.svg","./static/cachable/svg/menu.svg":"./dist/svg/menu.A2C4DD00686F5D23F78885AC4CE3E075FCA78DFBDEA70407667FBBD9801B7A75.svg","./static/cachable/img/Spock_vulcan-salute.png":"./dist/img/Spock_vulcan-salute.50BD6BD857160173DDF9A35A751F5755A3ED3B471F1628D5CD0542B635C18068.png","./static/cachable/svg/home.svg":"./dist/svg/home.28C26C2D3E4013D24D755A589A80D8DD5C49DA5397032E3F09B76BC3A2C314ED.svg","./static/cachable/svg/help-circle.svg":"./dist/svg/help-circle.BE230ABD2E05EB05EF6C5B7D04D35A3A43637EF1E046DEF3D244425609B99F81.svg","./static/cachable/svg/shield.svg":"./dist/svg/shield.13AFE15DCB4882B4A940CFDC3E2088A733CD4E6F97F25B211D87C7C9D6DBA2B6.svg","./static/cachable/css/main.css":"./dist/css/main.C9D814A73388500CC43B26842F4EE585CD53535A6EC915A3153DC5107C1FA1C1.css"},"base_dir":"./dist"}
|
67
examples/actix-web/src/index.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
pub fn get_index() -> String {
|
||||
let template = format!(
|
||||
"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<meta name='viewport' content='width=device-width' />
|
||||
<title>Cache buster Actix Web example</title>
|
||||
</head>
|
||||
<body>
|
||||
<img
|
||||
class='greetings'
|
||||
src='{}'
|
||||
alt='logo image'
|
||||
/>
|
||||
<h1>
|
||||
Cache Buster
|
||||
</h1>
|
||||
<h2>
|
||||
May your cache long live and prosper!
|
||||
</h2>
|
||||
|
||||
<h3>What is cache busting?</h3>
|
||||
|
||||
<p>
|
||||
To optimise network load time, browsers cache static files. Caching
|
||||
greatly improves performance but how do you inform browsers to invalidate
|
||||
cache when your files have changed?
|
||||
</p>
|
||||
<p>
|
||||
Cache busting is a simple but effective solution for this issue. There are
|
||||
several ways to achieve this but the way this library does this is by
|
||||
changing file names to include the hash of the files' contents. So if you
|
||||
have <code>bundle.js</code>, it will become
|
||||
<code>bundle.long-sha256-hash.js</code>. This lets you set a super long
|
||||
cache age as, because of the file names changing, the path to the
|
||||
filename, too, will change. So as far as the browser is concerned, you are
|
||||
trying to load a file that it doesn't have.
|
||||
</p>
|
||||
<p>
|
||||
Pretty neat, isn't it?
|
||||
</p>
|
||||
|
||||
<h3>Features</h3>
|
||||
<ul>
|
||||
<li><code>SHA-256</code> based name generation during compile-time</li>
|
||||
<li>Processes files based on provided <code>MIME</code> filters</li>
|
||||
<li>
|
||||
Exposes modified names to program during runtime
|
||||
</li>
|
||||
<li>
|
||||
Route prefixes(optional)
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
<link rel='stylesheet' href='{}' type='text/css' media='all'>
|
||||
</html>",
|
||||
crate::FILES
|
||||
.get_full_path("./static/cachable/img/Spock_vulcan-salute.png")
|
||||
.unwrap(),
|
||||
crate::FILES
|
||||
.get_full_path("./static/cachable/css/main.css")
|
||||
.unwrap()
|
||||
);
|
||||
template
|
||||
}
|
169
examples/actix-web/src/main.rs
Normal file
|
@ -0,0 +1,169 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use actix_web::body::Body;
|
||||
use actix_web::{get, http::header, web, HttpResponse, Responder};
|
||||
use actix_web::{App, HttpServer};
|
||||
use lazy_static::lazy_static;
|
||||
use log::info;
|
||||
use mime_guess::from_path;
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
use cache_buster::Files;
|
||||
|
||||
mod index;
|
||||
pub const CACHE_AGE: u32 = 60 * 60 * 24 * 365;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref FILES: Files = {
|
||||
let map = include_str!("./cache_buster_data.json");
|
||||
Files::new(&map)
|
||||
};
|
||||
pub static ref INDEX: String = index::get_index();
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
std::env::set_var("RUST_LOG", "info");
|
||||
|
||||
let ip = "localhost:2080";
|
||||
crate::FILES
|
||||
.get_full_path("./static/cachable/img/Spock_vulcan-salute.png")
|
||||
.expect("unable to find Spock Vulcan salute image");
|
||||
crate::FILES
|
||||
.get("./static/cachable/css/main.css")
|
||||
.expect("unable to find CSS");
|
||||
|
||||
pretty_env_logger::init();
|
||||
|
||||
info!("Starting server at http://{}", &ip);
|
||||
HttpServer::new(move || {
|
||||
App::new()
|
||||
.wrap(actix_web::middleware::Logger::default())
|
||||
.configure(services)
|
||||
})
|
||||
.bind(ip)
|
||||
.unwrap()
|
||||
.run()
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "dist/"]
|
||||
struct Asset;
|
||||
|
||||
fn handle_assets(path: &str) -> HttpResponse {
|
||||
match Asset::get(path) {
|
||||
Some(content) => {
|
||||
let body: Body = match content {
|
||||
Cow::Borrowed(bytes) => bytes.into(),
|
||||
Cow::Owned(bytes) => bytes.into(),
|
||||
};
|
||||
|
||||
HttpResponse::Ok()
|
||||
.insert_header(header::CacheControl(vec![
|
||||
header::CacheDirective::Public,
|
||||
header::CacheDirective::Extension("immutable".into(), None),
|
||||
header::CacheDirective::MaxAge(CACHE_AGE),
|
||||
]))
|
||||
.content_type(from_path(path).first_or_octet_stream().as_ref())
|
||||
.body(body)
|
||||
}
|
||||
None => HttpResponse::NotFound().body("404 Not Found"),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/dist/{_:.*}")]
|
||||
pub async fn static_files(path: web::Path<String>) -> impl Responder {
|
||||
info!("fetching file: {}", &path);
|
||||
handle_assets(&path)
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
pub async fn serve_index() -> impl Responder {
|
||||
HttpResponse::Ok()
|
||||
.content_type("text/html; charset=utf-8")
|
||||
.body(&*INDEX)
|
||||
}
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "static/no-cache/"]
|
||||
struct Favicons;
|
||||
|
||||
fn handle_favicons(path: &str) -> HttpResponse {
|
||||
match Favicons::get(path) {
|
||||
Some(content) => {
|
||||
let body: Body = match content {
|
||||
Cow::Borrowed(bytes) => bytes.into(),
|
||||
Cow::Owned(bytes) => bytes.into(),
|
||||
};
|
||||
|
||||
HttpResponse::Ok()
|
||||
.insert_header(header::CacheControl(vec![
|
||||
header::CacheDirective::Public,
|
||||
header::CacheDirective::Extension("immutable".into(), None),
|
||||
header::CacheDirective::MaxAge(CACHE_AGE),
|
||||
]))
|
||||
.content_type(from_path(path).first_or_octet_stream().as_ref())
|
||||
.body(body)
|
||||
}
|
||||
None => HttpResponse::NotFound().body("404 Not Found"),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/{file}")]
|
||||
pub async fn favicons(path: web::Path<String>) -> impl Responder {
|
||||
handle_favicons(&path)
|
||||
}
|
||||
|
||||
fn services(cfg: &mut actix_web::web::ServiceConfig) {
|
||||
cfg.service(static_files);
|
||||
cfg.service(serve_index);
|
||||
cfg.service(favicons);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::test;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn static_assets_work() {
|
||||
let mut app = test::init_service(App::new().configure(services)).await;
|
||||
|
||||
let img_resp = test::call_service(
|
||||
&mut app,
|
||||
test::TestRequest::get()
|
||||
.uri(
|
||||
&crate::FILES
|
||||
.get_full_path("./static/cachable/img/Spock_vulcan-salute.png")
|
||||
.unwrap()[1..],
|
||||
)
|
||||
.to_request(),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(img_resp.status(), StatusCode::OK);
|
||||
|
||||
let css_resp = test::call_service(
|
||||
&mut app,
|
||||
test::TestRequest::get()
|
||||
.uri(
|
||||
&crate::FILES
|
||||
.get_full_path("./static/cachable/img/Spock_vulcan-salute.png")
|
||||
.unwrap()[1..],
|
||||
)
|
||||
.to_request(),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(css_resp.status(), StatusCode::OK);
|
||||
|
||||
let favicon_resp = test::call_service(
|
||||
&mut app,
|
||||
test::TestRequest::get().uri("/favicon.ico").to_request(),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(favicon_resp.status(), StatusCode::OK);
|
||||
}
|
||||
}
|
27
examples/actix-web/static/cachable/css/main.css
Normal file
|
@ -0,0 +1,27 @@
|
|||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #22272e;
|
||||
color: #adbac7;
|
||||
max-width: 60%;
|
||||
margin: auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.greetings {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
margin: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.9rem;
|
||||
color: #adbac7;
|
||||
background-color: rgba(205, 217, 229, 0.15);
|
||||
border-radius: 6px;
|
||||
padding: 0.2em 0.4em;
|
||||
}
|
BIN
examples/actix-web/static/cachable/img/Spock_vulcan-salute.png
Normal file
After Width: | Height: | Size: 211 KiB |
55
examples/actix-web/static/cachable/index.html
Normal file
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Cache buster Actix Web example</title>
|
||||
</head>
|
||||
<body>
|
||||
<img
|
||||
class="greetings"
|
||||
src="./img/Spock_vulcan-salute.png"
|
||||
alt="logo image"
|
||||
/>
|
||||
<h1>
|
||||
Cache Buster
|
||||
</h1>
|
||||
<h2>
|
||||
May your cache long live and prosper!
|
||||
</h2>
|
||||
|
||||
<h3>What is cache busting?</h3>
|
||||
|
||||
<p>
|
||||
To optimise network load time, browsers cache static files. Caching
|
||||
greatly improves performance but how do you inform browsers to invalidate
|
||||
cache when your files have changed?
|
||||
</p>
|
||||
<p>
|
||||
Cache busting is a simple but effective solution for this issue. There are
|
||||
several ways to achieve this but the way this library does this is by
|
||||
changing file names to include the hash of the files' contents. So if you
|
||||
have <code>bundle.js</code>, it will become
|
||||
<code>bundle.long-sha256-hash.js</code>. This lets you set a super long
|
||||
cache age as, because of the file names changing, the path to the
|
||||
filename, too, will change. So as far as the browser is concerned, you are
|
||||
trying to load a file that it doesn't have.
|
||||
</p>
|
||||
<p>
|
||||
Pretty neat, isn't it?
|
||||
</p>
|
||||
|
||||
<h3>Features</h3>
|
||||
<ul>
|
||||
<li><code>SHA-256</code> based name generation during compile-time</li>
|
||||
<li>Processes files based on provided <code>MIME</code> filters</li>
|
||||
<li>
|
||||
Exposes modified names to program during runtime
|
||||
</li>
|
||||
<li>
|
||||
Route prefixes(optional)
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
<link rel="stylesheet" href="./css/main.css" type="text/css" media="all">
|
||||
</html>
|
1
examples/actix-web/static/cachable/svg/bell.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bell"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
|
After Width: | Height: | Size: 321 B |
1
examples/actix-web/static/cachable/svg/credit-card.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-credit-card"><rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect><line x1="1" y1="10" x2="23" y2="10"></line></svg>
|
After Width: | Height: | Size: 329 B |
1
examples/actix-web/static/cachable/svg/eye-off.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye-off"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
|
After Width: | Height: | Size: 460 B |
1
examples/actix-web/static/cachable/svg/eye.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
|
After Width: | Height: | Size: 316 B |
1
examples/actix-web/static/cachable/svg/file-text.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
|
After Width: | Height: | Size: 473 B |
1
examples/actix-web/static/cachable/svg/file.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
|
After Width: | Height: | Size: 337 B |
1
examples/actix-web/static/cachable/svg/filter.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-filter"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon></svg>
|
After Width: | Height: | Size: 290 B |
1
examples/actix-web/static/cachable/svg/github.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-github"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>
|
After Width: | Height: | Size: 528 B |
1
examples/actix-web/static/cachable/svg/globe.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-globe"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
|
After Width: | Height: | Size: 409 B |
1
examples/actix-web/static/cachable/svg/help-circle.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
After Width: | Height: | Size: 365 B |
1
examples/actix-web/static/cachable/svg/home.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
|
After Width: | Height: | Size: 332 B |
1
examples/actix-web/static/cachable/svg/log-out.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-log-out"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
After Width: | Height: | Size: 367 B |
1
examples/actix-web/static/cachable/svg/menu.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
|
After Width: | Height: | Size: 346 B |
1
examples/actix-web/static/cachable/svg/moon.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
After Width: | Height: | Size: 281 B |
1
examples/actix-web/static/cachable/svg/settings.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-settings"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
After Width: | Height: | Size: 1,011 B |
1
examples/actix-web/static/cachable/svg/shield-off.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield-off"><path d="M19.69 14a6.9 6.9 0 0 0 .31-2V5l-8-3-3.16 1.18"></path><path d="M4.73 4.73L4 5v7c0 6 8 10 8 10a20.29 20.29 0 0 0 5.62-4.38"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
|
After Width: | Height: | Size: 405 B |
1
examples/actix-web/static/cachable/svg/shield.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
|
After Width: | Height: | Size: 279 B |
1
examples/actix-web/static/cachable/svg/tag.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tag"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7.01" y2="7"></line></svg>
|
After Width: | Height: | Size: 355 B |
1
examples/actix-web/static/cachable/svg/toggle-left.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-toggle-left"><rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="8" cy="12" r="3"></circle></svg>
|
After Width: | Height: | Size: 323 B |
1
examples/actix-web/static/cachable/svg/toggle-right.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-toggle-right"><rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="16" cy="12" r="3"></circle></svg>
|
After Width: | Height: | Size: 325 B |
1
examples/actix-web/static/cachable/svg/user.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>
|
After Width: | Height: | Size: 313 B |
BIN
examples/actix-web/static/no-cache/favicon-16x16.png
Normal file
After Width: | Height: | Size: 616 B |
BIN
examples/actix-web/static/no-cache/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/actix-web/static/no-cache/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |