Auto merge of #14445 - mrnayak:netSecurity, r=jdm

Redesign CookieStorage and Implement Leave Secure Cookie Alone

CookieStorage has been refactored to use HashMap with the base domain as the key. Values of hashmap are vector of cookies.
CookieStorage now has max_per_host which restricts maximum cookies that can be added per base domain.
Cookie eviction does not take place if max_per_host is not reached.
Cookie eviction logic implemented here does following steps
1) Evict all expired cookies
2) Remove oldest accessed non-secure cookie If any
3) When no non-secure cookie exists, remove oldest accessed secure cookie if new cookie being added is secure. Else ignore new cookie

---
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [X] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- 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/14445)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-12-04 15:30:46 -08:00 committed by GitHub
commit b05c27cb58
5 changed files with 195 additions and 21 deletions

View file

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cookie_rs;
use hyper::header::{Header, SetCookie};
use net::cookie::Cookie;
use net::cookie_storage::CookieStorage;
use net_traits::CookieSource;
@ -110,8 +111,7 @@ fn delay_to_ensure_different_timestamp() {
}
#[cfg(not(target_os = "windows"))]
fn delay_to_ensure_different_timestamp() {
}
fn delay_to_ensure_different_timestamp() {}
#[test]
fn test_sort_order() {
@ -132,3 +132,102 @@ fn test_sort_order() {
assert!(CookieStorage::cookie_comparator(&a_prime, &a) == Ordering::Greater);
assert!(CookieStorage::cookie_comparator(&a, &a) == Ordering::Equal);
}
fn add_retrieve_cookies(set_location: &str,
set_cookies: &[String],
final_location: &str)
-> String {
let mut storage = CookieStorage::new(5);
let url = ServoUrl::parse(set_location).unwrap();
let source = CookieSource::HTTP;
// Add all cookies to the store
for str_cookie in set_cookies {
let bytes = str_cookie.to_string().into_bytes();
let header = Header::parse_header(&[bytes]).unwrap();
let SetCookie(cookies) = header;
for bare_cookie in cookies {
let cookie = Cookie::new_wrapped(bare_cookie, &url, source).unwrap();
storage.push(cookie, source);
}
}
// Get cookies for the test location
let url = ServoUrl::parse(final_location).unwrap();
storage.cookies_for_url(&url, source).unwrap_or("".to_string())
}
#[test]
fn test_cookie_eviction_expired() {
let mut vec = Vec::new();
for i in 1..6 {
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2000 21:06:29 GMT",
i);
vec.push(st);
}
vec.push("foo=bar; Secure; expires=Sun, 18-Apr-2027 21:06:29 GMT".to_owned());
let r = add_retrieve_cookies("https://home.example.org:8888/cookie-parser?0001",
&vec, "https://home.example.org:8888/cookie-parser-result?0001");
assert_eq!(&r, "foo=bar");
}
#[test]
fn test_cookie_eviction_all_secure_one_nonsecure() {
let mut vec = Vec::new();
for i in 1..5 {
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2026 21:06:29 GMT",
i);
vec.push(st);
}
vec.push("foo=bar; expires=Sun, 18-Apr-2026 21:06:29 GMT".to_owned());
vec.push("foo2=bar; Secure; expires=Sun, 18-Apr-2028 21:06:29 GMT".to_owned());
let r = add_retrieve_cookies("https://home.example.org:8888/cookie-parser?0001",
&vec, "https://home.example.org:8888/cookie-parser-result?0001");
assert_eq!(&r, "extra1=bar; extra2=bar; extra3=bar; extra4=bar; foo2=bar");
}
#[test]
fn test_cookie_eviction_all_secure_new_nonsecure() {
let mut vec = Vec::new();
for i in 1..6 {
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2026 21:06:29 GMT",
i);
vec.push(st);
}
vec.push("foo=bar; expires=Sun, 18-Apr-2077 21:06:29 GMT".to_owned());
let r = add_retrieve_cookies("https://home.example.org:8888/cookie-parser?0001",
&vec, "https://home.example.org:8888/cookie-parser-result?0001");
assert_eq!(&r, "extra1=bar; extra2=bar; extra3=bar; extra4=bar; extra5=bar");
}
#[test]
fn test_cookie_eviction_all_nonsecure_new_secure() {
let mut vec = Vec::new();
for i in 1..6 {
let st = format!("extra{}=bar; expires=Sun, 18-Apr-2026 21:06:29 GMT", i);
vec.push(st);
}
vec.push("foo=bar; Secure; expires=Sun, 18-Apr-2077 21:06:29 GMT".to_owned());
let r = add_retrieve_cookies("https://home.example.org:8888/cookie-parser?0001",
&vec, "https://home.example.org:8888/cookie-parser-result?0001");
assert_eq!(&r, "extra2=bar; extra3=bar; extra4=bar; extra5=bar; foo=bar");
}
#[test]
fn test_cookie_eviction_all_nonsecure_new_nonsecure() {
let mut vec = Vec::new();
for i in 1..6 {
let st = format!("extra{}=bar; expires=Sun, 18-Apr-2026 21:06:29 GMT", i);
vec.push(st);
}
vec.push("foo=bar; expires=Sun, 18-Apr-2077 21:06:29 GMT".to_owned());
let r = add_retrieve_cookies("https://home.example.org:8888/cookie-parser?0001",
&vec, "https://home.example.org:8888/cookie-parser-result?0001");
assert_eq!(&r, "extra2=bar; extra3=bar; extra4=bar; extra5=bar; foo=bar");
}

View file

@ -10,7 +10,7 @@ use servo_url::ServoUrl;
fn run(set_location: &str, set_cookies: &[&str], final_location: &str) -> String {
let mut storage = CookieStorage::new();
let mut storage = CookieStorage::new(150);
let url = ServoUrl::parse(set_location).unwrap();
let source = CookieSource::HTTP;