···88888989A comma-separated list of paths to treat as plain text routes
90909191+These patterns do not support regular expressions, but do support the use of `*`
9292+as a wildcard.
9393+9194```dotenv
9292-PLAIN_TEXT_ROUTE=/robots.txt,/license.txt
9595+PLAIN_TEXT_ROUTE=/robots.txt,/license.txt,*.xml
9396```
94979598## `MATHJAX`
+37-1
src/response.rs
···291291 ));
292292293293 if let Ok(plain_texts) = var("PLAIN_TEXT_ROUTE") {
294294- if plain_texts.split(',').any(|r| r == req.path()) {
294294+ if plain_texts.split(',').any(|r| {
295295+ path_matches_pattern(r, req.path())
296296+ || path_matches_pattern(r, req.path().trim_end_matches('/'))
297297+ }) {
295298 return Ok(
296299 HttpResponse::Ok().body(response.content().clone().unwrap_or_default()),
297300 );
···304307 .body(html_context),
305308 )
306309}
310310+311311+fn path_matches_pattern(pattern: &str, path: &str) -> bool {
312312+ let parts: Vec<&str> = pattern.split('*').collect();
313313+ let mut position = 0;
314314+315315+ if !pattern.starts_with('*') {
316316+ if let Some(part) = parts.first() {
317317+ if !path.starts_with(part) {
318318+ return false;
319319+ }
320320+321321+ position = part.len();
322322+ }
323323+ }
324324+325325+ for part in &parts[1..parts.len() - 1] {
326326+ if let Some(found_position) = path[position..].find(part) {
327327+ position += found_position + part.len();
328328+ } else {
329329+ return false;
330330+ }
331331+ }
332332+333333+ if !pattern.ends_with('*') {
334334+ if let Some(part) = parts.last() {
335335+ if !path[position..].ends_with(part) {
336336+ return false;
337337+ }
338338+ }
339339+ }
340340+341341+ true
342342+}