aboutsummaryrefslogtreecommitdiff
path: root/src/api/icons.rs
diff options
context:
space:
mode:
authorBlackDex <[email protected]>2022-06-21 18:47:01 +0200
committerBlackDex <[email protected]>2022-06-25 11:29:08 +0200
commitc7a752b01d704c116d715d75f75ff6fa00ab964d (patch)
treef7fde75ad87286b368aa0fb1ad9e5d294e0570ea /src/api/icons.rs
parent887e320e7f8dfc62d9b3ed08aca216cd7ad229f1 (diff)
downloadvaultwarden-c7a752b01d704c116d715d75f75ff6fa00ab964d.tar.gz
vaultwarden-c7a752b01d704c116d715d75f75ff6fa00ab964d.zip
Update dep's and small improvements on favicons
- Updated dependencies (html5gum for favicon downloading) * Also openssl, time, jsonwebtoken and r2d2 - Small optimizations on downloading favicons. It now only emits tokens/tags which needs to be parsed, all others are being skipped. This prevents unneeded items within the for-loop being parsed.
Diffstat (limited to 'src/api/icons.rs')
-rw-r--r--src/api/icons.rs47
1 files changed, 34 insertions, 13 deletions
diff --git a/src/api/icons.rs b/src/api/icons.rs
index dc27d13a..90d306fb 100644
--- a/src/api/icons.rs
+++ b/src/api/icons.rs
@@ -19,7 +19,7 @@ use tokio::{
net::lookup_host,
};
-use html5gum::{Emitter, EndTag, InfallibleTokenizer, Readable, StartTag, StringReader, Tokenizer};
+use html5gum::{Emitter, EndTag, HtmlString, InfallibleTokenizer, Readable, StartTag, StringReader, Tokenizer};
use crate::{
error::Error,
@@ -433,7 +433,7 @@ async fn get_favicons_node(
for token in dom {
match token {
FaviconToken::StartTag(tag) => {
- if tag.name == TAG_LINK
+ if *tag.name == TAG_LINK
&& tag.attributes.contains_key(ATTR_REL)
&& tag.attributes.contains_key(ATTR_HREF)
{
@@ -443,7 +443,7 @@ async fn get_favicons_node(
if rel_value.contains("icon") && !rel_value.contains("mask-icon") {
icon_tags.push(tag);
}
- } else if tag.name == TAG_BASE && tag.attributes.contains_key(ATTR_HREF) {
+ } else if *tag.name == TAG_BASE && tag.attributes.contains_key(ATTR_HREF) {
let href = std::str::from_utf8(tag.attributes.get(ATTR_HREF).unwrap()).unwrap_or_default();
debug!("Found base href: {href}");
base_url = match base_url.join(href) {
@@ -453,7 +453,7 @@ async fn get_favicons_node(
}
}
FaviconToken::EndTag(tag) => {
- if tag.name == TAG_HEAD {
+ if *tag.name == TAG_HEAD {
break;
}
}
@@ -830,17 +830,18 @@ impl reqwest::cookie::CookieStore for Jar {
/// Therefor parsing the HTML content is faster.
use std::collections::{BTreeSet, VecDeque};
+#[derive(Debug)]
enum FaviconToken {
StartTag(StartTag),
EndTag(EndTag),
}
-#[derive(Default)]
+#[derive(Default, Debug)]
struct FaviconEmitter {
current_token: Option<FaviconToken>,
- last_start_tag: Vec<u8>,
- current_attribute: Option<(Vec<u8>, Vec<u8>)>,
- seen_attributes: BTreeSet<Vec<u8>>,
+ last_start_tag: HtmlString,
+ current_attribute: Option<(HtmlString, HtmlString)>,
+ seen_attributes: BTreeSet<HtmlString>,
emitted_tokens: VecDeque<FaviconToken>,
}
@@ -887,18 +888,38 @@ impl Emitter for FaviconEmitter {
self.seen_attributes.clear();
}
- fn emit_current_tag(&mut self) {
+ fn emit_current_tag(&mut self) -> Option<html5gum::State> {
self.flush_current_attribute();
let mut token = self.current_token.take().unwrap();
+ let mut emit = false;
match token {
- FaviconToken::EndTag(_) => {
+ FaviconToken::EndTag(ref mut tag) => {
+ // Always clean seen attributes
self.seen_attributes.clear();
+
+ // Only trigger an emit for the </head> tag.
+ // This is matched, and will break the for-loop.
+ if *tag.name == b"head" {
+ emit = true;
+ }
}
FaviconToken::StartTag(ref mut tag) => {
- self.set_last_start_tag(Some(&tag.name));
+ // Only trriger an emit for <link> and <base> tags.
+ // These are the only tags we want to parse.
+ if *tag.name == b"link" || *tag.name == b"base" {
+ self.set_last_start_tag(Some(&tag.name));
+ emit = true;
+ } else {
+ self.set_last_start_tag(None);
+ }
}
}
- self.emit_token(token);
+
+ // Only emit the tags we want to parse.
+ if emit {
+ self.emit_token(token);
+ }
+ None
}
fn push_tag_name(&mut self, s: &[u8]) {
@@ -921,7 +942,7 @@ impl Emitter for FaviconEmitter {
fn init_attribute(&mut self) {
self.flush_current_attribute();
- self.current_attribute = Some((Vec::new(), Vec::new()));
+ self.current_attribute = Some(Default::default());
}
fn push_attribute_name(&mut self, s: &[u8]) {