mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
servo: Merge #6722 - Obey Strict-Transport-Security header (from samfoo:sts-headers); r=jdm
Resolves #6703. Done: * [x] When STS headers received, add the host to the HSTS list Todo: * [ ] Persist the in-memory list so that it's reloaded on the next browser boot * [ ] Add tests to `http_loader::load` - it's pretty well completely untested right now, but it's a bit gnarly to untangle and without mocking, it's hard to deal with the dependency on making a real network request. Writing a mock request object should be doable for testing, but there's a lot going on in the function right now. Source-Repo: https://github.com/servo/servo Source-Revision: f1c26c59f177570a697c420308fb89d9773c7468
This commit is contained in:
parent
e69b59f7ca
commit
34d2f0c3a8
@ -2,7 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer};
|
||||
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer, IncludeSubdomains};
|
||||
use net_traits::ProgressMsg::{Payload, Done};
|
||||
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent};
|
||||
use mime_classifier::MIMEClassifier;
|
||||
@ -15,8 +15,8 @@ use std::collections::HashSet;
|
||||
use file_loader;
|
||||
use flate2::read::{DeflateDecoder, GzDecoder};
|
||||
use hyper::client::Request;
|
||||
use hyper::header::{AcceptEncoding, Accept, ContentLength, ContentType, Host, Location, qitem};
|
||||
use hyper::header::{Quality, QualityItem};
|
||||
use hyper::header::{AcceptEncoding, Accept, ContentLength, ContentType, Host, Location, qitem, Quality, QualityItem};
|
||||
use hyper::header::StrictTransportSecurity;
|
||||
use hyper::Error as HttpError;
|
||||
use hyper::method::Method;
|
||||
use hyper::mime::{Mime, TopLevel, SubLevel};
|
||||
@ -37,13 +37,13 @@ use uuid;
|
||||
use std::borrow::ToOwned;
|
||||
use std::boxed::FnBox;
|
||||
|
||||
pub fn factory(cookies_chan: IpcSender<ControlMsg>,
|
||||
pub fn factory(resource_mgr_chan: IpcSender<ControlMsg>,
|
||||
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||
hsts_list: Arc<Mutex<HSTSList>>)
|
||||
-> Box<FnBox(LoadData, LoadConsumer, Arc<MIMEClassifier>) + Send> {
|
||||
box move |load_data, senders, classifier| {
|
||||
spawn_named("http_loader".to_owned(),
|
||||
move || load(load_data, senders, classifier, cookies_chan, devtools_chan, hsts_list))
|
||||
move || load(load_data, senders, classifier, resource_mgr_chan, devtools_chan, hsts_list))
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ fn request_must_be_secured(hsts_list: &HSTSList, url: &Url) -> bool {
|
||||
fn load(mut load_data: LoadData,
|
||||
start_chan: LoadConsumer,
|
||||
classifier: Arc<MIMEClassifier>,
|
||||
cookies_chan: IpcSender<ControlMsg>,
|
||||
resource_mgr_chan: IpcSender<ControlMsg>,
|
||||
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||
hsts_list: Arc<Mutex<HSTSList>>) {
|
||||
// FIXME: At the time of writing this FIXME, servo didn't have any central
|
||||
@ -204,7 +204,7 @@ reason: \"certificate verify failed\" }]))";
|
||||
}
|
||||
|
||||
let (tx, rx) = ipc::channel().unwrap();
|
||||
cookies_chan.send(ControlMsg::GetCookiesForUrl(url.clone(),
|
||||
resource_mgr_chan.send(ControlMsg::GetCookiesForUrl(url.clone(),
|
||||
tx,
|
||||
CookieSource::HTTP)).unwrap();
|
||||
if let Some(cookie_list) = rx.recv().unwrap() {
|
||||
@ -291,13 +291,36 @@ reason: \"certificate verify failed\" }]))";
|
||||
if let Some(cookies) = response.headers.get_raw("set-cookie") {
|
||||
for cookie in cookies.iter() {
|
||||
if let Ok(cookies) = String::from_utf8(cookie.clone()) {
|
||||
cookies_chan.send(ControlMsg::SetCookiesForUrl(url.clone(),
|
||||
cookies,
|
||||
CookieSource::HTTP)).unwrap();
|
||||
resource_mgr_chan.send(ControlMsg::SetCookiesForUrl(url.clone(),
|
||||
cookies,
|
||||
CookieSource::HTTP)).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if url.scheme == "https" {
|
||||
if let Some(header) = response.headers.get::<StrictTransportSecurity>() {
|
||||
if let Some(host) = url.domain() {
|
||||
info!("adding host {} to the strict transport security list", host);
|
||||
info!("- max-age {}", header.max_age);
|
||||
|
||||
let include_subdomains = if header.include_subdomains {
|
||||
info!("- includeSubdomains");
|
||||
IncludeSubdomains::Included
|
||||
} else {
|
||||
IncludeSubdomains::NotIncluded
|
||||
};
|
||||
|
||||
resource_mgr_chan.send(
|
||||
ControlMsg::SetHSTSEntryForHost(
|
||||
host.to_string(), include_subdomains, header.max_age
|
||||
)
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if response.status.class() == StatusClass::Redirection {
|
||||
match response.headers.get::<Location>() {
|
||||
Some(&Location(ref new_url)) => {
|
||||
|
@ -238,7 +238,7 @@ impl ResourceChannelManager {
|
||||
consumer.send(self.resource_manager.cookie_storage.cookies_for_url(&url, source)).unwrap();
|
||||
}
|
||||
ControlMsg::SetHSTSEntryForHost(host, include_subdomains, max_age) => {
|
||||
if let Some(entry) = HSTSEntry::new(host, include_subdomains, max_age) {
|
||||
if let Some(entry) = HSTSEntry::new(host, include_subdomains, Some(max_age)) {
|
||||
self.resource_manager.add_hsts_entry(entry)
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ pub enum ControlMsg {
|
||||
/// Retrieve the stored cookies for a given URL
|
||||
GetCookiesForUrl(Url, IpcSender<Option<String>>, CookieSource),
|
||||
/// Store a domain's STS information
|
||||
SetHSTSEntryForHost(String, IncludeSubdomains, Option<u64>),
|
||||
SetHSTSEntryForHost(String, IncludeSubdomains, u64),
|
||||
Exit
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user