Auto merge of #14716 - mrnayak:hsts, r=jdm

Implement HSTS fetch step

Implemented step nine of the main fetch. If current URL scheme is 'HTTP' and
current URL's host is domain and if current URL's host matched with Known
HSTS Host Domain Name Matching results in either a superdomain match with
an asserted includeSubDomains directive or a congruent match then we
change request scheme to 'https'. This change has been made in method.rs

A test case to validate this has been added in fetch.rs. For asserting
https scheme, a https localhost was required. For this purpose I have
created a self-signed certificate and refactored fetch-context and
connector.rs to programmatically trust this certificate for running this
test case.

This should fix https://github.com/servo/servo/issues/14363
<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #14363

<!-- Either: -->
- [X] There are tests for these changes

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14716)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-12-29 00:35:09 -08:00 committed by GitHub
commit c7991d596f
8 changed files with 117 additions and 9 deletions

View file

@ -27,11 +27,11 @@ const DEFAULT_CIPHERS: &'static str = concat!(
"AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
);
pub fn create_http_connector() -> Arc<Pool<Connector>> {
pub fn create_http_connector(certificate_file: &str) -> Arc<Pool<Connector>> {
let mut context = SslContext::new(SslMethod::Sslv23).unwrap();
context.set_CA_file(&resources_dir_path()
.expect("Need certificate file to make network requests")
.join("certs")).unwrap();
.join(certificate_file)).unwrap();
context.set_cipher_list(DEFAULT_CIPHERS).unwrap();
context.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
let connector = HttpsConnector::new(ServoSslClient {

View file

@ -189,7 +189,15 @@ pub fn main_fetch(request: Rc<Request>,
}
// Step 9
// TODO this step (HSTS)
if !request.current_url().is_secure_scheme() && request.current_url().domain().is_some() {
if context.state
.hsts_list
.read()
.unwrap()
.is_host_secure(request.current_url().domain().unwrap()) {
request.url_list.borrow_mut().last_mut().unwrap().as_mut_url().unwrap().set_scheme("https").unwrap();
}
}
// Step 10
// this step is obsoleted by fetch_async

View file

@ -76,13 +76,13 @@ pub struct HttpState {
}
impl HttpState {
pub fn new() -> HttpState {
pub fn new(certificate_path: &str) -> HttpState {
HttpState {
hsts_list: Arc::new(RwLock::new(HstsList::new())),
cookie_jar: Arc::new(RwLock::new(CookieStorage::new(150))),
auth_cache: Arc::new(RwLock::new(AuthCache::new())),
blocked_content: Arc::new(None),
connector_pool: create_http_connector(),
connector_pool: create_http_connector(certificate_path),
}
}
}

View file

@ -109,13 +109,13 @@ fn create_resource_groups(config_dir: Option<&Path>)
cookie_jar: Arc::new(RwLock::new(cookie_jar)),
auth_cache: Arc::new(RwLock::new(auth_cache)),
hsts_list: Arc::new(RwLock::new(hsts_list.clone())),
connector: create_http_connector(),
connector: create_http_connector("certs"),
};
let private_resource_group = ResourceGroup {
cookie_jar: Arc::new(RwLock::new(CookieStorage::new(150))),
auth_cache: Arc::new(RwLock::new(AuthCache::new())),
hsts_list: Arc::new(RwLock::new(HstsList::new())),
connector: create_http_connector(),
connector: create_http_connector("certs"),
};
(resource_group, private_resource_group)
}