clippy: fix warnings in components/net (#31564)

* clippy: fix some warnings in components/net

* fix: review comments

* fix: tidy
This commit is contained in:
eri 2024-03-10 16:34:16 +01:00 committed by GitHub
parent 099bb0fa19
commit 67b277c992
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 325 additions and 379 deletions

View file

@ -54,7 +54,7 @@ impl Service<Destination> for ServoHttpConnector {
let authority = if let Some(port) = auth.port() { let authority = if let Some(port) = auth.port() {
format!("{}:{}", host, port.as_str()) format!("{}:{}", host, port.as_str())
} else { } else {
format!("{}", &*host) (*host).to_string()
}; };
if let Ok(authority) = Authority::from_maybe_shared(authority) { if let Ok(authority) = Authority::from_maybe_shared(authority) {

View file

@ -106,8 +106,8 @@ impl Cookie {
"" ""
}) })
.to_owned(); .to_owned();
if path.chars().next() != Some('/') { if !path.starts_with('/') {
path = Cookie::default_path(&request.path().to_owned()).to_string(); path = Cookie::default_path(request.path()).to_string();
} }
cookie.set_path(path); cookie.set_path(path);
@ -152,12 +152,12 @@ impl Cookie {
// http://tools.ietf.org/html/rfc6265#section-5.1.4 // http://tools.ietf.org/html/rfc6265#section-5.1.4
pub fn default_path(request_path: &str) -> &str { pub fn default_path(request_path: &str) -> &str {
// Step 2 // Step 2
if request_path.chars().next() != Some('/') { if !request_path.starts_with('/') {
return "/"; return "/";
} }
// Step 3 // Step 3
let rightmost_slash_idx = request_path.rfind("/").unwrap(); let rightmost_slash_idx = request_path.rfind('/').unwrap();
if rightmost_slash_idx == 0 { if rightmost_slash_idx == 0 {
// There's only one slash; it's the first character // There's only one slash; it's the first character
return "/"; return "/";
@ -178,11 +178,11 @@ impl Cookie {
( (
// The cookie-path is a prefix of the request-path, and the last // The cookie-path is a prefix of the request-path, and the last
// character of the cookie-path is %x2F ("/"). // character of the cookie-path is %x2F ("/").
cookie_path.ends_with("/") || cookie_path.ends_with('/') ||
// The cookie-path is a prefix of the request-path, and the first // The cookie-path is a prefix of the request-path, and the first
// character of the request-path that is not included in the cookie- // character of the request-path that is not included in the cookie-
// path is a %x2F ("/") character. // path is a %x2F ("/") character.
request_path[cookie_path.len()..].starts_with("/") request_path[cookie_path.len()..].starts_with('/')
)) ))
} }
@ -205,15 +205,13 @@ impl Cookie {
if self.cookie.domain() != domain { if self.cookie.domain() != domain {
return false; return false;
} }
} else { } else if let (Some(domain), Some(cookie_domain)) = (domain, &self.cookie.domain()) {
if let (Some(domain), &Some(ref cookie_domain)) = (domain, &self.cookie.domain()) {
if !Cookie::domain_match(domain, cookie_domain) { if !Cookie::domain_match(domain, cookie_domain) {
return false; return false;
} }
} }
}
if let Some(ref cookie_path) = self.cookie.path() { if let Some(cookie_path) = self.cookie.path() {
if !Cookie::path_match(url.path(), cookie_path) { if !Cookie::path_match(url.path(), cookie_path) {
return false; return false;
} }

View file

@ -42,7 +42,7 @@ impl CookieStorage {
source: CookieSource, source: CookieSource,
) -> Result<Option<Cookie>, ()> { ) -> Result<Option<Cookie>, ()> {
let domain = reg_host(cookie.cookie.domain().as_ref().unwrap_or(&"")); let domain = reg_host(cookie.cookie.domain().as_ref().unwrap_or(&""));
let cookies = self.cookies_map.entry(domain).or_insert(vec![]); let cookies = self.cookies_map.entry(domain).or_default();
// https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 2 // https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt Step 2
if !cookie.cookie.secure().unwrap_or(false) && !url.is_secure_scheme() { if !cookie.cookie.secure().unwrap_or(false) && !url.is_secure_scheme() {
@ -90,7 +90,7 @@ impl CookieStorage {
} }
pub fn clear_storage(&mut self, url: &ServoUrl) { pub fn clear_storage(&mut self, url: &ServoUrl) {
let domain = reg_host(url.host_str().unwrap_or("")); let domain = reg_host(url.host_str().unwrap_or(""));
let cookies = self.cookies_map.entry(domain).or_insert(vec![]); let cookies = self.cookies_map.entry(domain).or_default();
for cookie in cookies.iter_mut() { for cookie in cookies.iter_mut() {
cookie.set_expiry_time_negative(); cookie.set_expiry_time_negative();
} }
@ -116,12 +116,12 @@ impl CookieStorage {
} }
// Step 12 // Step 12
let domain = reg_host(&cookie.cookie.domain().as_ref().unwrap_or(&"")); let domain = reg_host(cookie.cookie.domain().as_ref().unwrap_or(&""));
let cookies = self.cookies_map.entry(domain).or_insert(vec![]); let cookies = self.cookies_map.entry(domain).or_default();
if cookies.len() == self.max_per_host { if cookies.len() == self.max_per_host {
let old_len = cookies.len(); let old_len = cookies.len();
cookies.retain(|c| !is_cookie_expired(&c)); cookies.retain(|c| !is_cookie_expired(c));
let new_len = cookies.len(); let new_len = cookies.len();
// https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt // https://www.ietf.org/id/draft-ietf-httpbis-cookie-alone-01.txt
@ -153,8 +153,8 @@ impl CookieStorage {
let domain = reg_host(url.host_str().unwrap_or("")); let domain = reg_host(url.host_str().unwrap_or(""));
if let Entry::Occupied(mut entry) = self.cookies_map.entry(domain) { if let Entry::Occupied(mut entry) = self.cookies_map.entry(domain) {
let cookies = entry.get_mut(); let cookies = entry.get_mut();
cookies.retain(|c| !is_cookie_expired(&c)); cookies.retain(|c| !is_cookie_expired(c));
if cookies.len() == 0 { if cookies.is_empty() {
entry.remove_entry(); entry.remove_entry();
} }
} }
@ -179,10 +179,10 @@ impl CookieStorage {
}; };
// Step 2 // Step 2
let domain = reg_host(url.host_str().unwrap_or("")); let domain = reg_host(url.host_str().unwrap_or(""));
let cookies = self.cookies_map.entry(domain).or_insert(vec![]); let cookies = self.cookies_map.entry(domain).or_default();
let mut url_cookies: Vec<&mut Cookie> = cookies.iter_mut().filter(filterer).collect(); let mut url_cookies: Vec<&mut Cookie> = cookies.iter_mut().filter(filterer).collect();
url_cookies.sort_by(|a, b| CookieStorage::cookie_comparator(*a, *b)); url_cookies.sort_by(|a, b| CookieStorage::cookie_comparator(a, b));
let reducer = |acc: String, c: &mut &mut Cookie| -> String { let reducer = |acc: String, c: &mut &mut Cookie| -> String {
// Step 3 // Step 3
@ -211,7 +211,7 @@ impl CookieStorage {
source: CookieSource, source: CookieSource,
) -> impl Iterator<Item = cookie_rs::Cookie<'static>> + 'a { ) -> impl Iterator<Item = cookie_rs::Cookie<'static>> + 'a {
let domain = reg_host(url.host_str().unwrap_or("")); let domain = reg_host(url.host_str().unwrap_or(""));
let cookies = self.cookies_map.entry(domain).or_insert(vec![]); let cookies = self.cookies_map.entry(domain).or_default();
cookies cookies
.iter_mut() .iter_mut()
@ -223,7 +223,7 @@ impl CookieStorage {
} }
} }
fn reg_host<'a>(url: &'a str) -> String { fn reg_host(url: &str) -> String {
reg_suffix(url).to_lowercase() reg_suffix(url).to_lowercase()
} }
@ -250,7 +250,7 @@ fn evict_one_cookie(is_secure_cookie: bool, cookies: &mut Vec<Cookie>) -> bool {
cookies.remove(index); cookies.remove(index);
} }
} }
return true; true
} }
fn get_oldest_accessed(is_secure_cookie: bool, cookies: &mut Vec<Cookie>) -> Option<(usize, Tm)> { fn get_oldest_accessed(is_secure_cookie: bool, cookies: &mut Vec<Cookie>) -> Option<(usize, Tm)> {

View file

@ -130,7 +130,7 @@ impl Decoder {
Decoder { Decoder {
inner: Inner::Pending(Pending { inner: Inner::Pending(Pending {
body: ReadableChunks::new(body), body: ReadableChunks::new(body),
type_: type_, type_,
}), }),
} }
} }
@ -222,7 +222,7 @@ impl Gzip {
Gzip { Gzip {
buf: BytesMut::with_capacity(INIT_BUFFER_SIZE), buf: BytesMut::with_capacity(INIT_BUFFER_SIZE),
inner: Box::new(gzip::Decoder::new(Peeked::new(stream))), inner: Box::new(gzip::Decoder::new(Peeked::new(stream))),
reader: reader, reader,
} }
} }
} }
@ -286,7 +286,7 @@ impl Brotli {
Self { Self {
buf: BytesMut::with_capacity(INIT_BUFFER_SIZE), buf: BytesMut::with_capacity(INIT_BUFFER_SIZE),
inner: Box::new(Decompressor::new(Peeked::new(stream), BUF_SIZE)), inner: Box::new(Decompressor::new(Peeked::new(stream), BUF_SIZE)),
reader: reader, reader,
} }
} }
} }
@ -318,7 +318,7 @@ impl Deflate {
Self { Self {
buf: BytesMut::with_capacity(INIT_BUFFER_SIZE), buf: BytesMut::with_capacity(INIT_BUFFER_SIZE),
inner: Box::new(DeflateDecoder::new(Peeked::new(stream))), inner: Box::new(DeflateDecoder::new(Peeked::new(stream))),
reader: reader, reader,
} }
} }
} }
@ -382,7 +382,7 @@ impl<R> Peeked<R> {
Peeked { Peeked {
state: PeekedState::NotReady, state: PeekedState::NotReady,
peeked_buf: [0; 10], peeked_buf: [0; 10],
inner: inner, inner,
pos: 0, pos: 0,
} }
} }
@ -418,10 +418,10 @@ impl<R: Read> Read for Peeked<R> {
return Ok(len); return Ok(len);
}, },
PeekedState::NotReady => { PeekedState::NotReady => {
let mut buf = &mut self.peeked_buf[self.pos..]; let buf = &mut self.peeked_buf[self.pos..];
let stream = self.inner.clone(); let stream = self.inner.clone();
let mut reader = stream.lock().unwrap(); let mut reader = stream.lock().unwrap();
let read = reader.read(&mut buf); let read = reader.read(buf);
match read { match read {
Ok(0) => self.ready(), Ok(0) => self.ready(),
@ -444,7 +444,7 @@ impl<S> ReadableChunks<S> {
fn new(stream: S) -> Self { fn new(stream: S) -> Self {
ReadableChunks { ReadableChunks {
state: ReadState::NotReady, state: ReadState::NotReady,
stream: stream, stream,
waker: None, waker: None,
} }
} }

View file

@ -60,11 +60,11 @@ impl CorsCacheEntry {
header_or_method: HeaderOrMethod, header_or_method: HeaderOrMethod,
) -> CorsCacheEntry { ) -> CorsCacheEntry {
CorsCacheEntry { CorsCacheEntry {
origin: origin, origin,
url: url, url,
max_age: max_age, max_age,
credentials: credentials, credentials,
header_or_method: header_or_method, header_or_method,
created: time::now().to_timespec(), created: time::now().to_timespec(),
} }
} }
@ -77,14 +77,10 @@ fn match_headers(cors_cache: &CorsCacheEntry, cors_req: &Request) -> bool {
} }
/// A simple, vector-based CORS Cache /// A simple, vector-based CORS Cache
#[derive(Clone)] #[derive(Clone, Default)]
pub struct CorsCache(Vec<CorsCacheEntry>); pub struct CorsCache(Vec<CorsCacheEntry>);
impl CorsCache { impl CorsCache {
pub fn new() -> CorsCache {
CorsCache(vec![])
}
fn find_entry_by_header<'a>( fn find_entry_by_header<'a>(
&'a mut self, &'a mut self,
request: &Request, request: &Request,
@ -122,7 +118,7 @@ impl CorsCache {
/// Returns true if an entry with a /// Returns true if an entry with a
/// [matching header](https://fetch.spec.whatwg.org/#concept-cache-match-header) is found /// [matching header](https://fetch.spec.whatwg.org/#concept-cache-match-header) is found
pub fn match_header(&mut self, request: &Request, header_name: &HeaderName) -> bool { pub fn match_header(&mut self, request: &Request, header_name: &HeaderName) -> bool {
self.find_entry_by_header(&request, header_name).is_some() self.find_entry_by_header(request, header_name).is_some()
} }
/// Updates max age if an entry for a /// Updates max age if an entry for a
@ -136,7 +132,7 @@ impl CorsCache {
new_max_age: u32, new_max_age: u32,
) -> bool { ) -> bool {
match self match self
.find_entry_by_header(&request, header_name) .find_entry_by_header(request, header_name)
.map(|e| e.max_age = new_max_age) .map(|e| e.max_age = new_max_age)
{ {
Some(_) => true, Some(_) => true,
@ -156,7 +152,7 @@ impl CorsCache {
/// Returns true if an entry with a /// Returns true if an entry with a
/// [matching method](https://fetch.spec.whatwg.org/#concept-cache-match-method) is found /// [matching method](https://fetch.spec.whatwg.org/#concept-cache-match-method) is found
pub fn match_method(&mut self, request: &Request, method: Method) -> bool { pub fn match_method(&mut self, request: &Request, method: Method) -> bool {
self.find_entry_by_method(&request, method).is_some() self.find_entry_by_method(request, method).is_some()
} }
/// Updates max age if an entry for /// Updates max age if an entry for
@ -170,7 +166,7 @@ impl CorsCache {
new_max_age: u32, new_max_age: u32,
) -> bool { ) -> bool {
match self match self
.find_entry_by_method(&request, method.clone()) .find_entry_by_method(request, method.clone())
.map(|e| e.max_age = new_max_age) .map(|e| e.max_age = new_max_age)
{ {
Some(_) => true, Some(_) => true,

View file

@ -17,14 +17,14 @@ pub fn determine_nosniff(headers: &HeaderMap) -> bool {
match values { match values {
None => false, None => false,
Some(values) => !values.is_empty() && (&values[0]).eq_ignore_ascii_case("nosniff"), Some(values) => !values.is_empty() && values[0].eq_ignore_ascii_case("nosniff"),
} }
} }
/// <https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split> /// <https://fetch.spec.whatwg.org/#concept-header-list-get-decode-split>
fn get_header_value_as_list(name: &str, headers: &HeaderMap) -> Option<Vec<String>> { fn get_header_value_as_list(name: &str, headers: &HeaderMap) -> Option<Vec<String>> {
fn char_is_not_quote_or_comma(c: char) -> bool { fn char_is_not_quote_or_comma(c: char) -> bool {
return c != '\u{0022}' && c != '\u{002C}'; c != '\u{0022}' && c != '\u{002C}'
} }
// Step 1 // Step 1
@ -33,7 +33,7 @@ fn get_header_value_as_list(name: &str, headers: &HeaderMap) -> Option<Vec<Strin
if let Some(input) = initial_value { if let Some(input) = initial_value {
// https://fetch.spec.whatwg.org/#header-value-get-decode-and-split // https://fetch.spec.whatwg.org/#header-value-get-decode-and-split
// Step 1 // Step 1
let input = input.into_iter().map(|u| char::from(u)).collect::<String>(); let input = input.into_iter().map(char::from).collect::<String>();
// Step 2 // Step 2
let mut position = input.chars().peekable(); let mut position = input.chars().peekable();
@ -81,7 +81,7 @@ fn get_header_value_as_list(name: &str, headers: &HeaderMap) -> Option<Vec<Strin
} }
// Step 2 // Step 2
return None; None
} }
/// <https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points> /// <https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points>
@ -102,13 +102,13 @@ where
} }
// Step 3 // Step 3
return result; result
} }
/// <https://fetch.spec.whatwg.org/#collect-an-http-quoted-string> /// <https://fetch.spec.whatwg.org/#collect-an-http-quoted-string>
fn collect_http_quoted_string(position: &mut Peekable<Chars>, extract_value: bool) -> String { fn collect_http_quoted_string(position: &mut Peekable<Chars>, extract_value: bool) -> String {
fn char_is_not_quote_or_backslash(c: char) -> bool { fn char_is_not_quote_or_backslash(c: char) -> bool {
return c != '\u{0022}' && c != '\u{005C}'; c != '\u{0022}' && c != '\u{005C}'
} }
// Step 2 // Step 2
@ -159,5 +159,5 @@ fn collect_http_quoted_string(position: &mut Peekable<Chars>, extract_value: boo
} }
// Step 6, 7 // Step 6, 7
return value; value
} }

View file

@ -84,7 +84,7 @@ pub struct CancellationListener {
impl CancellationListener { impl CancellationListener {
pub fn new(cancel_chan: Option<IpcReceiver<()>>) -> Self { pub fn new(cancel_chan: Option<IpcReceiver<()>>) -> Self {
Self { Self {
cancel_chan: cancel_chan, cancel_chan,
cancelled: false, cancelled: false,
} }
} }
@ -121,7 +121,7 @@ pub async fn fetch(request: &mut Request, target: Target<'_>, context: &FetchCon
.unwrap() .unwrap()
.set_attribute(ResourceAttribute::StartTime(ResourceTimeValue::FetchStart)); .set_attribute(ResourceAttribute::StartTime(ResourceTimeValue::FetchStart));
fetch_with_cors_cache(request, &mut CorsCache::new(), target, context).await; fetch_with_cors_cache(request, &mut CorsCache::default(), target, context).await;
} }
pub async fn fetch_with_cors_cache( pub async fn fetch_with_cors_cache(
@ -161,7 +161,7 @@ pub async fn fetch_with_cors_cache(
} }
// Step 8. // Step 8.
main_fetch(request, cache, false, false, target, &mut None, &context).await; main_fetch(request, cache, false, false, target, &mut None, context).await;
} }
/// <https://www.w3.org/TR/CSP/#should-block-request> /// <https://www.w3.org/TR/CSP/#should-block-request>
@ -209,16 +209,16 @@ pub async fn main_fetch(
} }
// Step 2. // Step 2.
if request.local_urls_only { if request.local_urls_only &&
if !matches!( !matches!(
request.current_url().scheme(), request.current_url().scheme(),
"about" | "blob" | "data" | "filesystem" "about" | "blob" | "data" | "filesystem"
) { )
{
response = Some(Response::network_error(NetworkError::Internal( response = Some(Response::network_error(NetworkError::Internal(
"Non-local scheme".into(), "Non-local scheme".into(),
))); )));
} }
}
// Step 2.2. // Step 2.2.
// TODO: Report violations. // TODO: Report violations.
@ -267,7 +267,7 @@ pub async fn main_fetch(
) )
}, },
}; };
request.referrer = referrer_url.map_or(Referrer::NoReferrer, |url| Referrer::ReferrerUrl(url)); request.referrer = referrer_url.map_or(Referrer::NoReferrer, Referrer::ReferrerUrl);
// Step 9. // Step 9.
// TODO: handle FTP URLs. // TODO: handle FTP URLs.
@ -451,7 +451,7 @@ pub async fn main_fetch(
*body = ResponseBody::Empty; *body = ResponseBody::Empty;
} }
internal_response.get_network_error().map(|e| e.clone()) internal_response.get_network_error().cloned()
}; };
// Execute deferred rebinding of response. // Execute deferred rebinding of response.
@ -469,7 +469,7 @@ pub async fn main_fetch(
response_loaded = true; response_loaded = true;
// Step 19.2. // Step 19.2.
let ref integrity_metadata = &request.integrity_metadata; let integrity_metadata = &request.integrity_metadata;
if response.termination_reason.is_none() && if response.termination_reason.is_none() &&
!is_response_integrity_valid(integrity_metadata, &response) !is_response_integrity_valid(integrity_metadata, &response)
{ {
@ -502,8 +502,8 @@ pub async fn main_fetch(
// in http_network_fetch. However, we can't yet follow the request // in http_network_fetch. However, we can't yet follow the request
// upload progress, so I'm keeping it here for now and pretending // upload progress, so I'm keeping it here for now and pretending
// the body got sent in one chunk // the body got sent in one chunk
target.process_request_body(&request); target.process_request_body(request);
target.process_request_eof(&request); target.process_request_eof(request);
} }
// Step 22. // Step 22.
@ -518,7 +518,7 @@ pub async fn main_fetch(
target.process_response_eof(&response); target.process_response_eof(&response);
if let Ok(http_cache) = context.state.http_cache.write() { if let Ok(http_cache) = context.state.http_cache.write() {
http_cache.update_awaiting_consumers(&request, &response); http_cache.update_awaiting_consumers(request, &response);
} }
// Steps 25-27. // Steps 25-27.

View file

@ -5,7 +5,6 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fs::File; use std::fs::File;
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom};
use std::mem;
use std::ops::Index; use std::ops::Index;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; use std::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering};
@ -103,13 +102,12 @@ impl FileManager {
let store = self.store.clone(); let store = self.store.clone();
self.thread_pool self.thread_pool
.upgrade() .upgrade()
.and_then(|pool| { .map(|pool| {
pool.spawn(move || { pool.spawn(move || {
if let Err(e) = store.try_read_file(&sender, id, origin) { if let Err(e) = store.try_read_file(&sender, id, origin) {
let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e))); let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e)));
} }
}); });
Some(())
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
warn!("FileManager tried to read a file after CoreResourceManager has exited."); warn!("FileManager tried to read a file after CoreResourceManager has exited.");
@ -160,11 +158,10 @@ impl FileManager {
let embedder = self.embedder_proxy.clone(); let embedder = self.embedder_proxy.clone();
self.thread_pool self.thread_pool
.upgrade() .upgrade()
.and_then(|pool| { .map(|pool| {
pool.spawn(move || { pool.spawn(move || {
store.select_file(filter, sender, origin, opt_test_path, embedder); store.select_file(filter, sender, origin, opt_test_path, embedder);
}); });
Some(())
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
warn!( warn!(
@ -177,11 +174,10 @@ impl FileManager {
let embedder = self.embedder_proxy.clone(); let embedder = self.embedder_proxy.clone();
self.thread_pool self.thread_pool
.upgrade() .upgrade()
.and_then(|pool| { .map(|pool| {
pool.spawn(move || { pool.spawn(move || {
store.select_files(filter, sender, origin, opt_test_paths, embedder); store.select_files(filter, sender, origin, opt_test_paths, embedder);
}); });
Some(())
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
warn!( warn!(
@ -221,7 +217,7 @@ impl FileManager {
let done_sender = done_sender.clone(); let done_sender = done_sender.clone();
self.thread_pool self.thread_pool
.upgrade() .upgrade()
.and_then(|pool| { .map(|pool| {
pool.spawn(move || { pool.spawn(move || {
loop { loop {
if cancellation_listener.lock().unwrap().cancelled() { if cancellation_listener.lock().unwrap().cancelled() {
@ -266,7 +262,7 @@ impl FileManager {
if length == 0 { if length == 0 {
let mut body = res_body.lock().unwrap(); let mut body = res_body.lock().unwrap();
let completed_body = match *body { let completed_body = match *body {
ResponseBody::Receiving(ref mut body) => mem::replace(body, vec![]), ResponseBody::Receiving(ref mut body) => std::mem::take(body),
_ => vec![], _ => vec![],
}; };
*body = ResponseBody::Done(completed_body); *body = ResponseBody::Done(completed_body);
@ -276,7 +272,6 @@ impl FileManager {
reader.consume(length); reader.consume(length);
} }
}); });
Some(())
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
warn!("FileManager tried to fetch a file in chunks after CoreResourceManager has exited."); warn!("FileManager tried to fetch a file in chunks after CoreResourceManager has exited.");
@ -373,7 +368,7 @@ impl FileManager {
FileImpl::Sliced(parent_id, inner_rel_pos) => { FileImpl::Sliced(parent_id, inner_rel_pos) => {
// Next time we don't need to check validity since // Next time we don't need to check validity since
// we have already done that for requesting URL if necessary. // we have already done that for requesting URL if necessary.
return self.fetch_blob_buf( self.fetch_blob_buf(
done_sender, done_sender,
cancellation_listener, cancellation_listener,
&parent_id, &parent_id,
@ -383,7 +378,7 @@ impl FileManager {
RelativePos::full_range().slice_inner(&inner_rel_pos), RelativePos::full_range().slice_inner(&inner_rel_pos),
), ),
response, response,
); )
}, },
} }
} }
@ -411,7 +406,7 @@ impl FileManagerStore {
origin_in: &FileOrigin, origin_in: &FileOrigin,
) -> Result<FileImpl, BlobURLStoreError> { ) -> Result<FileImpl, BlobURLStoreError> {
match self.entries.read().unwrap().get(id) { match self.entries.read().unwrap().get(id) {
Some(ref entry) => { Some(entry) => {
if *origin_in != *entry.origin { if *origin_in != *entry.origin {
Err(BlobURLStoreError::InvalidOrigin) Err(BlobURLStoreError::InvalidOrigin)
} else { } else {
@ -441,7 +436,7 @@ impl FileManagerStore {
let zero_refs = entry.refs.load(Ordering::Acquire) == 0; let zero_refs = entry.refs.load(Ordering::Acquire) == 0;
// Check if no other fetch has acquired a token for this file. // Check if no other fetch has acquired a token for this file.
let no_outstanding_tokens = entry.outstanding_tokens.len() == 0; let no_outstanding_tokens = entry.outstanding_tokens.is_empty();
// Check if there is still a blob URL outstanding. // Check if there is still a blob URL outstanding.
let valid = entry.is_valid_url.load(Ordering::Acquire); let valid = entry.is_valid_url.load(Ordering::Acquire);
@ -450,7 +445,7 @@ impl FileManagerStore {
let do_remove = zero_refs && no_outstanding_tokens && !valid; let do_remove = zero_refs && no_outstanding_tokens && !valid;
if do_remove { if do_remove {
entries.remove(&file_id); entries.remove(file_id);
} }
} }
} }
@ -461,7 +456,7 @@ impl FileManagerStore {
let parent_id = match entries.get(file_id) { let parent_id = match entries.get(file_id) {
Some(entry) => { Some(entry) => {
if let FileImpl::Sliced(ref parent_id, _) = entry.file_impl { if let FileImpl::Sliced(ref parent_id, _) = entry.file_impl {
Some(parent_id.clone()) Some(*parent_id)
} else { } else {
None None
} }
@ -477,7 +472,7 @@ impl FileManagerStore {
return FileTokenCheck::ShouldFail; return FileTokenCheck::ShouldFail;
} }
let token = Uuid::new_v4(); let token = Uuid::new_v4();
entry.outstanding_tokens.insert(token.clone()); entry.outstanding_tokens.insert(token);
return FileTokenCheck::Required(token); return FileTokenCheck::Required(token);
} }
FileTokenCheck::ShouldFail FileTokenCheck::ShouldFail
@ -585,7 +580,6 @@ impl FileManagerStore {
}, },
None => { None => {
let _ = sender.send(Err(FileManagerThreadError::UserCancelled)); let _ = sender.send(Err(FileManagerThreadError::UserCancelled));
return;
}, },
} }
} }
@ -631,7 +625,6 @@ impl FileManagerStore {
}, },
None => { None => {
let _ = sender.send(Err(FileManagerThreadError::UserCancelled)); let _ = sender.send(Err(FileManagerThreadError::UserCancelled));
return;
}, },
} }
} }
@ -672,7 +665,7 @@ impl FileManagerStore {
id, id,
FileStoreEntry { FileStoreEntry {
origin: origin.to_string(), origin: origin.to_string(),
file_impl: file_impl, file_impl,
refs: AtomicUsize::new(1), refs: AtomicUsize::new(1),
// Invalid here since create_entry is called by file selection // Invalid here since create_entry is called by file selection
is_valid_url: AtomicBool::new(false), is_valid_url: AtomicBool::new(false),
@ -687,11 +680,11 @@ impl FileManagerStore {
}; };
Ok(SelectedFile { Ok(SelectedFile {
id: id, id,
filename: filename_path.to_path_buf(), filename: filename_path.to_path_buf(),
modified: modified_epoch, modified: modified_epoch,
size: file_size, size: file_size,
type_string: type_string, type_string,
}) })
} }
@ -798,13 +791,13 @@ impl FileManagerStore {
let is_valid = entry.is_valid_url.load(Ordering::Acquire); let is_valid = entry.is_valid_url.load(Ordering::Acquire);
// Check if no fetch has acquired a token for this file. // Check if no fetch has acquired a token for this file.
let no_outstanding_tokens = entry.outstanding_tokens.len() == 0; let no_outstanding_tokens = entry.outstanding_tokens.is_empty();
// Can we remove this file? // Can we remove this file?
let do_remove = !is_valid && no_outstanding_tokens; let do_remove = !is_valid && no_outstanding_tokens;
if let FileImpl::Sliced(ref parent_id, _) = entry.file_impl { if let FileImpl::Sliced(ref parent_id, _) = entry.file_impl {
(do_remove, Some(parent_id.clone())) (do_remove, Some(*parent_id))
} else { } else {
(do_remove, None) (do_remove, None)
} }
@ -867,13 +860,13 @@ impl FileManagerStore {
let zero_refs = entry.refs.load(Ordering::Acquire) == 0; let zero_refs = entry.refs.load(Ordering::Acquire) == 0;
// Check if no fetch has acquired a token for this file. // Check if no fetch has acquired a token for this file.
let no_outstanding_tokens = entry.outstanding_tokens.len() == 0; let no_outstanding_tokens = entry.outstanding_tokens.is_empty();
// Can we remove this file? // Can we remove this file?
let do_remove = zero_refs && no_outstanding_tokens; let do_remove = zero_refs && no_outstanding_tokens;
if let FileImpl::Sliced(ref parent_id, _) = entry.file_impl { if let FileImpl::Sliced(ref parent_id, _) = entry.file_impl {
(do_remove, Some(parent_id.clone()), Ok(())) (do_remove, Some(*parent_id), Ok(()))
} else { } else {
(do_remove, None, Ok(())) (do_remove, None, Ok(()))
} }
@ -913,7 +906,7 @@ fn read_file_in_chunks(
buf.truncate(n); buf.truncate(n);
let blob_buf = BlobBuf { let blob_buf = BlobBuf {
filename: opt_filename, filename: opt_filename,
type_string: type_string, type_string,
size: size as u64, size: size as u64,
bytes: buf, bytes: buf,
}; };

View file

@ -19,7 +19,7 @@ lazy_static! {
fn create_host_table() -> Option<HashMap<String, IpAddr>> { fn create_host_table() -> Option<HashMap<String, IpAddr>> {
let path = env::var_os("HOST_FILE")?; let path = env::var_os("HOST_FILE")?;
let file = File::open(&path).ok()?; let file = File::open(path).ok()?;
let mut reader = BufReader::new(file); let mut reader = BufReader::new(file);
let mut lines = String::new(); let mut lines = String::new();

View file

@ -33,9 +33,9 @@ impl HstsEntry {
None None
} else { } else {
Some(HstsEntry { Some(HstsEntry {
host: host, host,
include_subdomains: (subdomains == IncludeSubdomains::Included), include_subdomains: (subdomains == IncludeSubdomains::Included),
max_age: max_age, max_age,
timestamp: Some(time::get_time().sec as u64), timestamp: Some(time::get_time().sec as u64),
}) })
} }
@ -60,18 +60,12 @@ impl HstsEntry {
} }
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct HstsList { pub struct HstsList {
pub entries_map: HashMap<String, Vec<HstsEntry>>, pub entries_map: HashMap<String, Vec<HstsEntry>>,
} }
impl HstsList { impl HstsList {
pub fn new() -> HstsList {
HstsList {
entries_map: HashMap::new(),
}
}
/// Create an `HstsList` from the bytes of a JSON preload file. /// Create an `HstsList` from the bytes of a JSON preload file.
pub fn from_preload(preload_content: &str) -> Option<HstsList> { pub fn from_preload(preload_content: &str) -> Option<HstsList> {
#[derive(Deserialize)] #[derive(Deserialize)]
@ -81,14 +75,14 @@ impl HstsList {
let hsts_entries: Option<HstsEntries> = serde_json::from_str(preload_content).ok(); let hsts_entries: Option<HstsEntries> = serde_json::from_str(preload_content).ok();
hsts_entries.map_or(None, |hsts_entries| { hsts_entries.map(|hsts_entries| {
let mut hsts_list: HstsList = HstsList::new(); let mut hsts_list: HstsList = HstsList::default();
for hsts_entry in hsts_entries.entries { for hsts_entry in hsts_entries.entries {
hsts_list.push(hsts_entry); hsts_list.push(hsts_entry);
} }
return Some(hsts_list); hsts_list
}) })
} }
@ -112,7 +106,7 @@ impl HstsList {
fn has_domain(&self, host: &str, base_domain: &str) -> bool { fn has_domain(&self, host: &str, base_domain: &str) -> bool {
self.entries_map.get(base_domain).map_or(false, |entries| { self.entries_map.get(base_domain).map_or(false, |entries| {
entries.iter().any(|e| e.matches_domain(&host)) entries.iter().any(|e| e.matches_domain(host))
}) })
} }
@ -128,10 +122,7 @@ impl HstsList {
let have_domain = self.has_domain(&entry.host, base_domain); let have_domain = self.has_domain(&entry.host, base_domain);
let have_subdomain = self.has_subdomain(&entry.host, base_domain); let have_subdomain = self.has_subdomain(&entry.host, base_domain);
let entries = self let entries = self.entries_map.entry(base_domain.to_owned()).or_default();
.entries_map
.entry(base_domain.to_owned())
.or_insert(vec![]);
if !have_domain && !have_subdomain { if !have_domain && !have_subdomain {
entries.push(entry); entries.push(entry);
} else if !have_subdomain { } else if !have_subdomain {

View file

@ -126,7 +126,7 @@ pub struct CachedResponse {
} }
/// A memory cache. /// A memory cache.
#[derive(MallocSizeOf)] #[derive(Default, MallocSizeOf)]
pub struct HttpCache { pub struct HttpCache {
/// cached responses. /// cached responses.
entries: HashMap<CacheKey, Vec<CachedResource>>, entries: HashMap<CacheKey, Vec<CachedResource>>,
@ -192,12 +192,12 @@ fn calculate_response_age(response: &Response) -> Duration {
/// or uses a heuristic if none are present. /// or uses a heuristic if none are present.
fn get_response_expiry(response: &Response) -> Duration { fn get_response_expiry(response: &Response) -> Duration {
// Calculating Freshness Lifetime <https://tools.ietf.org/html/rfc7234#section-4.2.1> // Calculating Freshness Lifetime <https://tools.ietf.org/html/rfc7234#section-4.2.1>
let age = calculate_response_age(&response); let age = calculate_response_age(response);
if let Some(directives) = response.headers.typed_get::<CacheControl>() { if let Some(directives) = response.headers.typed_get::<CacheControl>() {
if directives.no_cache() { if directives.no_cache() {
// Requires validation on first use. // Requires validation on first use.
return Duration::seconds(0i64); return Duration::seconds(0i64);
} else { }
if let Some(secs) = directives.max_age().or(directives.s_max_age()) { if let Some(secs) = directives.max_age().or(directives.s_max_age()) {
let max_age = Duration::from_std(secs).unwrap(); let max_age = Duration::from_std(secs).unwrap();
if max_age < age { if max_age < age {
@ -206,7 +206,6 @@ fn get_response_expiry(response: &Response) -> Duration {
return max_age - age; return max_age - age;
} }
} }
}
match response.headers.typed_get::<Expires>() { match response.headers.typed_get::<Expires>() {
Some(t) => { Some(t) => {
// store the period of time from now until expiry // store the period of time from now until expiry
@ -217,9 +216,8 @@ fn get_response_expiry(response: &Response) -> Duration {
if desired > current { if desired > current {
return desired - current; return desired - current;
} else {
return Duration::seconds(0i64);
} }
return Duration::seconds(0i64);
}, },
// Malformed Expires header, shouldn't be used to construct a valid response. // Malformed Expires header, shouldn't be used to construct a valid response.
None if response.headers.contains_key(header::EXPIRES) => return Duration::seconds(0i64), None if response.headers.contains_key(header::EXPIRES) => return Duration::seconds(0i64),
@ -246,19 +244,19 @@ fn get_response_expiry(response: &Response) -> Duration {
let last_modified = Timespec::new(last_modified.as_secs() as i64, 0); let last_modified = Timespec::new(last_modified.as_secs() as i64, 0);
// A typical setting of this fraction might be 10%. // A typical setting of this fraction might be 10%.
let raw_heuristic_calc = (current - last_modified) / 10; let raw_heuristic_calc = (current - last_modified) / 10;
let result = if raw_heuristic_calc < max_heuristic {
if raw_heuristic_calc < max_heuristic {
raw_heuristic_calc raw_heuristic_calc
} else { } else {
max_heuristic max_heuristic
}; }
result
} else { } else {
max_heuristic max_heuristic
}; };
if is_cacheable_by_default(*code) { if is_cacheable_by_default(*code) {
// Status codes that are cacheable by default can use heuristics to determine freshness. // Status codes that are cacheable by default can use heuristics to determine freshness.
return heuristic_freshness; return heuristic_freshness;
} else { }
// Other status codes can only use heuristic freshness if the public cache directive is present. // Other status codes can only use heuristic freshness if the public cache directive is present.
if let Some(ref directives) = response.headers.typed_get::<CacheControl>() { if let Some(ref directives) = response.headers.typed_get::<CacheControl>() {
if directives.public() { if directives.public() {
@ -266,7 +264,6 @@ fn get_response_expiry(response: &Response) -> Duration {
} }
} }
} }
}
// Requires validation upon first use as default. // Requires validation upon first use as default.
Duration::seconds(0i64) Duration::seconds(0i64)
} }
@ -335,9 +332,9 @@ fn create_cached_response(
response.status = cached_resource.data.status.clone(); response.status = cached_resource.data.status.clone();
response.raw_status = cached_resource.data.raw_status.clone(); response.raw_status = cached_resource.data.raw_status.clone();
response.url_list = cached_resource.data.url_list.clone(); response.url_list = cached_resource.data.url_list.clone();
response.https_state = cached_resource.data.https_state.clone(); response.https_state = cached_resource.data.https_state;
response.referrer = request.referrer.to_url().cloned(); response.referrer = request.referrer.to_url().cloned();
response.referrer_policy = request.referrer_policy.clone(); response.referrer_policy = request.referrer_policy;
response.aborted = cached_resource.aborted.clone(); response.aborted = cached_resource.aborted.clone();
let expires = cached_resource.data.expires; let expires = cached_resource.data.expires;
let adjusted_expires = get_expiry_adjustment_from_request_headers(request, expires); let adjusted_expires = get_expiry_adjustment_from_request_headers(request, expires);
@ -347,10 +344,9 @@ fn create_cached_response(
// TODO: take must-revalidate into account <https://tools.ietf.org/html/rfc7234#section-5.2.2.1> // TODO: take must-revalidate into account <https://tools.ietf.org/html/rfc7234#section-5.2.2.1>
// TODO: if this cache is to be considered shared, take proxy-revalidate into account // TODO: if this cache is to be considered shared, take proxy-revalidate into account
// <https://tools.ietf.org/html/rfc7234#section-5.2.2.7> // <https://tools.ietf.org/html/rfc7234#section-5.2.2.7>
let has_expired = let has_expired = adjusted_expires <= time_since_validated;
(adjusted_expires < time_since_validated) || (adjusted_expires == time_since_validated);
let cached_response = CachedResponse { let cached_response = CachedResponse {
response: response, response,
needs_validation: has_expired, needs_validation: has_expired,
}; };
Some(cached_response) Some(cached_response)
@ -370,12 +366,12 @@ fn create_resource_with_bytes_from_resource(
data: Measurable(MeasurableCachedResource { data: Measurable(MeasurableCachedResource {
metadata: resource.data.metadata.clone(), metadata: resource.data.metadata.clone(),
location_url: resource.data.location_url.clone(), location_url: resource.data.location_url.clone(),
https_state: resource.data.https_state.clone(), https_state: resource.data.https_state,
status: Some((StatusCode::PARTIAL_CONTENT, "Partial Content".into())), status: Some((StatusCode::PARTIAL_CONTENT, "Partial Content".into())),
raw_status: Some((206, b"Partial Content".to_vec())), raw_status: Some((206, b"Partial Content".to_vec())),
url_list: resource.data.url_list.clone(), url_list: resource.data.url_list.clone(),
expires: resource.data.expires.clone(), expires: resource.data.expires,
last_validated: resource.data.last_validated.clone(), last_validated: resource.data.last_validated,
}), }),
} }
} }
@ -413,7 +409,7 @@ fn handle_range_request(
// see <https://tools.ietf.org/html/rfc7233#section-4.3>. // see <https://tools.ietf.org/html/rfc7233#section-4.3>.
// TODO: add support for complete and partial resources, // TODO: add support for complete and partial resources,
// whose body is in the ResponseBody::Receiving state. // whose body is in the ResponseBody::Receiving state.
(&(Bound::Included(beginning), Bound::Included(end)), Some(ref complete_resource)) => { (&(Bound::Included(beginning), Bound::Included(end)), Some(complete_resource)) => {
if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() { if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() {
if end == u64::max_value() { if end == u64::max_value() {
// Prevent overflow on the addition below. // Prevent overflow on the addition below.
@ -427,7 +423,7 @@ fn handle_range_request(
create_resource_with_bytes_from_resource(bytes, complete_resource); create_resource_with_bytes_from_resource(bytes, complete_resource);
let cached_headers = new_resource.data.metadata.headers.lock().unwrap(); let cached_headers = new_resource.data.metadata.headers.lock().unwrap();
let cached_response = let cached_response =
create_cached_response(request, &new_resource, &*cached_headers, done_chan); create_cached_response(request, &new_resource, &cached_headers, done_chan);
if let Some(cached_response) = cached_response { if let Some(cached_response) = cached_response {
return Some(cached_response); return Some(cached_response);
} }
@ -451,7 +447,7 @@ fn handle_range_request(
if res_beginning <= beginning && res_end >= end { if res_beginning <= beginning && res_end >= end {
let resource_body = &*partial_resource.body.lock().unwrap(); let resource_body = &*partial_resource.body.lock().unwrap();
let requested = match resource_body { let requested = match resource_body {
&ResponseBody::Done(ref body) => { ResponseBody::Done(body) => {
let b = beginning as usize - res_beginning as usize; let b = beginning as usize - res_beginning as usize;
let e = end as usize - res_beginning as usize + 1; let e = end as usize - res_beginning as usize + 1;
body.get(b..e) body.get(b..e)
@ -460,9 +456,9 @@ fn handle_range_request(
}; };
if let Some(bytes) = requested { if let Some(bytes) = requested {
let new_resource = let new_resource =
create_resource_with_bytes_from_resource(&bytes, partial_resource); create_resource_with_bytes_from_resource(bytes, partial_resource);
let cached_response = let cached_response =
create_cached_response(request, &new_resource, &*headers, done_chan); create_cached_response(request, &new_resource, &headers, done_chan);
if let Some(cached_response) = cached_response { if let Some(cached_response) = cached_response {
return Some(cached_response); return Some(cached_response);
} }
@ -470,7 +466,7 @@ fn handle_range_request(
} }
} }
}, },
(&(Bound::Included(beginning), Bound::Unbounded), Some(ref complete_resource)) => { (&(Bound::Included(beginning), Bound::Unbounded), Some(complete_resource)) => {
if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() { if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() {
let b = beginning as usize; let b = beginning as usize;
let requested = body.get(b..); let requested = body.get(b..);
@ -479,7 +475,7 @@ fn handle_range_request(
create_resource_with_bytes_from_resource(bytes, complete_resource); create_resource_with_bytes_from_resource(bytes, complete_resource);
let cached_headers = new_resource.data.metadata.headers.lock().unwrap(); let cached_headers = new_resource.data.metadata.headers.lock().unwrap();
let cached_response = let cached_response =
create_cached_response(request, &new_resource, &*cached_headers, done_chan); create_cached_response(request, &new_resource, &cached_headers, done_chan);
if let Some(cached_response) = cached_response { if let Some(cached_response) = cached_response {
return Some(cached_response); return Some(cached_response);
} }
@ -505,7 +501,7 @@ fn handle_range_request(
if res_beginning < beginning && res_end == total - 1 { if res_beginning < beginning && res_end == total - 1 {
let resource_body = &*partial_resource.body.lock().unwrap(); let resource_body = &*partial_resource.body.lock().unwrap();
let requested = match resource_body { let requested = match resource_body {
&ResponseBody::Done(ref body) => { ResponseBody::Done(body) => {
let from_byte = beginning as usize - res_beginning as usize; let from_byte = beginning as usize - res_beginning as usize;
body.get(from_byte..) body.get(from_byte..)
}, },
@ -513,9 +509,9 @@ fn handle_range_request(
}; };
if let Some(bytes) = requested { if let Some(bytes) = requested {
let new_resource = let new_resource =
create_resource_with_bytes_from_resource(&bytes, partial_resource); create_resource_with_bytes_from_resource(bytes, partial_resource);
let cached_response = let cached_response =
create_cached_response(request, &new_resource, &*headers, done_chan); create_cached_response(request, &new_resource, &headers, done_chan);
if let Some(cached_response) = cached_response { if let Some(cached_response) = cached_response {
return Some(cached_response); return Some(cached_response);
} }
@ -523,7 +519,7 @@ fn handle_range_request(
} }
} }
}, },
(&(Bound::Unbounded, Bound::Included(offset)), Some(ref complete_resource)) => { (&(Bound::Unbounded, Bound::Included(offset)), Some(complete_resource)) => {
if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() { if let ResponseBody::Done(ref body) = *complete_resource.body.lock().unwrap() {
let from_byte = body.len() - offset as usize; let from_byte = body.len() - offset as usize;
let requested = body.get(from_byte..); let requested = body.get(from_byte..);
@ -532,7 +528,7 @@ fn handle_range_request(
create_resource_with_bytes_from_resource(bytes, complete_resource); create_resource_with_bytes_from_resource(bytes, complete_resource);
let cached_headers = new_resource.data.metadata.headers.lock().unwrap(); let cached_headers = new_resource.data.metadata.headers.lock().unwrap();
let cached_response = let cached_response =
create_cached_response(request, &new_resource, &*cached_headers, done_chan); create_cached_response(request, &new_resource, &cached_headers, done_chan);
if let Some(cached_response) = cached_response { if let Some(cached_response) = cached_response {
return Some(cached_response); return Some(cached_response);
} }
@ -551,8 +547,8 @@ fn handle_range_request(
} else { } else {
continue; continue;
}; };
if !(total >= res_beginning) || if total < res_beginning ||
!(total >= res_end) || total < res_end ||
offset == 0 || offset == 0 ||
offset == u64::max_value() offset == u64::max_value()
{ {
@ -562,7 +558,7 @@ fn handle_range_request(
if (total - res_beginning) > (offset - 1) && (total - res_end) < offset + 1 { if (total - res_beginning) > (offset - 1) && (total - res_end) < offset + 1 {
let resource_body = &*partial_resource.body.lock().unwrap(); let resource_body = &*partial_resource.body.lock().unwrap();
let requested = match resource_body { let requested = match resource_body {
&ResponseBody::Done(ref body) => { ResponseBody::Done(body) => {
let from_byte = body.len() - offset as usize; let from_byte = body.len() - offset as usize;
body.get(from_byte..) body.get(from_byte..)
}, },
@ -570,9 +566,9 @@ fn handle_range_request(
}; };
if let Some(bytes) = requested { if let Some(bytes) = requested {
let new_resource = let new_resource =
create_resource_with_bytes_from_resource(&bytes, partial_resource); create_resource_with_bytes_from_resource(bytes, partial_resource);
let cached_response = let cached_response =
create_cached_response(request, &new_resource, &*headers, done_chan); create_cached_response(request, &new_resource, &headers, done_chan);
if let Some(cached_response) = cached_response { if let Some(cached_response) = cached_response {
return Some(cached_response); return Some(cached_response);
} }
@ -587,13 +583,6 @@ fn handle_range_request(
} }
impl HttpCache { impl HttpCache {
/// Create a new memory cache instance.
pub fn new() -> HttpCache {
HttpCache {
entries: HashMap::new(),
}
}
/// Constructing Responses from Caches. /// Constructing Responses from Caches.
/// <https://tools.ietf.org/html/rfc7234#section-4> /// <https://tools.ietf.org/html/rfc7234#section-4>
pub fn construct_response( pub fn construct_response(
@ -608,11 +597,11 @@ impl HttpCache {
debug!("non-GET method, not caching"); debug!("non-GET method, not caching");
return None; return None;
} }
let entry_key = CacheKey::new(&request); let entry_key = CacheKey::new(request);
let resources = self let resources = self
.entries .entries
.get(&entry_key)? .get(&entry_key)?
.into_iter() .iter()
.filter(|r| !r.aborted.load(Ordering::Relaxed)); .filter(|r| !r.aborted.load(Ordering::Relaxed));
let mut candidates = vec![]; let mut candidates = vec![];
for cached_resource in resources { for cached_resource in resources {
@ -671,7 +660,7 @@ impl HttpCache {
range_spec.iter().collect(), range_spec.iter().collect(),
done_chan, done_chan,
); );
} else { }
while let Some(cached_resource) = candidates.pop() { while let Some(cached_resource) = candidates.pop() {
// Not a Range request. // Not a Range request.
// Do not allow 206 responses to be constructed. // Do not allow 206 responses to be constructed.
@ -697,12 +686,11 @@ impl HttpCache {
// or using the Date header to return the most recent one. // or using the Date header to return the most recent one.
let cached_headers = cached_resource.data.metadata.headers.lock().unwrap(); let cached_headers = cached_resource.data.metadata.headers.lock().unwrap();
let cached_response = let cached_response =
create_cached_response(request, cached_resource, &*cached_headers, done_chan); create_cached_response(request, cached_resource, &cached_headers, done_chan);
if let Some(cached_response) = cached_response { if let Some(cached_response) = cached_response {
return Some(cached_response); return Some(cached_response);
} }
} }
}
debug!("couldn't find an appropriate response, not caching"); debug!("couldn't find an appropriate response, not caching");
// The cache wasn't able to construct anything. // The cache wasn't able to construct anything.
None None
@ -712,7 +700,7 @@ impl HttpCache {
/// whose response body was still receiving data when the resource was constructed, /// whose response body was still receiving data when the resource was constructed,
/// and whose response has now either been completed or cancelled. /// and whose response has now either been completed or cancelled.
pub fn update_awaiting_consumers(&self, request: &Request, response: &Response) { pub fn update_awaiting_consumers(&self, request: &Request, response: &Response) {
let entry_key = CacheKey::new(&request); let entry_key = CacheKey::new(request);
let cached_resources = match self.entries.get(&entry_key) { let cached_resources = match self.entries.get(&entry_key) {
None => return, None => return,
@ -762,9 +750,9 @@ impl HttpCache {
done_chan: &mut DoneChannel, done_chan: &mut DoneChannel,
) -> Option<Response> { ) -> Option<Response> {
assert_eq!(response.status.map(|s| s.0), Some(StatusCode::NOT_MODIFIED)); assert_eq!(response.status.map(|s| s.0), Some(StatusCode::NOT_MODIFIED));
let entry_key = CacheKey::new(&request); let entry_key = CacheKey::new(request);
if let Some(cached_resources) = self.entries.get_mut(&entry_key) { if let Some(cached_resources) = self.entries.get_mut(&entry_key) {
for cached_resource in cached_resources.iter_mut() { if let Some(cached_resource) = cached_resources.iter_mut().next() {
// done_chan will have been set to Some(..) by http_network_fetch. // done_chan will have been set to Some(..) by http_network_fetch.
// If the body is not receiving data, set the done_chan back to None. // If the body is not receiving data, set the done_chan back to None.
// Otherwise, create a new dedicated channel to update the consumer. // Otherwise, create a new dedicated channel to update the consumer.
@ -794,9 +782,9 @@ impl HttpCache {
); );
constructed_response.body = cached_resource.body.clone(); constructed_response.body = cached_resource.body.clone();
constructed_response.status = cached_resource.data.status.clone(); constructed_response.status = cached_resource.data.status.clone();
constructed_response.https_state = cached_resource.data.https_state.clone(); constructed_response.https_state = cached_resource.data.https_state;
constructed_response.referrer = request.referrer.to_url().cloned(); constructed_response.referrer = request.referrer.to_url().cloned();
constructed_response.referrer_policy = request.referrer_policy.clone(); constructed_response.referrer_policy = request.referrer_policy;
constructed_response.raw_status = cached_resource.data.raw_status.clone(); constructed_response.raw_status = cached_resource.data.raw_status.clone();
constructed_response.url_list = cached_resource.data.url_list.clone(); constructed_response.url_list = cached_resource.data.url_list.clone();
cached_resource.data.expires = get_response_expiry(&constructed_response); cached_resource.data.expires = get_response_expiry(&constructed_response);
@ -831,12 +819,12 @@ impl HttpCache {
self.invalidate_for_url(&url); self.invalidate_for_url(&url);
} }
} }
if let Some(Ok(ref content_location)) = response if let Some(Ok(content_location)) = response
.headers .headers
.get(header::CONTENT_LOCATION) .get(header::CONTENT_LOCATION)
.map(HeaderValue::to_str) .map(HeaderValue::to_str)
{ {
if let Ok(url) = request.current_url().join(&content_location) { if let Ok(url) = request.current_url().join(content_location) {
self.invalidate_for_url(&url); self.invalidate_for_url(&url);
} }
} }
@ -862,7 +850,7 @@ impl HttpCache {
// responses to be stored is present in the response. // responses to be stored is present in the response.
return; return;
}; };
let entry_key = CacheKey::new(&request); let entry_key = CacheKey::new(request);
let metadata = match response.metadata() { let metadata = match response.metadata() {
Ok(FetchMetadata::Filtered { Ok(FetchMetadata::Filtered {
filtered: _, filtered: _,
@ -874,7 +862,7 @@ impl HttpCache {
if !response_is_cacheable(&metadata) { if !response_is_cacheable(&metadata) {
return; return;
} }
let expiry = get_response_expiry(&response); let expiry = get_response_expiry(response);
let cacheable_metadata = CachedMetadata { let cacheable_metadata = CachedMetadata {
headers: Arc::new(Mutex::new(response.headers.clone())), headers: Arc::new(Mutex::new(response.headers.clone())),
data: Measurable(MeasurableCachedMetadata { data: Measurable(MeasurableCachedMetadata {
@ -892,7 +880,7 @@ impl HttpCache {
data: Measurable(MeasurableCachedResource { data: Measurable(MeasurableCachedResource {
metadata: cacheable_metadata, metadata: cacheable_metadata,
location_url: response.location_url.clone(), location_url: response.location_url.clone(),
https_state: response.https_state.clone(), https_state: response.https_state,
status: response.status.clone(), status: response.status.clone(),
raw_status: response.raw_status.clone(), raw_status: response.raw_status.clone(),
url_list: response.url_list.clone(), url_list: response.url_list.clone(),
@ -900,7 +888,7 @@ impl HttpCache {
last_validated: time::now(), last_validated: time::now(),
}), }),
}; };
let entry = self.entries.entry(entry_key).or_insert_with(|| vec![]); let entry = self.entries.entry(entry_key).or_default();
entry.push(entry_resource); entry.push(entry_resource);
// TODO: Complete incomplete responses, including 206 response, when stored here. // TODO: Complete incomplete responses, including 206 response, when stored here.
// See A cache MAY complete a stored incomplete response by making a subsequent range request // See A cache MAY complete a stored incomplete response by making a subsequent range request

View file

@ -5,8 +5,6 @@
use core::convert::Infallible; use core::convert::Infallible;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::iter::FromIterator; use std::iter::FromIterator;
use std::mem;
use std::ops::Deref;
use std::sync::{Arc as StdArc, Condvar, Mutex, RwLock}; use std::sync::{Arc as StdArc, Condvar, Mutex, RwLock};
use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
@ -21,8 +19,8 @@ use headers::authorization::Basic;
use headers::{ use headers::{
AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowMethods, AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowMethods,
AccessControlAllowOrigin, AccessControlMaxAge, AccessControlRequestHeaders, AccessControlAllowOrigin, AccessControlMaxAge, AccessControlRequestHeaders,
AccessControlRequestMethod, Authorization, CacheControl, ContentEncoding, ContentLength, AccessControlRequestMethod, Authorization, CacheControl, ContentLength, HeaderMapExt,
HeaderMapExt, IfModifiedSince, LastModified, Origin as HyperOrigin, Pragma, Referer, UserAgent, IfModifiedSince, LastModified, Origin as HyperOrigin, Pragma, Referer, UserAgent,
}; };
use http::header::{ use http::header::{
self, HeaderValue, ACCEPT, CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LOCATION, CONTENT_TYPE, self, HeaderValue, ACCEPT, CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LOCATION, CONTENT_TYPE,
@ -101,15 +99,15 @@ pub struct HttpState {
pub override_manager: CertificateErrorOverrideManager, pub override_manager: CertificateErrorOverrideManager,
} }
impl HttpState { impl Default for HttpState {
pub fn new() -> HttpState { fn default() -> Self {
let override_manager = CertificateErrorOverrideManager::new(); let override_manager = CertificateErrorOverrideManager::new();
HttpState { Self {
hsts_list: RwLock::new(HstsList::new()), hsts_list: RwLock::new(HstsList::default()),
cookie_jar: RwLock::new(CookieStorage::new(150)), cookie_jar: RwLock::new(CookieStorage::new(150)),
auth_cache: RwLock::new(AuthCache::new()), auth_cache: RwLock::new(AuthCache::default()),
history_states: RwLock::new(HashMap::new()), history_states: RwLock::new(HashMap::new()),
http_cache: RwLock::new(HttpCache::new()), http_cache: RwLock::new(HttpCache::default()),
http_cache_state: Mutex::new(HashMap::new()), http_cache_state: Mutex::new(HashMap::new()),
client: create_http_client(create_tls_config( client: create_http_client(create_tls_config(
CACertificates::Default, CACertificates::Default,
@ -193,7 +191,7 @@ fn no_referrer_when_downgrade(referrer_url: ServoUrl, current_url: ServoUrl) ->
return None; return None;
} }
// Step 2 // Step 2
return strip_url_for_use_as_referrer(referrer_url, false); strip_url_for_use_as_referrer(referrer_url, false)
} }
/// <https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-strict-origin> /// <https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-strict-origin>
@ -237,8 +235,8 @@ fn is_schemelessy_same_site(site_a: &ImmutableOrigin, site_b: &ImmutableOrigin)
let host_b_reg = reg_suffix(&host_b); let host_b_reg = reg_suffix(&host_b);
// Step 2.2-2.3 // Step 2.2-2.3
(site_a.host() == site_b.host() && host_a_reg == "") || (site_a.host() == site_b.host() && host_a_reg.is_empty()) ||
(host_a_reg == host_b_reg && host_a_reg != "") (host_a_reg == host_b_reg && !host_a_reg.is_empty())
} else { } else {
// Step 3 // Step 3
false false
@ -345,7 +343,7 @@ fn set_cookies_from_headers(
) { ) {
for cookie in headers.get_all(header::SET_COOKIE) { for cookie in headers.get_all(header::SET_COOKIE) {
if let Ok(cookie_str) = std::str::from_utf8(cookie.as_bytes()) { if let Ok(cookie_str) = std::str::from_utf8(cookie.as_bytes()) {
set_cookie_for_url(&cookie_jar, &url, &cookie_str); set_cookie_for_url(cookie_jar, url, cookie_str);
} }
} }
} }
@ -363,16 +361,16 @@ fn prepare_devtools_request(
is_xhr: bool, is_xhr: bool,
) -> ChromeToDevtoolsControlMsg { ) -> ChromeToDevtoolsControlMsg {
let request = DevtoolsHttpRequest { let request = DevtoolsHttpRequest {
url: url, url,
method: method, method,
headers: headers, headers,
body: body, body,
pipeline_id: pipeline_id, pipeline_id,
startedDateTime: now, startedDateTime: now,
timeStamp: now.duration_since(UNIX_EPOCH).unwrap_or_default().as_secs() as i64, timeStamp: now.duration_since(UNIX_EPOCH).unwrap_or_default().as_secs() as i64,
connect_time: connect_time, connect_time,
send_time: send_time, send_time,
is_xhr: is_xhr, is_xhr,
}; };
let net_event = NetworkEvent::HttpRequest(request); let net_event = NetworkEvent::HttpRequest(request);
@ -396,10 +394,10 @@ fn send_response_to_devtools(
pipeline_id: PipelineId, pipeline_id: PipelineId,
) { ) {
let response = DevtoolsHttpResponse { let response = DevtoolsHttpResponse {
headers: headers, headers,
status: status, status,
body: None, body: None,
pipeline_id: pipeline_id, pipeline_id,
}; };
let net_event_response = NetworkEvent::HttpResponse(response); let net_event_response = NetworkEvent::HttpResponse(response);
@ -411,7 +409,7 @@ fn auth_from_cache(
auth_cache: &RwLock<AuthCache>, auth_cache: &RwLock<AuthCache>,
origin: &ImmutableOrigin, origin: &ImmutableOrigin,
) -> Option<Authorization<Basic>> { ) -> Option<Authorization<Basic>> {
if let Some(ref auth_entry) = auth_cache if let Some(auth_entry) = auth_cache
.read() .read()
.unwrap() .unwrap()
.entries .entries
@ -503,9 +501,9 @@ async fn obtain_response(
.clone() .clone()
.into_url() .into_url()
.as_ref() .as_ref()
.replace("|", "%7C") .replace('|', "%7C")
.replace("{", "%7B") .replace('{', "%7B")
.replace("}", "%7D"); .replace('}', "%7D");
let request = if let Some(chunk_requester) = body { let request = if let Some(chunk_requester) = body {
let (sink, stream) = if source_is_null { let (sink, stream) = if source_is_null {
@ -649,7 +647,7 @@ async fn obtain_response(
.set_attribute(ResourceAttribute::ConnectEnd(connect_end)); .set_attribute(ResourceAttribute::ConnectEnd(connect_end));
let request_id = request_id.map(|v| v.to_owned()); let request_id = request_id.map(|v| v.to_owned());
let pipeline_id = pipeline_id.clone(); let pipeline_id = *pipeline_id;
let closure_url = url.clone(); let closure_url = url.clone();
let method = method.clone(); let method = method.clone();
let send_start = precise_time_ms(); let send_start = precise_time_ms();
@ -760,13 +758,13 @@ pub async fn http_fetch(
let method_mismatch = !method_cache_match && let method_mismatch = !method_cache_match &&
(!is_cors_safelisted_method(&request.method) || request.use_cors_preflight); (!is_cors_safelisted_method(&request.method) || request.use_cors_preflight);
let header_mismatch = request.headers.iter().any(|(name, value)| { let header_mismatch = request.headers.iter().any(|(name, value)| {
!cache.match_header(&*request, &name) && !cache.match_header(&*request, name) &&
!is_cors_safelisted_request_header(&name, &value) !is_cors_safelisted_request_header(&name, &value)
}); });
// Sub-substep 1 // Sub-substep 1
if method_mismatch || header_mismatch { if method_mismatch || header_mismatch {
let preflight_result = cors_preflight_fetch(&request, cache, context).await; let preflight_result = cors_preflight_fetch(request, cache, context).await;
// Sub-substep 2 // Sub-substep 2
if let Some(e) = preflight_result.get_network_error() { if let Some(e) = preflight_result.get_network_error() {
return Response::network_error(e.clone()); return Response::network_error(e.clone());
@ -798,7 +796,7 @@ pub async fn http_fetch(
.await; .await;
// Substep 4 // Substep 4
if cors_flag && cors_check(&request, &fetch_result).is_err() { if cors_flag && cors_check(request, &fetch_result).is_err() {
return Response::network_error(NetworkError::Internal("CORS check failed".into())); return Response::network_error(NetworkError::Internal("CORS check failed".into()));
} }
@ -834,7 +832,7 @@ pub async fn http_fetch(
.and_then(|v| { .and_then(|v| {
HeaderValue::to_str(v) HeaderValue::to_str(v)
.map(|l| { .map(|l| {
ServoUrl::parse_with_base(response.actual_response().url(), &l) ServoUrl::parse_with_base(response.actual_response().url(), l)
.map_err(|err| err.to_string()) .map_err(|err| err.to_string())
}) })
.ok() .ok()
@ -1093,7 +1091,7 @@ fn try_immutable_origin_to_hyper_origin(url_origin: &ImmutableOrigin) -> Option<
("http", 80) | ("https", 443) => None, ("http", 80) | ("https", 443) => None,
_ => Some(*port), _ => Some(*port),
}; };
HyperOrigin::try_from_parts(&scheme, &host.to_string(), port).ok() HyperOrigin::try_from_parts(scheme, &host.to_string(), port).ok()
}, },
} }
} }
@ -1257,14 +1255,15 @@ async fn http_network_or_cache_fetch(
} }
// Substep 5 // Substep 5
if authentication_fetch_flag && authorization_value.is_none() { if authentication_fetch_flag &&
if has_credentials(&current_url) { authorization_value.is_none() &&
has_credentials(&current_url)
{
authorization_value = Some(Authorization::basic( authorization_value = Some(Authorization::basic(
current_url.username(), current_url.username(),
current_url.password().unwrap_or(""), current_url.password().unwrap_or(""),
)); ));
} }
}
// Substep 6 // Substep 6
if let Some(basic) = authorization_value { if let Some(basic) = authorization_value {
@ -1285,7 +1284,7 @@ async fn http_network_or_cache_fetch(
// That one happens when a fetch gets a cache hit, and the resource is pending completion from the network. // That one happens when a fetch gets a cache hit, and the resource is pending completion from the network.
{ {
let (lock, cvar) = { let (lock, cvar) = {
let entry_key = CacheKey::new(&http_request); let entry_key = CacheKey::new(http_request);
let mut state_map = context.state.http_cache_state.lock().unwrap(); let mut state_map = context.state.http_cache_state.lock().unwrap();
&*state_map &*state_map
.entry(entry_key) .entry(entry_key)
@ -1314,7 +1313,7 @@ async fn http_network_or_cache_fetch(
// Step 5.19 // Step 5.19
if let Ok(http_cache) = context.state.http_cache.read() { if let Ok(http_cache) = context.state.http_cache.read() {
if let Some(response_from_cache) = if let Some(response_from_cache) =
http_cache.construct_response(&http_request, done_chan) http_cache.construct_response(http_request, done_chan)
{ {
let response_headers = response_from_cache.response.headers.clone(); let response_headers = response_from_cache.response.headers.clone();
// Substep 1, 2, 3, 4 // Substep 1, 2, 3, 4
@ -1378,7 +1377,7 @@ async fn http_network_or_cache_fetch(
// if no stores are pending. // if no stores are pending.
fn update_http_cache_state(context: &FetchContext, http_request: &Request) { fn update_http_cache_state(context: &FetchContext, http_request: &Request) {
let (lock, cvar) = { let (lock, cvar) = {
let entry_key = CacheKey::new(&http_request); let entry_key = CacheKey::new(http_request);
let mut state_map = context.state.http_cache_state.lock().unwrap(); let mut state_map = context.state.http_cache_state.lock().unwrap();
&*state_map &*state_map
.get_mut(&entry_key) .get_mut(&entry_key)
@ -1437,7 +1436,7 @@ async fn http_network_or_cache_fetch(
if http_request.cache_mode == CacheMode::OnlyIfCached { if http_request.cache_mode == CacheMode::OnlyIfCached {
// The cache will not be updated, // The cache will not be updated,
// set its state to ready to construct. // set its state to ready to construct.
update_http_cache_state(context, &http_request); update_http_cache_state(context, http_request);
return Response::network_error(NetworkError::Internal( return Response::network_error(NetworkError::Internal(
"Couldn't find response in cache".into(), "Couldn't find response in cache".into(),
)); ));
@ -1452,7 +1451,7 @@ async fn http_network_or_cache_fetch(
if let Some((200..=399, _)) = forward_response.raw_status { if let Some((200..=399, _)) = forward_response.raw_status {
if !http_request.method.is_safe() { if !http_request.method.is_safe() {
if let Ok(mut http_cache) = context.state.http_cache.write() { if let Ok(mut http_cache) = context.state.http_cache.write() {
http_cache.invalidate(&http_request, &forward_response); http_cache.invalidate(http_request, &forward_response);
} }
} }
} }
@ -1467,7 +1466,7 @@ async fn http_network_or_cache_fetch(
// Ensure done_chan is None, // Ensure done_chan is None,
// since the network response will be replaced by the revalidated stored one. // since the network response will be replaced by the revalidated stored one.
*done_chan = None; *done_chan = None;
response = http_cache.refresh(&http_request, forward_response.clone(), done_chan); response = http_cache.refresh(http_request, forward_response.clone(), done_chan);
} }
wait_for_cached_response(done_chan, &mut response).await; wait_for_cached_response(done_chan, &mut response).await;
} }
@ -1477,7 +1476,7 @@ async fn http_network_or_cache_fetch(
if http_request.cache_mode != CacheMode::NoStore { if http_request.cache_mode != CacheMode::NoStore {
// Subsubstep 2, doing it first to avoid a clone of forward_response. // Subsubstep 2, doing it first to avoid a clone of forward_response.
if let Ok(mut http_cache) = context.state.http_cache.write() { if let Ok(mut http_cache) = context.state.http_cache.write() {
http_cache.store(&http_request, &forward_response); http_cache.store(http_request, &forward_response);
} }
} }
// Subsubstep 1 // Subsubstep 1
@ -1488,7 +1487,7 @@ async fn http_network_or_cache_fetch(
let mut response = response.unwrap(); let mut response = response.unwrap();
// The cache has been updated, set its state to ready to construct. // The cache has been updated, set its state to ready to construct.
update_http_cache_state(context, &http_request); update_http_cache_state(context, http_request);
// Step 8 // Step 8
// TODO: if necessary set response's range-requested flag // TODO: if necessary set response's range-requested flag
@ -1537,7 +1536,7 @@ async fn http_network_or_cache_fetch(
// Step 5 // Step 5
if let Origin::Origin(ref request_origin) = request.origin { if let Origin::Origin(ref request_origin) = request.origin {
let schemeless_same_origin = let schemeless_same_origin =
is_schemelessy_same_site(&request_origin, &current_url_origin); is_schemelessy_same_site(request_origin, &current_url_origin);
if schemeless_same_origin && if schemeless_same_origin &&
(request_origin.scheme() == Some("https") || (request_origin.scheme() == Some("https") ||
response.https_state == HttpsState::None) response.https_state == HttpsState::None)
@ -1555,7 +1554,7 @@ async fn http_network_or_cache_fetch(
} }
if http_request.response_tainting != ResponseTainting::CorsTainting && if http_request.response_tainting != ResponseTainting::CorsTainting &&
cross_origin_resource_policy_check(&http_request, &response) == cross_origin_resource_policy_check(http_request, &response) ==
CrossOriginResourcePolicy::Blocked CrossOriginResourcePolicy::Blocked
{ {
return Response::network_error(NetworkError::Internal( return Response::network_error(NetworkError::Internal(
@ -1722,7 +1721,7 @@ async fn http_network_fetch(
.map(|body| body.source_is_null()) .map(|body| body.source_is_null())
.unwrap_or(false), .unwrap_or(false),
&request.pipeline_id, &request.pipeline_id,
request_id.as_ref().map(Deref::deref), request_id.as_deref(),
is_xhr, is_xhr,
context, context,
fetch_terminated_sender, fetch_terminated_sender,
@ -1796,7 +1795,7 @@ async fn http_network_fetch(
)); ));
response.headers = res.headers().clone(); response.headers = res.headers().clone();
response.referrer = request.referrer.to_url().cloned(); response.referrer = request.referrer.to_url().cloned();
response.referrer_policy = request.referrer_policy.clone(); response.referrer_policy = request.referrer_policy;
let res_body = response.body.clone(); let res_body = response.body.clone();
@ -1834,7 +1833,7 @@ async fn http_network_fetch(
send_response_to_devtools( send_response_to_devtools(
&sender, &sender,
request_id.unwrap(), request_id.unwrap(),
meta_headers.map(|hdrs| Serde::into_inner(hdrs)), meta_headers.map(Serde::into_inner),
meta_status, meta_status,
pipeline_id, pipeline_id,
); );
@ -1852,7 +1851,6 @@ async fn http_network_fetch(
res.into_body() res.into_body()
.map_err(|e| { .map_err(|e| {
warn!("Error streaming response body: {:?}", e); warn!("Error streaming response body: {:?}", e);
()
}) })
.try_fold(res_body, move |res_body, chunk| { .try_fold(res_body, move |res_body, chunk| {
if cancellation_listener.lock().unwrap().cancelled() { if cancellation_listener.lock().unwrap().cancelled() {
@ -1862,7 +1860,7 @@ async fn http_network_fetch(
} }
if let ResponseBody::Receiving(ref mut body) = *res_body.lock().unwrap() { if let ResponseBody::Receiving(ref mut body) = *res_body.lock().unwrap() {
let bytes = chunk; let bytes = chunk;
body.extend_from_slice(&*bytes); body.extend_from_slice(&bytes);
let _ = done_sender.send(Data::Payload(bytes.to_vec())); let _ = done_sender.send(Data::Payload(bytes.to_vec()));
} }
future::ready(Ok(res_body)) future::ready(Ok(res_body))
@ -1871,7 +1869,7 @@ async fn http_network_fetch(
debug!("successfully finished response for {:?}", url1); debug!("successfully finished response for {:?}", url1);
let mut body = res_body.lock().unwrap(); let mut body = res_body.lock().unwrap();
let completed_body = match *body { let completed_body = match *body {
ResponseBody::Receiving(ref mut body) => mem::replace(body, vec![]), ResponseBody::Receiving(ref mut body) => std::mem::take(body),
_ => vec![], _ => vec![],
}; };
*body = ResponseBody::Done(completed_body); *body = ResponseBody::Done(completed_body);
@ -1886,7 +1884,7 @@ async fn http_network_fetch(
debug!("finished response for {:?}", url2); debug!("finished response for {:?}", url2);
let mut body = res_body2.lock().unwrap(); let mut body = res_body2.lock().unwrap();
let completed_body = match *body { let completed_body = match *body {
ResponseBody::Receiving(ref mut body) => mem::replace(body, vec![]), ResponseBody::Receiving(ref mut body) => std::mem::take(body),
_ => vec![], _ => vec![],
}; };
*body = ResponseBody::Done(completed_body); *body = ResponseBody::Done(completed_body);
@ -1913,16 +1911,6 @@ async fn http_network_fetch(
// Step 6-11 // Step 6-11
// (needs stream bodies) // (needs stream bodies)
// Step 12
// TODO when https://bugzilla.mozilla.org/show_bug.cgi?id=1030660
// is resolved, this step will become uneccesary
// TODO this step
if let Some(encoding) = response.headers.typed_get::<ContentEncoding>() {
if encoding.contains("gzip") {
} else if encoding.contains("compress") {
}
};
// Step 13 // Step 13
// TODO this step isn't possible yet (CSP) // TODO this step isn't possible yet (CSP)
@ -1974,8 +1962,8 @@ async fn cors_preflight_fetch(
Origin::Origin(origin) => origin.clone(), Origin::Origin(origin) => origin.clone(),
}) })
.pipeline_id(request.pipeline_id) .pipeline_id(request.pipeline_id)
.initiator(request.initiator.clone()) .initiator(request.initiator)
.destination(request.destination.clone()) .destination(request.destination)
.referrer_policy(request.referrer_policy) .referrer_policy(request.referrer_policy)
.mode(RequestMode::CorsMode) .mode(RequestMode::CorsMode)
.response_tainting(ResponseTainting::CorsTainting) .response_tainting(ResponseTainting::CorsTainting)
@ -2007,7 +1995,7 @@ async fn cors_preflight_fetch(
let response = let response =
http_network_or_cache_fetch(&mut preflight, false, false, &mut None, context).await; http_network_or_cache_fetch(&mut preflight, false, false, &mut None, context).await;
// Step 7 // Step 7
if cors_check(&request, &response).is_ok() && if cors_check(request, &response).is_ok() &&
response response
.status .status
.as_ref() .as_ref()
@ -2079,7 +2067,7 @@ async fn cors_preflight_fetch(
// Substep 6 // Substep 6
if request.headers.iter().any(|(name, _)| { if request.headers.iter().any(|(name, _)| {
is_cors_non_wildcard_request_header_name(&name) && is_cors_non_wildcard_request_header_name(name) &&
header_names.iter().all(|hn| hn != name) header_names.iter().all(|hn| hn != name)
}) { }) {
return Response::network_error(NetworkError::Internal( return Response::network_error(NetworkError::Internal(
@ -2116,12 +2104,12 @@ async fn cors_preflight_fetch(
// Substep 12, 13 // Substep 12, 13
for method in &methods { for method in &methods {
cache.match_method_and_update(&*request, method.clone(), max_age); cache.match_method_and_update(request, method.clone(), max_age);
} }
// Substep 14, 15 // Substep 14, 15
for header_name in &header_names { for header_name in &header_names {
cache.match_header_and_update(&*request, &*header_name, max_age); cache.match_header_and_update(request, header_name, max_age);
} }
// Substep 16 // Substep 16

View file

@ -44,14 +44,11 @@ use crate::resource_thread::CoreResourceThreadPool;
fn decode_bytes_sync(key: LoadKey, bytes: &[u8], cors: CorsStatus) -> DecoderMsg { fn decode_bytes_sync(key: LoadKey, bytes: &[u8], cors: CorsStatus) -> DecoderMsg {
let image = load_from_memory(bytes, cors); let image = load_from_memory(bytes, cors);
DecoderMsg { DecoderMsg { key, image }
key: key,
image: image,
}
} }
fn get_placeholder_image(webrender_api: &WebrenderIpcSender, data: &[u8]) -> Arc<Image> { fn get_placeholder_image(webrender_api: &WebrenderIpcSender, data: &[u8]) -> Arc<Image> {
let mut image = load_from_memory(&data, CorsStatus::Unsafe).unwrap(); let mut image = load_from_memory(data, CorsStatus::Unsafe).unwrap();
set_webrender_image_key(webrender_api, &mut image); set_webrender_image_key(webrender_api, &mut image);
Arc::new(image) Arc::new(image)
} }
@ -63,7 +60,7 @@ fn set_webrender_image_key(webrender_api: &WebrenderIpcSender, image: &mut Image
let mut bytes = Vec::new(); let mut bytes = Vec::new();
let is_opaque = match image.format { let is_opaque = match image.format {
PixelFormat::BGRA8 => { PixelFormat::BGRA8 => {
bytes.extend_from_slice(&*image.bytes); bytes.extend_from_slice(&image.bytes);
pixels::rgba8_premultiply_inplace(bytes.as_mut_slice()) pixels::rgba8_premultiply_inplace(bytes.as_mut_slice())
}, },
PixelFormat::RGB8 => { PixelFormat::RGB8 => {
@ -130,7 +127,7 @@ impl AllPendingLoads {
} }
fn remove(&mut self, key: &LoadKey) -> Option<PendingLoad> { fn remove(&mut self, key: &LoadKey) -> Option<PendingLoad> {
self.loads.remove(key).and_then(|pending_load| { self.loads.remove(key).map(|pending_load| {
self.url_to_load_key self.url_to_load_key
.remove(&( .remove(&(
pending_load.url.clone(), pending_load.url.clone(),
@ -138,16 +135,16 @@ impl AllPendingLoads {
pending_load.cors_setting, pending_load.cors_setting,
)) ))
.unwrap(); .unwrap();
Some(pending_load) pending_load
}) })
} }
fn get_cached<'a>( fn get_cached(
&'a mut self, &mut self,
url: ServoUrl, url: ServoUrl,
origin: ImmutableOrigin, origin: ImmutableOrigin,
cors_status: Option<CorsSettings>, cors_status: Option<CorsSettings>,
) -> CacheResult<'a> { ) -> CacheResult<'_> {
match self match self
.url_to_load_key .url_to_load_key
.entry((url.clone(), origin.clone(), cors_status)) .entry((url.clone(), origin.clone(), cors_status))
@ -192,10 +189,7 @@ struct CompletedLoad {
impl CompletedLoad { impl CompletedLoad {
fn new(image_response: ImageResponse, id: PendingImageId) -> CompletedLoad { fn new(image_response: ImageResponse, id: PendingImageId) -> CompletedLoad {
CompletedLoad { CompletedLoad { image_response, id }
image_response: image_response,
id: id,
}
} }
} }
@ -224,7 +218,7 @@ impl ImageBytes {
ImageBytes::InProgress(ref mut bytes) => bytes, ImageBytes::InProgress(ref mut bytes) => bytes,
ImageBytes::Complete(_) => panic!("attempted modification of complete image bytes"), ImageBytes::Complete(_) => panic!("attempted modification of complete image bytes"),
}; };
mem::replace(own_bytes, vec![]) std::mem::take(own_bytes)
}; };
let bytes = Arc::new(bytes); let bytes = Arc::new(bytes);
*self = ImageBytes::Complete(bytes.clone()); *self = ImageBytes::Complete(bytes.clone());
@ -233,8 +227,8 @@ impl ImageBytes {
fn as_slice(&self) -> &[u8] { fn as_slice(&self) -> &[u8] {
match *self { match *self {
ImageBytes::InProgress(ref bytes) => &bytes, ImageBytes::InProgress(ref bytes) => bytes,
ImageBytes::Complete(ref bytes) => &*bytes, ImageBytes::Complete(ref bytes) => bytes,
} }
} }
} }
@ -307,7 +301,7 @@ impl PendingLoad {
metadata: None, metadata: None,
result: None, result: None,
listeners: vec![], listeners: vec![],
url: url, url,
load_origin, load_origin,
final_url: None, final_url: None,
cors_setting, cors_setting,
@ -368,7 +362,7 @@ impl ImageCacheStore {
let completed_load = CompletedLoad::new(image_response.clone(), key); let completed_load = CompletedLoad::new(image_response.clone(), key);
self.completed_loads.insert( self.completed_loads.insert(
( (
pending_load.url.into(), pending_load.url,
pending_load.load_origin, pending_load.load_origin,
pending_load.cors_setting, pending_load.cors_setting,
), ),
@ -441,7 +435,7 @@ impl ImageCache for ImageCacheImpl {
completed_loads: HashMap::new(), completed_loads: HashMap::new(),
placeholder_image: get_placeholder_image(&webrender_api, &rippy_data), placeholder_image: get_placeholder_image(&webrender_api, &rippy_data),
placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(), placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(),
webrender_api: webrender_api, webrender_api,
})), })),
thread_pool: CoreResourceThreadPool::new(thread_count), thread_pool: CoreResourceThreadPool::new(thread_count),
} }
@ -501,9 +495,9 @@ impl ImageCache for ImageCacheImpl {
CacheResult::Hit(key, pl) => match (&pl.result, &pl.metadata) { CacheResult::Hit(key, pl) => match (&pl.result, &pl.metadata) {
(&Some(Ok(_)), _) => { (&Some(Ok(_)), _) => {
debug!("Sync decoding {} ({:?})", url, key); debug!("Sync decoding {} ({:?})", url, key);
decode_bytes_sync(key, &pl.bytes.as_slice(), pl.cors_status) decode_bytes_sync(key, pl.bytes.as_slice(), pl.cors_status)
}, },
(&None, &Some(ref meta)) => { (&None, Some(meta)) => {
debug!("Metadata available for {} ({:?})", url, key); debug!("Metadata available for {} ({:?})", url, key);
return ImageCacheResult::Available( return ImageCacheResult::Available(
ImageOrMetadataAvailable::MetadataAvailable(meta.clone()), ImageOrMetadataAvailable::MetadataAvailable(meta.clone()),
@ -589,7 +583,7 @@ impl ImageCache for ImageCacheImpl {
fn notify_pending_response(&self, id: PendingImageId, action: FetchResponseMsg) { fn notify_pending_response(&self, id: PendingImageId, action: FetchResponseMsg) {
match (action, id) { match (action, id) {
(FetchResponseMsg::ProcessRequestBody, _) | (FetchResponseMsg::ProcessRequestBody, _) |
(FetchResponseMsg::ProcessRequestEOF, _) => return, (FetchResponseMsg::ProcessRequestEOF, _) => (),
(FetchResponseMsg::ProcessResponse(response), _) => { (FetchResponseMsg::ProcessResponse(response), _) => {
debug!("Received {:?} for {:?}", response.as_ref().map(|_| ()), id); debug!("Received {:?} for {:?}", response.as_ref().map(|_| ()), id);
let mut store = self.store.lock().unwrap(); let mut store = self.store.lock().unwrap();
@ -648,7 +642,7 @@ impl ImageCache for ImageCacheImpl {
let local_store = self.store.clone(); let local_store = self.store.clone();
self.thread_pool.spawn(move || { self.thread_pool.spawn(move || {
let msg = decode_bytes_sync(key, &*bytes, cors_status); let msg = decode_bytes_sync(key, &bytes, cors_status);
debug!("Image decoded"); debug!("Image decoded");
local_store.lock().unwrap().handle_decoder(msg); local_store.lock().unwrap().handle_decoder(msg);
}); });

View file

@ -49,6 +49,21 @@ pub enum NoSniffFlag {
Off, Off,
} }
impl Default for MimeClassifier {
fn default() -> Self {
Self {
image_classifier: GroupedClassifier::image_classifer(),
audio_video_classifier: GroupedClassifier::audio_video_classifier(),
scriptable_classifier: GroupedClassifier::scriptable_classifier(),
plaintext_classifier: GroupedClassifier::plaintext_classifier(),
archive_classifier: GroupedClassifier::archive_classifier(),
binary_or_plaintext: BinaryOrPlaintextClassifier,
feeds_classifier: FeedsClassifier,
font_classifier: GroupedClassifier::font_classifier(),
}
}
}
impl MimeClassifier { impl MimeClassifier {
//Performs MIME Type Sniffing Algorithm (sections 7 and 8) //Performs MIME Type Sniffing Algorithm (sections 7 and 8)
pub fn classify<'a>( pub fn classify<'a>(
@ -164,19 +179,6 @@ impl MimeClassifier {
} }
} }
pub fn new() -> MimeClassifier {
MimeClassifier {
image_classifier: GroupedClassifier::image_classifer(),
audio_video_classifier: GroupedClassifier::audio_video_classifier(),
scriptable_classifier: GroupedClassifier::scriptable_classifier(),
plaintext_classifier: GroupedClassifier::plaintext_classifier(),
archive_classifier: GroupedClassifier::archive_classifier(),
binary_or_plaintext: BinaryOrPlaintextClassifier,
feeds_classifier: FeedsClassifier,
font_classifier: GroupedClassifier::font_classifier(),
}
}
pub fn validate(&self) -> Result<(), String> { pub fn validate(&self) -> Result<(), String> {
self.image_classifier.validate()?; self.image_classifier.validate()?;
self.audio_video_classifier.validate()?; self.audio_video_classifier.validate()?;
@ -240,13 +242,13 @@ impl MimeClassifier {
} }
fn get_media_type(mime: &Mime) -> Option<MediaType> { fn get_media_type(mime: &Mime) -> Option<MediaType> {
if MimeClassifier::is_xml(&mime) { if MimeClassifier::is_xml(mime) {
Some(MediaType::Xml) Some(MediaType::Xml)
} else if MimeClassifier::is_html(&mime) { } else if MimeClassifier::is_html(mime) {
Some(MediaType::Html) Some(MediaType::Html)
} else if MimeClassifier::is_image(&mime) { } else if MimeClassifier::is_image(mime) {
Some(MediaType::Image) Some(MediaType::Image)
} else if MimeClassifier::is_audio_video(&mime) { } else if MimeClassifier::is_audio_video(mime) {
Some(MediaType::AudioVideo) Some(MediaType::AudioVideo)
} else { } else {
None None
@ -256,7 +258,7 @@ impl MimeClassifier {
fn maybe_get_media_type(supplied_type: &Option<Mime>) -> Option<MediaType> { fn maybe_get_media_type(supplied_type: &Option<Mime>) -> Option<MediaType> {
supplied_type supplied_type
.as_ref() .as_ref()
.and_then(|ref mime| MimeClassifier::get_media_type(mime)) .and_then(MimeClassifier::get_media_type)
} }
} }
@ -338,7 +340,7 @@ impl MIMEChecker for ByteMatcher {
} }
fn validate(&self) -> Result<(), String> { fn validate(&self) -> Result<(), String> {
if self.pattern.len() == 0 { if self.pattern.is_empty() {
return Err(format!("Zero length pattern for {:?}", self.content_type)); return Err(format!("Zero length pattern for {:?}", self.content_type));
} }
if self.pattern.len() != self.mask.len() { if self.pattern.len() != self.mask.len() {
@ -436,8 +438,8 @@ impl BinaryOrPlaintextClassifier {
} else if data.iter().any(|&x| { } else if data.iter().any(|&x| {
x <= 0x08u8 || x <= 0x08u8 ||
x == 0x0Bu8 || x == 0x0Bu8 ||
(x >= 0x0Eu8 && x <= 0x1Au8) || (0x0Eu8..=0x1Au8).contains(&x) ||
(x >= 0x1Cu8 && x <= 0x1Fu8) (0x1Cu8..=0x1Fu8).contains(&x)
}) { }) {
mime::APPLICATION_OCTET_STREAM mime::APPLICATION_OCTET_STREAM
} else { } else {
@ -618,7 +620,7 @@ impl FeedsClassifier {
// TODO: need max_bytes to prevent inadvertently examining html document // TODO: need max_bytes to prevent inadvertently examining html document
// eg. an html page with a feed example // eg. an html page with a feed example
loop { loop {
if matcher.find(|&x| *x == b'<').is_none() { if !matcher.any(|x| *x == b'<') {
return None; return None;
} }

View file

@ -9,7 +9,6 @@ use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::{self, BufReader}; use std::io::{self, BufReader};
use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use std::thread; use std::thread;
@ -160,8 +159,8 @@ fn create_http_states(
ignore_certificate_errors: bool, ignore_certificate_errors: bool,
) -> (Arc<HttpState>, Arc<HttpState>) { ) -> (Arc<HttpState>, Arc<HttpState>) {
let mut hsts_list = HstsList::from_servo_preload(); let mut hsts_list = HstsList::from_servo_preload();
let mut auth_cache = AuthCache::new(); let mut auth_cache = AuthCache::default();
let http_cache = HttpCache::new(); let http_cache = HttpCache::default();
let mut cookie_jar = CookieStorage::new(150); let mut cookie_jar = CookieStorage::new(150);
if let Some(config_dir) = config_dir { if let Some(config_dir) = config_dir {
read_json_from_file(&mut auth_cache, config_dir, "auth_cache.json"); read_json_from_file(&mut auth_cache, config_dir, "auth_cache.json");
@ -189,9 +188,9 @@ fn create_http_states(
let private_http_state = HttpState { let private_http_state = HttpState {
hsts_list: RwLock::new(HstsList::from_servo_preload()), hsts_list: RwLock::new(HstsList::from_servo_preload()),
cookie_jar: RwLock::new(CookieStorage::new(150)), cookie_jar: RwLock::new(CookieStorage::new(150)),
auth_cache: RwLock::new(AuthCache::new()), auth_cache: RwLock::new(AuthCache::default()),
history_states: RwLock::new(HashMap::new()), history_states: RwLock::new(HashMap::new()),
http_cache: RwLock::new(HttpCache::new()), http_cache: RwLock::new(HttpCache::default()),
http_cache_state: Mutex::new(HashMap::new()), http_cache_state: Mutex::new(HashMap::new()),
client: create_http_client(create_tls_config( client: create_http_client(create_tls_config(
ca_certificates, ca_certificates,
@ -213,7 +212,7 @@ impl ResourceChannelManager {
memory_reporter: IpcReceiver<ReportsChan>, memory_reporter: IpcReceiver<ReportsChan>,
) { ) {
let (public_http_state, private_http_state) = create_http_states( let (public_http_state, private_http_state) = create_http_states(
self.config_dir.as_ref().map(Deref::deref), self.config_dir.as_deref(),
self.ca_certificates.clone(), self.ca_certificates.clone(),
self.ignore_certificate_errors, self.ignore_certificate_errors,
); );
@ -426,11 +425,10 @@ pub fn write_json_to_file<T>(data: &T, config_dir: &Path, filename: &str)
where where
T: Serialize, T: Serialize,
{ {
let json_encoded: String; let json_encoded: String = match serde_json::to_string_pretty(&data) {
match serde_json::to_string_pretty(&data) { Ok(d) => d,
Ok(d) => json_encoded = d,
Err(_) => return, Err(_) => return,
} };
let path = config_dir.join(filename); let path = config_dir.join(filename);
let display = path.display(); let display = path.display();
@ -451,9 +449,9 @@ pub struct AuthCacheEntry {
pub password: String, pub password: String,
} }
impl AuthCache { impl Default for AuthCache {
pub fn new() -> AuthCache { fn default() -> Self {
AuthCache { Self {
version: 1, version: 1,
entries: HashMap::new(), entries: HashMap::new(),
} }
@ -531,7 +529,7 @@ impl CoreResourceThreadPool {
.build() .build()
.unwrap(); .unwrap();
let state = Arc::new(Mutex::new(ThreadPoolState::new())); let state = Arc::new(Mutex::new(ThreadPoolState::new()));
CoreResourceThreadPool { pool: pool, state } CoreResourceThreadPool { pool, state }
} }
/// Spawn work on the thread-pool, if still active. /// Spawn work on the thread-pool, if still active.
@ -613,7 +611,7 @@ impl CoreResourceManager {
let pool = CoreResourceThreadPool::new(16); let pool = CoreResourceThreadPool::new(16);
let pool_handle = Arc::new(pool); let pool_handle = Arc::new(pool);
CoreResourceManager { CoreResourceManager {
user_agent: user_agent, user_agent,
devtools_sender, devtools_sender,
sw_managers: Default::default(), sw_managers: Default::default(),
filemanager: FileManager::new(embedder_proxy, Arc::downgrade(&pool_handle)), filemanager: FileManager::new(embedder_proxy, Arc::downgrade(&pool_handle)),
@ -708,7 +706,7 @@ impl CoreResourceManager {
let response = Response::from_init(res_init, timing_type); let response = Response::from_init(res_init, timing_type);
http_redirect_fetch( http_redirect_fetch(
&mut request, &mut request,
&mut CorsCache::new(), &mut CorsCache::default(),
response, response,
true, true,
&mut sender, &mut sender,

View file

@ -47,10 +47,10 @@ impl StorageManager {
resource_thread::read_json_from_file(&mut local_data, config_dir, "local_data.json"); resource_thread::read_json_from_file(&mut local_data, config_dir, "local_data.json");
} }
StorageManager { StorageManager {
port: port, port,
session_data: HashMap::new(), session_data: HashMap::new(),
local_data: local_data, local_data,
config_dir: config_dir, config_dir,
} }
} }
} }
@ -122,7 +122,7 @@ impl StorageManager {
let origin = self.origin_as_string(url); let origin = self.origin_as_string(url);
let data = self.select_data(storage_type); let data = self.select_data(storage_type);
sender sender
.send(data.get(&origin).map_or(0, |&(_, ref entry)| entry.len())) .send(data.get(&origin).map_or(0, |(_, entry)| entry.len()))
.unwrap(); .unwrap();
} }
@ -137,7 +137,7 @@ impl StorageManager {
let data = self.select_data(storage_type); let data = self.select_data(storage_type);
let key = data let key = data
.get(&origin) .get(&origin)
.and_then(|&(_, ref entry)| entry.keys().nth(index as usize)) .and_then(|(_, entry)| entry.keys().nth(index as usize))
.cloned(); .cloned();
sender.send(key).unwrap(); sender.send(key).unwrap();
} }
@ -147,7 +147,7 @@ impl StorageManager {
let data = self.select_data(storage_type); let data = self.select_data(storage_type);
let keys = data let keys = data
.get(&origin) .get(&origin)
.map_or(vec![], |&(_, ref entry)| entry.keys().cloned().collect()); .map_or(vec![], |(_, entry)| entry.keys().cloned().collect());
sender.send(keys).unwrap(); sender.send(keys).unwrap();
} }
@ -225,7 +225,7 @@ impl StorageManager {
sender sender
.send( .send(
data.get(&origin) data.get(&origin)
.and_then(|&(_, ref entry)| entry.get(&name)) .and_then(|(_, entry)| entry.get(&name))
.map(String::clone), .map(String::clone),
) )
.unwrap(); .unwrap();
@ -244,9 +244,9 @@ impl StorageManager {
let old_value = data let old_value = data
.get_mut(&origin) .get_mut(&origin)
.and_then(|&mut (ref mut total, ref mut entry)| { .and_then(|&mut (ref mut total, ref mut entry)| {
entry.remove(&name).and_then(|old| { entry.remove(&name).map(|old| {
*total -= name.as_bytes().len() + old.as_bytes().len(); *total -= name.as_bytes().len() + old.as_bytes().len();
Some(old) old
}) })
}); });
sender.send(old_value).unwrap(); sender.send(old_value).unwrap();

View file

@ -11,7 +11,7 @@ use generic_array::ArrayLength;
use net_traits::response::{Response, ResponseBody, ResponseType}; use net_traits::response::{Response, ResponseBody, ResponseType};
use sha2::{Digest, Sha256, Sha384, Sha512}; use sha2::{Digest, Sha256, Sha384, Sha512};
const SUPPORTED_ALGORITHM: &'static [&'static str] = &["sha256", "sha384", "sha512"]; const SUPPORTED_ALGORITHM: &[&str] = &["sha256", "sha384", "sha512"];
pub type StaticCharVec = &'static [char]; pub type StaticCharVec = &'static [char];
/// A "space character" according to: /// A "space character" according to:
/// ///
@ -33,7 +33,7 @@ impl SriEntry {
SriEntry { SriEntry {
alg: alg.to_owned(), alg: alg.to_owned(),
val: val.to_owned(), val: val.to_owned(),
opt: opt, opt,
} }
} }
} }
@ -46,7 +46,7 @@ pub fn parsed_metadata(integrity_metadata: &str) -> Vec<SriEntry> {
// Step 3 // Step 3
let tokens = split_html_space_chars(integrity_metadata); let tokens = split_html_space_chars(integrity_metadata);
for token in tokens { for token in tokens {
let parsed_data: Vec<&str> = token.split("-").collect(); let parsed_data: Vec<&str> = token.split('-').collect();
if parsed_data.len() > 1 { if parsed_data.len() > 1 {
let alg = parsed_data[0]; let alg = parsed_data[0];
@ -55,7 +55,7 @@ pub fn parsed_metadata(integrity_metadata: &str) -> Vec<SriEntry> {
continue; continue;
} }
let data: Vec<&str> = parsed_data[1].split("?").collect(); let data: Vec<&str> = parsed_data[1].split('?').collect();
let digest = data[0]; let digest = data[0];
let opt = if data.len() > 1 { let opt = if data.len() > 1 {
@ -68,7 +68,7 @@ pub fn parsed_metadata(integrity_metadata: &str) -> Vec<SriEntry> {
} }
} }
return result; result
} }
/// <https://w3c.github.io/webappsec-subresource-integrity/#getprioritizedhashfunction> /// <https://w3c.github.io/webappsec-subresource-integrity/#getprioritizedhashfunction>
@ -78,11 +78,11 @@ pub fn get_prioritized_hash_function(
) -> Option<String> { ) -> Option<String> {
let left_priority = SUPPORTED_ALGORITHM let left_priority = SUPPORTED_ALGORITHM
.iter() .iter()
.position(|s| s.to_owned() == hash_func_left) .position(|s| *s == hash_func_left)
.unwrap(); .unwrap();
let right_priority = SUPPORTED_ALGORITHM let right_priority = SUPPORTED_ALGORITHM
.iter() .iter()
.position(|s| s.to_owned() == hash_func_right) .position(|s| *s == hash_func_right)
.unwrap(); .unwrap();
if left_priority == right_priority { if left_priority == right_priority {
@ -102,7 +102,7 @@ pub fn get_strongest_metadata(integrity_metadata_list: Vec<SriEntry>) -> Vec<Sri
for integrity_metadata in &integrity_metadata_list[1..] { for integrity_metadata in &integrity_metadata_list[1..] {
let prioritized_hash = let prioritized_hash =
get_prioritized_hash_function(&integrity_metadata.alg, &*current_algorithm); get_prioritized_hash_function(&integrity_metadata.alg, &current_algorithm);
if prioritized_hash.is_none() { if prioritized_hash.is_none() {
result.push(integrity_metadata.clone()); result.push(integrity_metadata.clone());
} else if let Some(algorithm) = prioritized_hash { } else if let Some(algorithm) = prioritized_hash {
@ -174,9 +174,7 @@ pub fn is_response_integrity_valid(integrity_metadata: &str, response: &Response
false false
} }
pub fn split_html_space_chars<'a>( pub fn split_html_space_chars(s: &str) -> Filter<Split<'_, StaticCharVec>, fn(&&str) -> bool> {
s: &'a str,
) -> Filter<Split<'a, StaticCharVec>, fn(&&str) -> bool> {
fn not_empty(&split: &&str) -> bool { fn not_empty(&split: &&str) -> bool {
!split.is_empty() !split.is_empty()
} }

View file

@ -385,7 +385,7 @@ fn test_cors_preflight_cache_fetch() {
static ACK: &'static [u8] = b"ACK"; static ACK: &'static [u8] = b"ACK";
let state = Arc::new(AtomicUsize::new(0)); let state = Arc::new(AtomicUsize::new(0));
let counter = state.clone(); let counter = state.clone();
let mut cache = CorsCache::new(); let mut cache = CorsCache::default();
let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| { let handler = move |request: HyperRequest<Body>, response: &mut HyperResponse<Body>| {
if request.method() == Method::OPTIONS && state.clone().fetch_add(1, Ordering::SeqCst) == 0 if request.method() == Method::OPTIONS && state.clone().fetch_add(1, Ordering::SeqCst) == 0
{ {
@ -757,7 +757,7 @@ fn test_fetch_with_hsts() {
let (server, url) = make_ssl_server(handler); let (server, url) = make_ssl_server(handler);
let mut context = FetchContext { let mut context = FetchContext {
state: Arc::new(HttpState::new()), state: Arc::new(HttpState::default()),
user_agent: DEFAULT_USER_AGENT.into(), user_agent: DEFAULT_USER_AGENT.into(),
devtools_chan: None, devtools_chan: None,
filemanager: Arc::new(Mutex::new(FileManager::new( filemanager: Arc::new(Mutex::new(FileManager::new(
@ -816,7 +816,7 @@ fn test_load_adds_host_to_hsts_list_when_url_is_https() {
url.as_mut_url().set_scheme("https").unwrap(); url.as_mut_url().set_scheme("https").unwrap();
let mut context = FetchContext { let mut context = FetchContext {
state: Arc::new(HttpState::new()), state: Arc::new(HttpState::default()),
user_agent: DEFAULT_USER_AGENT.into(), user_agent: DEFAULT_USER_AGENT.into(),
devtools_chan: None, devtools_chan: None,
filemanager: Arc::new(Mutex::new(FileManager::new( filemanager: Arc::new(Mutex::new(FileManager::new(
@ -873,7 +873,7 @@ fn test_fetch_self_signed() {
url.as_mut_url().set_scheme("https").unwrap(); url.as_mut_url().set_scheme("https").unwrap();
let mut context = FetchContext { let mut context = FetchContext {
state: Arc::new(HttpState::new()), state: Arc::new(HttpState::default()),
user_agent: DEFAULT_USER_AGENT.into(), user_agent: DEFAULT_USER_AGENT.into(),
devtools_chan: None, devtools_chan: None,
filemanager: Arc::new(Mutex::new(FileManager::new( filemanager: Arc::new(Mutex::new(FileManager::new(

View file

@ -33,7 +33,7 @@ fn test_refreshing_resource_sets_done_chan_the_appropriate_value() {
response response
.headers .headers
.insert(EXPIRES, HeaderValue::from_str("-10").unwrap()); .insert(EXPIRES, HeaderValue::from_str("-10").unwrap());
let mut cache = HttpCache::new(); let mut cache = HttpCache::default();
response_bodies.iter().for_each(|body| { response_bodies.iter().for_each(|body| {
*response.body.lock().unwrap() = body.clone(); *response.body.lock().unwrap() = body.clone();
// First, store the 'normal' response. // First, store the 'normal' response.

View file

@ -103,7 +103,7 @@ fn new_fetch_context(
let sender = fc.unwrap_or_else(|| create_embedder_proxy()); let sender = fc.unwrap_or_else(|| create_embedder_proxy());
FetchContext { FetchContext {
state: Arc::new(HttpState::new()), state: Arc::new(HttpState::default()),
user_agent: DEFAULT_USER_AGENT.into(), user_agent: DEFAULT_USER_AGENT.into(),
devtools_chan: dc.map(|dc| Arc::new(Mutex::new(dc))), devtools_chan: dc.map(|dc| Arc::new(Mutex::new(dc))),
filemanager: Arc::new(Mutex::new(FileManager::new( filemanager: Arc::new(Mutex::new(FileManager::new(

View file

@ -53,7 +53,7 @@ fn test_sniff_mp4_matcher_long() {
#[test] #[test]
fn test_validate_classifier() { fn test_validate_classifier() {
let classifier = MimeClassifier::new(); let classifier = MimeClassifier::default();
classifier.validate().expect("Validation error") classifier.validate().expect("Validation error")
} }
@ -74,7 +74,7 @@ fn test_sniff_with_flags(
let mut filename = PathBuf::from("tests/parsable_mime/"); let mut filename = PathBuf::from("tests/parsable_mime/");
filename.push(filename_orig); filename.push(filename_orig);
let classifier = MimeClassifier::new(); let classifier = MimeClassifier::default();
let read_result = read_file(&filename); let read_result = read_file(&filename);

View file

@ -94,7 +94,7 @@ fn create_request(
} }
if resource_url.password().is_some() || resource_url.username() != "" { if resource_url.password().is_some() || resource_url.username() != "" {
let basic = base64::engine::general_purpose::STANDARD.encode(&format!( let basic = base64::engine::general_purpose::STANDARD.encode(format!(
"{}:{}", "{}:{}",
resource_url.username(), resource_url.username(),
resource_url.password().unwrap_or("") resource_url.password().unwrap_or("")
@ -147,7 +147,7 @@ fn process_ws_response(
.hsts_list .hsts_list
.write() .write()
.unwrap() .unwrap()
.update_hsts_list_from_response(resource_url, &response.headers()); .update_hsts_list_from_response(resource_url, response.headers());
Ok(protocol_in_use) Ok(protocol_in_use)
} }
@ -389,7 +389,7 @@ fn connect(
&req_url, &req_url,
&req_builder.origin.ascii_serialization(), &req_builder.origin.ascii_serialization(),
&protocols, &protocols,
&*http_state, &http_state,
) { ) {
Ok(c) => c, Ok(c) => c,
Err(e) => return Err(e.to_string()), Err(e) => return Err(e.to_string()),