Caching fonts proxy for Googel Fonts
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Did most except the fetching itself


Signed-off-by: MLC Bloeiman <mar@strawmelonjuice.com>

+110 -3
+110 -3
src/fonts.gleam
··· 1 - import gleam/io 1 + import ewe.{type Request, type Response} 2 + import gleam/bit_array 3 + import gleam/bool 4 + import gleam/erlang/process 5 + import gleam/http/response 6 + import gleam/option 7 + import gleam/result 8 + import gleam/string 9 + import simplifile 10 + import woof 11 + 12 + pub fn main() { 13 + // woof.set_sink(woof.beam_logger_sink) 14 + woof.set_sink(woof.default_sink) 15 + 16 + let assert Ok(_) = 17 + ewe.new(handler) 18 + |> ewe.bind("0.0.0.0") 19 + |> ewe.listening(port: 8080) 20 + |> ewe.start 21 + 22 + process.sleep_forever() 23 + } 24 + 25 + fn handler(req: Request) -> Response { 26 + let path_with_query = 27 + req.path 28 + <> { req.query |> option.map(fn(m) { "?" <> m }) |> option.unwrap("") } 29 + 30 + use <- woof.with_context([ 31 + woof.str("path+query", path_with_query), 32 + ]) 33 + woof.info("Incoming request", []) 34 + 35 + let le_error = 36 + response.new(500) 37 + |> response.set_header("content-type", "text/plain; charset=utf-8") 38 + |> response.set_body(ewe.TextData( 39 + "An issue occured. If this keeps happening, open an issue at <https://tangled.org/strawmelonjuice.com/fonts/issues>.", 40 + )) 41 + 42 + use <- bool.lazy_guard( 43 + !{ 44 + string.contains(path_with_query, "fonts.googleapis.com") 45 + |> bool.or(string.contains(path_with_query, "fonts.gstatic.com")) 46 + }, 47 + fn() { 48 + woof.warning("400: Is not a Google Fonts url.", []) 49 + response.new(400) 50 + |> response.set_header("content-type", "text/plain; charset=utf-8") 51 + |> response.set_body(ewe.TextData( 52 + path_with_query <> " is not a Google Fonts url.", 53 + )) 54 + }, 55 + ) 56 + 57 + let item = path_with_query 58 + // An url (and file path) safe version of the request. 59 + let item_id = 60 + bit_array.from_string(item) 61 + |> bit_array.base64_url_encode(False) 2 62 3 - pub fn main() -> Nil { 4 - io.println("Hello from fonts!") 63 + case 64 + simplifile.is_file("./data/" <> item_id <> "/payload"), 65 + simplifile.is_file("./data/" <> item_id <> "/mime") 66 + { 67 + // We cached from last time! 68 + Ok(True), Ok(True) -> { 69 + case simplifile.read("./data/" <> item_id <> "/mime") { 70 + Ok(mime) -> { 71 + case simplifile.read_bits("./data/" <> item_id <> "/payload") { 72 + Ok(payload) -> { 73 + response.new(200) 74 + |> response.set_header("content-type", mime <> "; charset=utf-8") 75 + |> response.set_body(ewe.BitsData(payload)) 76 + } 77 + Error(_) -> { 78 + woof.emergency( 79 + "File system at '" 80 + <> "./data/" 81 + <> item_id 82 + <> "/mime' seems unreachable!", 83 + [], 84 + ) 85 + le_error 86 + } 87 + } 88 + } 89 + Error(_) -> { 90 + woof.emergency( 91 + "File system at '" 92 + <> "./data/" 93 + <> item_id 94 + <> "/mime' seems unreachable!", 95 + [], 96 + ) 97 + le_error 98 + } 99 + } 100 + } 101 + // No cache or no valid cache found, time to see if we can fetch from Google. 102 + Ok(..), Ok(..) -> todo 103 + 104 + _, _ -> { 105 + woof.emergency( 106 + "File system at '" <> "./data/" <> item_id <> "' seems unreachable!", 107 + [], 108 + ) 109 + le_error 110 + } 111 + } 5 112 }