Skip to content

Commit

Permalink
Merge branch 'gzip-encoding'
Browse files Browse the repository at this point in the history
* Branch commit log:
  ui/Makefile.mk: compress all source maps with gzip
  ase/websocket.cc: serve gzip contents if requested and .gz files are on disk
	Note, Firefox, WebKit, Chrome, w3m all request gzip by default.
	Lynx, node, Py-urllib will auto unzip contents even if not requested.
	Wget only unzips contents if it actually requested it via --compress=gzip.
  ase/websocket.cc: recognoize UA for Wget, w3m, Lynx, Python-urllib
  ase/strings: add string_find_word()

Signed-off-by: Tim Janik <[email protected]>
  • Loading branch information
tim-janik committed Jun 8, 2024
2 parents 3309e74 + 21c5640 commit 0c69d0f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 10 deletions.
28 changes: 22 additions & 6 deletions ase/strings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ extern inline unichar totitle (unichar uc) { return g_unichar_totitle (uc);
} // Unicode

// === String ===
static inline bool
c_isalnum (uint8 c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
}

/// Reproduce a string @a s for @a count times.
String
string_multiply (const String &s,
Expand Down Expand Up @@ -509,6 +515,19 @@ strrstr (const char *haystack, const char *needle)
return nullptr;
}

/// Find occurance of `word` in `haystack`.
const char*
string_find_word (const char *haystack, const char *word)
{
return_unless (haystack && word, nullptr);
const size_t l = strlen (word);
// loop over all positions where `word` is found in `haystack`
for (const char *p = strstr (haystack, word); p; p = strstr (p + 1, word))
if ((p == haystack || !c_isalnum (p[-1])) && !c_isalnum (p[l]))
return p;
return nullptr;
}

/// Convert a boolean value into a string.
String
string_from_bool (bool value)
Expand Down Expand Up @@ -856,12 +875,6 @@ string_endswith (const String &string, const StringS &fragments)
return false;
}

static inline bool
c_isalnum (uint8 c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
}

static inline char
identifier_char_canon (char c)
{
Expand Down Expand Up @@ -1774,6 +1787,9 @@ string_tests()
TCMP (string_url_decode ("x%20%2B%20z"), ==, "x + z");
TCMP (string_url_decode ("x+%2B+z"), ==, "x+++z");
TCMP (string_url_decode ("x+%2B+z", true), ==, "x + z");
TASSERT (string_find_word ("mygzip", "gzip") == nullptr);
TASSERT (string_find_word ("gzip2", "gzip") == nullptr);
TASSERT (string_find_word ("mygzip,gzip-2", "gzip") != nullptr);
}

} // Anon
1 change: 1 addition & 0 deletions ase/strings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ typedef std::string String;
// == C-String ==
bool cstring_to_bool (const char *string, bool fallback = false);
const char* strrstr (const char *haystack, const char *needle);
const char* string_find_word (const char *haystack, const char *word);

// == String Formatting ==
template<class... Args> String string_format (const char *format, const Args &...args) ASE_PRINTF (1, 0);
Expand Down
19 changes: 17 additions & 2 deletions ase/websocket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,16 @@ WebSocketConnection::nickname ()
hh = "CR";
else if (Re::search (R"(\bSafari/)", ua) >= 0)
hh = "Sa";
else if (Re::search (R"(\bWget/)", ua) >= 0)
hh = "Wg";
else if (Re::search (R"(\bw3m/)", ua) >= 0)
hh = "W3";
else if (Re::search (R"(\bLynx/)", ua) >= 0)
hh = "Ly";
else if (Re::search (R"(\bPython-urllib/)", ua) >= 0)
hh = "Py";
else
hh = "Uk";
hh = "NA";
internals_.nickname_ = string_format ("%s-%08x:%x", hh, uint32_t (hash ^ (hash >> 32)), info.rport);
}
return internals_.nickname_;
Expand All @@ -357,6 +365,7 @@ WebSocketConnection::http_request ()
{
if (internals_.server->dir_.empty())
return;
Info info = get_info();
WppConnectionP cp = internals_.wppconp();
const auto &parts = string_split (cp->get_resource(), "?");

Expand All @@ -368,8 +377,10 @@ WebSocketConnection::http_request ()
filepath = Path::join (filepath, "index.html");

// serve existing files
const bool canzip = nullptr != string_find_word (info.header ("Accept-Encoding").c_str(), "gzip");
websocketpp::http::status_code::value status;
if (!filepath.empty() && Path::check (filepath, "fr"))
bool fp = false, fz = false;
if (!filepath.empty() && ((fp = Path::check (filepath, "fr")) || (fz = canzip && Path::check (filepath + ".gz", "fr"))))
{
const char *ext = strrchr (filepath.c_str(), '.');
const String mimetype = WebSocketServer::mime_type (ext ? ext + 1 : "", true);
Expand All @@ -391,6 +402,10 @@ WebSocketConnection::http_request ()
cp->append_header ("Cache-Control", "max-age=31536000, public, immutable");
break;
}
if (fz) {
filepath = filepath + ".gz";
cp->append_header ("Content-Encoding", "gzip");
}
Blob blob = Blob::from_file (filepath);
cp->set_body (blob.string());
status = websocketpp::http::status_code::ok;
Expand Down
8 changes: 6 additions & 2 deletions ui/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ ui/public.wildcards ::= $(wildcard \
)

# == ui/lit.js ==
$>/ui/lit.js.map: $>/ui/lit.js ;
$>/ui/lit.js.map.gz: $>/ui/lit.js ;
$>/ui/lit.js: ui/Makefile.mk node_modules/.npm.done | $>/ui/
$(QGEN)
$Q rm -f $>/ui/lit.js* $@
$Q for mod in $(ui/lit.modules) ; do echo "export * from '$$mod';" ; done > $>/ui/lit-all.js
$Q cd $>/ui/ && ../../node_modules/.bin/rollup -p @rollup/plugin-node-resolve lit-all.js -o lit.js --sourcemapFile lit.js.map -m
$Q gzip -f -9 $@.map
$Q $(RM) $>/ui/lit-all.js
$>/.ui-build-stamp: $>/ui/lit.js
ui/lit.modules = $(strip \
Expand All @@ -51,12 +52,13 @@ ui/lit.modules = $(strip \
)

# == ui/signal-polyfill.js ==
$>/ui/signal-polyfill.js.map: $>/ui/signal-polyfill.js ;
$>/ui/signal-polyfill.js.map.gz: $>/ui/signal-polyfill.js ;
$>/ui/signal-polyfill.js: ui/Makefile.mk node_modules/.npm.done | $>/ui/
$(QGEN)
$Q rm -f $>/ui/signal-polyfill.js* $@
$Q for mod in signal-polyfill ; do echo "export * from '$$mod';" ; done > $>/ui/signal-all.js
$Q cd $>/ui/ && ../../node_modules/.bin/rollup -p @rollup/plugin-node-resolve signal-all.js -o $(@F) --sourcemapFile $(@F).map -m
$Q gzip -f -9 $@.map
$Q $(RM) $>/ui/signal-all.js
$>/.ui-build-stamp: $>/ui/signal-polyfill.js

Expand Down Expand Up @@ -222,6 +224,7 @@ $>/ui/global.css: ui/global.scss $(ui/tailwind.inputs) $(ext/ui/b/js.files) ui/s
echo "@import '$$f';" || exit 1 ; done >> $>/ext/imports.scss
$Q POSTCSS_IMPORT_PATH=.:$>/ext \
node_modules/.bin/postcss --config ui < $>/ext/imports.scss -o $>/ext/ui/global.css
$Q gzip -f -9 $>/ext/ui/global.css.map
$Q mv $>/ext/ui/global.css* $(@D)
$>/.ui-reload-stamp: $>/ui/global.css

Expand Down Expand Up @@ -270,6 +273,7 @@ $>/ui/markdown-it.mjs: node_modules/.npm.done | $>/ui/
&& node_modules/.bin/rollup -f es --sourcemap \
-p @rollup/plugin-node-resolve -p "terser={output:{beautify:false}}" \
-o $@ $@.js \
&& gzip -f -9 $@.map \
&& rm -f $@.js
$>/.ui-build-stamp: $>/ui/markdown-it.mjs

Expand Down

0 comments on commit 0c69d0f

Please sign in to comment.