Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

write cookie_jar, hsts_list, auth_cache to file if profile_dir option is present #10661

Merged
merged 1 commit into from Apr 21, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

write cookie_jar, hsts_list, auth_cache, and local_data to file if pr…

…ofile_dir option is present
  • Loading branch information
DDEFISHER committed Apr 20, 2016
commit d4f63cda5ff4607f58d3feec2387e39f13b3411a
@@ -8,6 +8,7 @@
use cookie_rs;
use net_traits::CookieSource;
use pub_domains::PUB_DOMAINS;
use rustc_serialize::{Encodable, Encoder};
use std::borrow::ToOwned;
use std::net::{Ipv4Addr, Ipv6Addr};
use time::{Tm, now, at, Duration};
@@ -175,3 +176,65 @@ impl Cookie {
true
}
}

impl Encodable for Cookie {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("Cookie", 6, |e| {
try!(e.emit_struct_field("cookie", 0, |e| RsCookie(self.cookie.clone()).encode(e)));
try!(e.emit_struct_field("host_only", 1, |e| self.host_only.encode(e)));
try!(e.emit_struct_field("persistent", 2, |e| self.persistent.encode(e)));
try!(e.emit_struct_field("creation_time", 3, |e| Time(self.creation_time).encode(e)));
try!(e.emit_struct_field("last_access", 4, |e| Time(self.last_access).encode(e)));
match self.expiry_time {
Some(time) => try!(e.emit_struct_field("expiry_time", 5, |e| Time(time).encode(e))),
None => {},
}
Ok(())
})
}
}

struct Time(Tm);

impl Encodable for Time {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
let Time(time) = *self;
s.emit_struct("Time", 11, |e| {
try!(e.emit_struct_field("tm_sec", 0, |e| time.tm_sec.encode(e)));
try!(e.emit_struct_field("tm_min", 1, |e| time.tm_min.encode(e)));
try!(e.emit_struct_field("tm_hour", 2, |e| time.tm_hour.encode(e)));
try!(e.emit_struct_field("tm_mday", 3, |e| time.tm_mday.encode(e)));
try!(e.emit_struct_field("tm_mon", 4, |e| time.tm_mon.encode(e)));
try!(e.emit_struct_field("tm_year", 5, |e| time.tm_year.encode(e)));
try!(e.emit_struct_field("tm_wday", 6, |e| time.tm_wday.encode(e)));
try!(e.emit_struct_field("tm_yday", 7, |e| time.tm_yday.encode(e)));
try!(e.emit_struct_field("tm_isdst", 8, |e| time.tm_isdst.encode(e)));
try!(e.emit_struct_field("tm_utcoff", 9, |e| time.tm_utcoff.encode(e)));
try!(e.emit_struct_field("tm_nsec", 10, |e| time.tm_nsec.encode(e)));
Ok(())
})
}
}

struct RsCookie(cookie_rs::Cookie);

impl Encodable for RsCookie {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
let RsCookie(ref rs_cookie) = *self;
s.emit_struct("RsCookie", 9, |e| {
try!(e.emit_struct_field("name", 0, |e| rs_cookie.name.encode(e)));
try!(e.emit_struct_field("value", 1, |e| rs_cookie.value.encode(e)));
match rs_cookie.expires {
Some(time) => try!(e.emit_struct_field("expires", 2, |e| Time(time).encode(e))),
None => {},
}
try!(e.emit_struct_field("max_age", 3, |e| rs_cookie.max_age.encode(e)));
try!(e.emit_struct_field("domain", 4, |e| rs_cookie.domain.encode(e)));
try!(e.emit_struct_field("path", 5, |e| rs_cookie.path.encode(e)));
try!(e.emit_struct_field("secure", 6, |e| rs_cookie.secure.encode(e)));
try!(e.emit_struct_field("httponly", 7, |e| rs_cookie.httponly.encode(e)));
try!(e.emit_struct_field("custom", 8, |e| rs_cookie.custom.encode(e)));
Ok(())
})
}
}
@@ -7,16 +7,20 @@

use cookie::Cookie;
use net_traits::CookieSource;
use rustc_serialize::{Encodable, Encoder};
use std::cmp::Ordering;
use url::Url;

#[derive(RustcEncodable, Clone)]
pub struct CookieStorage {
version: u32,
cookies: Vec<Cookie>
}

impl CookieStorage {
pub fn new() -> CookieStorage {
CookieStorage {
version: 1,
cookies: Vec::new()
}
}
@@ -31,10 +31,10 @@ use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadContext, Loa
use net_traits::{Metadata, NetworkError};
use openssl::ssl::error::{SslError, OpensslError};
use openssl::ssl::{SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_VERIFY_PEER, SslContext, SslMethod};
use resource_thread::{CancellationListener, send_error, start_sending_sniffed_opt, AuthCacheEntry};
use resource_thread::{CancellationListener, send_error, start_sending_sniffed_opt, AuthCache, AuthCacheEntry};
use std::borrow::ToOwned;
use std::boxed::FnBox;
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
use std::error::Error;
use std::io::{self, Read, Write};
use std::sync::mpsc::Sender;
@@ -128,15 +128,15 @@ fn inner_url(url: &Url) -> Url {
pub struct HttpState {
pub hsts_list: Arc<RwLock<HstsList>>,
pub cookie_jar: Arc<RwLock<CookieStorage>>,
pub auth_cache: Arc<RwLock<HashMap<Url, AuthCacheEntry>>>,
pub auth_cache: Arc<RwLock<AuthCache>>,
}

impl HttpState {
pub fn new() -> HttpState {
HttpState {
hsts_list: Arc::new(RwLock::new(HstsList::new())),
cookie_jar: Arc::new(RwLock::new(CookieStorage::new())),
auth_cache: Arc::new(RwLock::new(HashMap::new())),
auth_cache: Arc::new(RwLock::new(AuthCache::new())),
}
}
}
@@ -522,7 +522,7 @@ pub fn modify_request_headers(headers: &mut Headers,
url: &Url,
user_agent: &str,
cookie_jar: &Arc<RwLock<CookieStorage>>,
auth_cache: &Arc<RwLock<HashMap<Url, AuthCacheEntry>>>,
auth_cache: &Arc<RwLock<AuthCache>>,
load_data: &LoadData) {
// Ensure that the host header is set from the original url
let host = Host {
@@ -555,13 +555,13 @@ pub fn modify_request_headers(headers: &mut Headers,

fn set_auth_header(headers: &mut Headers,
url: &Url,
auth_cache: &Arc<RwLock<HashMap<Url, AuthCacheEntry>>>) {
auth_cache: &Arc<RwLock<AuthCache>>) {

if !headers.has::<Authorization<Basic>>() {
if let Some(auth) = auth_from_url(url) {
headers.set(auth);
} else {
if let Some(ref auth_entry) = auth_cache.read().unwrap().get(url) {
if let Some(ref auth_entry) = auth_cache.read().unwrap().entries.get(url) {
auth_from_entry(&auth_entry, headers);
}
}
@@ -820,7 +820,7 @@ pub fn load<A, B>(load_data: &LoadData,
password: auth_header.password.to_owned().unwrap(),
};

http_state.auth_cache.write().unwrap().insert(doc_url.clone(), auth_entry);
http_state.auth_cache.write().unwrap().entries.insert(doc_url.clone(), auth_entry);
}
}

@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A thread that takes a URL and streams back the binary data.

use about_loader;
use chrome_loader;
use cookie;
@@ -23,13 +22,20 @@ use net_traits::ProgressMsg::Done;
use net_traits::{AsyncResponseTarget, Metadata, ProgressMsg, ResourceThread, ResponseAction};
use net_traits::{ControlMsg, CookieSource, LoadConsumer, LoadData, LoadResponse, ResourceId};
use net_traits::{NetworkError, WebSocketCommunicate, WebSocketConnectData};
use rustc_serialize::Encodable;
use rustc_serialize::json;
use std::borrow::ToOwned;
use std::boxed::FnBox;
use std::cell::Cell;
use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::sync::mpsc::{Receiver, Sender, channel};
use std::sync::{Arc, RwLock};
use url::Url;
use util::opts;
use util::prefs;
use util::thread::spawn_named;
use websocket_loader;
@@ -190,12 +196,54 @@ impl ResourceChannelManager {
ControlMsg::Synchronize(sender) => {
let _ = sender.send(());
}
ControlMsg::Exit => break,
ControlMsg::Exit => {
if let Some(ref profile_dir) = opts::get().profile_dir {
match self.resource_manager.auth_cache.read() {
Ok(auth_cache) => write_json_to_file(&*auth_cache, profile_dir, "auth_cache.json"),
Err(_) => warn!("Error writing auth cache to disk"),
}
match self.resource_manager.cookie_jar.read() {
Ok(jar) => write_json_to_file(&*jar, profile_dir, "cookie_jar.json"),
Err(_) => warn!("Error writing cookie jar to disk"),
}
match self.resource_manager.hsts_list.read() {
Ok(hsts) => write_json_to_file(&*hsts, profile_dir, "hsts_list.json"),
Err(_) => warn!("Error writing hsts list to disk"),
}
}
break;
}

}
}
}
}

pub fn write_json_to_file<T: Encodable>(data: &T, profile_dir: &str, filename: &str) {
let json_encoded: String;
match json::encode(&data) {
Ok(d) => json_encoded = d,
Err(_) => return,
}
let path = Path::new(profile_dir).join(filename);
let display = path.display();

let mut file = match File::create(&path) {
Err(why) => panic!("couldn't create {}: {}",
display,
Error::description(&why)),
Ok(file) => file,
};

match file.write_all(json_encoded.as_bytes()) {
Err(why) => {
panic!("couldn't write to {}: {}", display,
Error::description(&why))
},
Ok(_) => println!("successfully wrote to {}", display),
}
}

/// The optional resources required by the `CancellationListener`
pub struct CancellableResource {
/// The receiver which receives a message on load cancellation
@@ -259,15 +307,32 @@ impl Drop for CancellationListener {
}
}

#[derive(RustcDecodable, RustcEncodable, Clone)]
pub struct AuthCacheEntry {
pub user_name: String,
pub password: String,
}

impl AuthCache {

pub fn new() -> AuthCache {
AuthCache {
version: 1,
entries: HashMap::new()
}
}
}

#[derive(RustcDecodable, RustcEncodable, Clone)]
pub struct AuthCache {
pub version: u32,
pub entries: HashMap<Url, AuthCacheEntry>,
}

pub struct ResourceManager {
user_agent: String,
cookie_jar: Arc<RwLock<CookieStorage>>,
auth_cache: Arc<RwLock<HashMap<Url, AuthCacheEntry>>>,
auth_cache: Arc<RwLock<AuthCache>>,
mime_classifier: Arc<MIMEClassifier>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<RwLock<HstsList>>,
@@ -283,7 +348,7 @@ impl ResourceManager {
ResourceManager {
user_agent: user_agent,
cookie_jar: Arc::new(RwLock::new(CookieStorage::new())),
auth_cache: Arc::new(RwLock::new(HashMap::new())),
auth_cache: Arc::new(RwLock::new(AuthCache::new())),
mime_classifier: Arc::new(MIMEClassifier::new()),
devtools_chan: devtools_channel,
hsts_list: Arc::new(RwLock::new(hsts_list)),
@@ -4,10 +4,12 @@

use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use net_traits::storage_thread::{StorageThread, StorageThreadMsg, StorageType};
use resource_thread;
use std::borrow::ToOwned;
use std::collections::BTreeMap;
use std::collections::HashMap;
use url::Url;
use util::opts;
use util::thread::spawn_named;

const QUOTA_SIZE_LIMIT: usize = 5 * 1024 * 1024;
@@ -69,6 +71,9 @@ impl StorageManager {
self.clear(sender, url, storage_type)
}
StorageThreadMsg::Exit => {
if let Some(ref profile_dir) = opts::get().profile_dir {
resource_thread::write_json_to_file(&self.local_data, profile_dir, "local_data.json");
}
break
}
}
@@ -1382,7 +1382,7 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() {
password: "test".to_owned(),
};

http_state.auth_cache.write().unwrap().insert(url.clone(), auth_entry);
http_state.auth_cache.write().unwrap().entries.insert(url.clone(), auth_entry);

let mut load_data = LoadData::new(LoadContext::Browsing, url, None);
load_data.credentials_flag = true;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.