diff options
author | BlackDex <[email protected]> | 2022-06-21 18:47:01 +0200 |
---|---|---|
committer | BlackDex <[email protected]> | 2022-06-25 11:29:08 +0200 |
commit | c7a752b01d704c116d715d75f75ff6fa00ab964d (patch) | |
tree | f7fde75ad87286b368aa0fb1ad9e5d294e0570ea /src/api/icons.rs | |
parent | 887e320e7f8dfc62d9b3ed08aca216cd7ad229f1 (diff) | |
download | vaultwarden-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.rs | 47 |
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]) { |