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

Private browsing student project #10690

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Private browsing with tests

  • Loading branch information
srm09 committed May 2, 2016
commit 769e0eabe4ec21947f3d220a21d50eb140b1d8ae
@@ -38,7 +38,8 @@ use msg::constellation_msg::{self, ConstellationChan, PanicMsg};
use msg::webdriver_msg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::storage_thread::{StorageThread, StorageThreadMsg};
use net_traits::{self, ResourceThread};
use net_traits::{self, ResourceThread, ConstellationMsg as FromResourceMsg};
//use net_traits::{SendConstellationMsgChannel, Exit};
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use pipeline::{CompositionPipeline, InitialPipelineState, Pipeline, UnprivilegedPipelineContent};
use profile_traits::mem;
@@ -104,6 +105,9 @@ pub struct Constellation<LTF, STF> {
/// Receives messages from the compositor
pub compositor_receiver: Receiver<FromCompositorMsg>,

/// Receives ConstellationMsg
pub resource_msg_receiver: Receiver<FromResourceMsg>,

/// Receives messages from the layout thread
pub layout_receiver: Receiver<FromLayoutMsg>,

@@ -326,6 +330,8 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let (ipc_panic_receiver, ipc_panic_sender) = ConstellationChan::<PanicMsg>::new();
let panic_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_panic_receiver);
let compositor_sender_clone = compositor_sender.clone();
let (ipc_resource_msg_receiver, ipc_resource_msg_sender) = ConstellationChan::<FromResourceMsg>::new();
let resource_msg_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_resource_msg_receiver);
spawn_named("Constellation".to_owned(), move || {
let mut constellation: Constellation<LTF, STF> = Constellation {
script_sender: ipc_script_sender,
@@ -334,6 +340,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
script_receiver: script_receiver,
panic_sender: ipc_panic_sender,
compositor_receiver: compositor_receiver,
resource_msg_receiver: resource_msg_receiver,
layout_receiver: layout_receiver,
panic_receiver: panic_receiver,
compositor_proxy: state.compositor_proxy,
@@ -384,6 +391,8 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let namespace_id = constellation.next_pipeline_namespace_id();
PipelineNamespace::install(namespace_id);
constellation.run();
let _ = constellation.resource_thread.send(
net_traits::ControlMsg::SendConstellationMsgChannel(ipc_resource_msg_sender));

This comment has been minimized.

@jdm

jdm May 3, 2016

Member

Er. It's disconcerting that the test (presumably) passes right now, since this message will not be sent until Servo is in the process of shutting down - run is an endless loop.

});
compositor_sender
}
@@ -553,7 +562,8 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
Script(FromScriptMsg),
Compositor(FromCompositorMsg),
Layout(FromLayoutMsg),
Panic(PanicMsg)
Panic(PanicMsg),
Resource(FromResourceMsg),
}

// Get one incoming request.
@@ -572,6 +582,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let receiver_from_compositor = &self.compositor_receiver;
let receiver_from_layout = &self.layout_receiver;
let receiver_from_panic = &self.panic_receiver;
let receiver_from_constellation_msg = &self.resource_msg_receiver;
select! {
msg = receiver_from_script.recv() =>
Request::Script(msg.expect("Unexpected script channel panic in constellation")),
@@ -580,7 +591,9 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
msg = receiver_from_layout.recv() =>
Request::Layout(msg.expect("Unexpected layout channel panic in constellation")),
msg = receiver_from_panic.recv() =>
Request::Panic(msg.expect("Unexpected panic channel panic in constellation"))
Request::Panic(msg.expect("Unexpected panic channel panic in constellation")),
msg = receiver_from_constellation_msg.recv() =>
Request::Resource(msg.expect("Unexpected resource failure in constellation"))
}
};

@@ -819,6 +832,12 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
debug!("handling panic message ({:?})", pipeline_id);
self.handle_panic(pipeline_id, panic_reason, backtrace);
}

Request::Resource(FromResourceMsg::IsPrivate(pipeline_id, sender)) => {
debug!("constellation got IsPrivate message");
let _ = sender.send(self.check_is_pipeline_private(pipeline_id));
}

}
true
}
@@ -17,10 +17,11 @@ use hyper::header::{ContentType, Header, SetCookie};
use hyper::mime::{Mime, SubLevel, TopLevel};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use mime_classifier::{ApacheBugFlag, MIMEClassifier, NoSniffFlag};
use msg::constellation_msg::{ConstellationChan, PipelineId};
use net_traits::LoadContext;
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::{ControlMsg, ConstellationMsg, CookieSource, LoadConsumer, LoadData, LoadResponse, ResourceId};
use net_traits::{NetworkError, WebSocketCommunicate, WebSocketConnectData};
use rustc_serialize::json;
use rustc_serialize::{Decodable, Encodable};
@@ -45,6 +46,14 @@ pub enum ProgressSender {
Listener(AsyncResponseTarget),
}

#[derive(Clone)]
pub struct ResourceGroup {
cookie_jar: Arc<RwLock<CookieStorage>>,
auth_cache: Arc<RwLock<AuthCache>>,
hsts_list: Arc<RwLock<HstsList>>,
connector: Arc<Pool<Connector>>,
}

impl ProgressSender {
//XXXjdm return actual error
pub fn send(&self, msg: ProgressMsg) -> Result<(), ()> {
@@ -178,12 +187,12 @@ impl ResourceChannelManager {
match self.from_client.recv().unwrap() {
ControlMsg::Load(load_data, consumer, id_sender) =>
self.resource_manager.load(load_data, consumer, id_sender, control_sender.clone()),
ControlMsg::WebsocketConnect(connect, connect_data) =>
self.resource_manager.websocket_connect(connect, connect_data),
ControlMsg::SetCookiesForUrl(request, cookie_list, source) =>
self.resource_manager.set_cookies_for_url(request, cookie_list, source),
ControlMsg::GetCookiesForUrl(url, consumer, source) => {
let cookie_jar = &self.resource_manager.cookie_jar;
ControlMsg::WebsocketConnect(pipeline_id, connect, connect_data) =>
self.resource_manager.websocket_connect(pipeline_id, connect, connect_data),
ControlMsg::SetCookiesForUrl(pipeline_id, request, cookie_list, source) =>
self.resource_manager.set_cookies_for_url(pipeline_id, request, cookie_list, source),
ControlMsg::GetCookiesForUrl(pipeline_id, url, consumer, source) => {
let cookie_jar = &self.resource_manager.get_resource_group(Some(pipeline_id)).cookie_jar;
let mut cookie_jar = cookie_jar.write().unwrap();
consumer.send(cookie_jar.cookies_for_url(&url, source)).unwrap();
}
@@ -196,17 +205,22 @@ impl ResourceChannelManager {
ControlMsg::Synchronize(sender) => {
let _ = sender.send(());
}
ControlMsg::SendConstellationMsgChannel(sender) => {
self.resource_manager.constellation_msg_chan = Some(sender);
}
ControlMsg::Exit => {
let resource_grp = self.resource_manager.get_resource_group(None);
let cookie_jar = resource_grp.cookie_jar;
if let Some(ref profile_dir) = opts::get().profile_dir {
match self.resource_manager.auth_cache.read() {
match resource_grp.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() {
match 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() {
match resource_grp.hsts_list.read() {
Ok(hsts) => write_json_to_file(&*hsts, profile_dir, "hsts_list.json"),
Err(_) => warn!("Error writing hsts list to disk"),
}
@@ -359,14 +373,13 @@ pub struct AuthCache {

pub struct ResourceManager {
user_agent: String,
cookie_jar: Arc<RwLock<CookieStorage>>,
auth_cache: Arc<RwLock<AuthCache>>,
mime_classifier: Arc<MIMEClassifier>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<RwLock<HstsList>>,
connector: Arc<Pool<Connector>>,
cancel_load_map: HashMap<ResourceId, Sender<()>>,
next_resource_id: ResourceId,
constellation_msg_chan: Option<ConstellationChan<ConstellationMsg>>,
resource_group: ResourceGroup,
private_resource_group: ResourceGroup,
}

impl ResourceManager {
@@ -380,25 +393,40 @@ impl ResourceManager {
read_json_from_file(&mut hsts_list, profile_dir, "hsts_list.json");
read_json_from_file(&mut cookie_jar, profile_dir, "cookie_jar.json");
}
ResourceManager {
user_agent: user_agent,
let resource_group = ResourceGroup {
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(),
};
let private_resource_group = ResourceGroup {
cookie_jar: Arc::new(RwLock::new(CookieStorage::new())),
auth_cache: Arc::new(RwLock::new(AuthCache::new())),
hsts_list: Arc::new(RwLock::new(HstsList::new())),
connector: create_http_connector(),
};
ResourceManager {
user_agent: user_agent,
mime_classifier: Arc::new(MIMEClassifier::new()),
devtools_chan: devtools_channel,
hsts_list: Arc::new(RwLock::new(hsts_list)),
connector: create_http_connector(),
cancel_load_map: HashMap::new(),
next_resource_id: ResourceId(0),
constellation_msg_chan: None,
resource_group: resource_group,
private_resource_group: private_resource_group,
}
}

fn set_cookies_for_url(&mut self, request: Url, cookie_list: String, source: CookieSource) {
fn set_cookies_for_url(&mut self,
pipeline_id: PipelineId,
request: Url,
cookie_list: String,
source: CookieSource) {
let header = Header::parse_header(&[cookie_list.into_bytes()]);
if let Ok(SetCookie(cookies)) = header {
for bare_cookie in cookies {
if let Some(cookie) = cookie::Cookie::new_wrapped(bare_cookie, &request, source) {
let cookie_jar = &self.cookie_jar;
let cookie_jar = &self.get_resource_group(Some(pipeline_id)).cookie_jar;
let mut cookie_jar = cookie_jar.write().unwrap();
cookie_jar.push(cookie, source);
}
@@ -436,15 +464,16 @@ impl ResourceManager {
"chrome" => from_factory(chrome_loader::factory),
"file" => from_factory(file_loader::factory),
"http" | "https" | "view-source" => {
let resource_grp = self.get_resource_group(load_data.pipeline_id);

This comment has been minimized.

@srm09

srm09 May 3, 2016

Author Contributor

In the test file, the scheme for the iframe src URL is file:/// whereas the loader which has the code changes for private/public resource group requires the scheme http/https would be leading to the failed test case. Does this seem logical???

This comment has been minimized.

@jdm

jdm May 3, 2016

Member

Why would the scheme be a file:// url? The tests are loaded from a local HTTP server.

let http_state = HttpState {
hsts_list: self.hsts_list.clone(),
cookie_jar: self.cookie_jar.clone(),
auth_cache: self.auth_cache.clone()
hsts_list: resource_grp.hsts_list.clone(),
cookie_jar: resource_grp.cookie_jar.clone(),
auth_cache: resource_grp.auth_cache.clone()
};
http_loader::factory(self.user_agent.clone(),
http_state,
self.devtools_chan.clone(),
self.connector.clone())
resource_grp.connector.clone())
},
"data" => from_factory(data_loader::factory),
"about" => from_factory(about_loader::factory),
@@ -463,8 +492,26 @@ impl ResourceManager {
}

fn websocket_connect(&self,
pipeline_id: PipelineId,
connect: WebSocketCommunicate,
connect_data: WebSocketConnectData) {
websocket_loader::init(connect, connect_data, self.cookie_jar.clone());
let resource_grp = self.get_resource_group(Some(pipeline_id));
websocket_loader::init(connect, connect_data, resource_grp.cookie_jar);
}

fn get_resource_group(&self, pipeline_id: Option<PipelineId>) -> ResourceGroup {
let is_private = match pipeline_id {
Some(id) => {
let (tx, rx) = ipc::channel::<bool>().unwrap();
let ConstellationChan(ref chan) = self.constellation_msg_chan.clone().unwrap();
let _ = chan.send(ConstellationMsg::IsPrivate(id, tx));
rx.recv().unwrap()
},
None => false
};
match is_private {
true => self.private_resource_group.clone(),
false => self.resource_group.clone(),
}
}
}
@@ -33,9 +33,8 @@ use hyper::http::RawStatus;
use hyper::method::Method;
use hyper::mime::{Attr, Mime};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use msg::constellation_msg::{ConstellationChan, PipelineId, ReferrerPolicy};
use serde::{Deserializer, Serializer};
use std::sync::mpsc::Sender;
use std::thread;
use url::Url;
use websocket::header;
@@ -223,15 +222,17 @@ pub enum ControlMsg {
/// Request the data associated with a particular URL
Load(LoadData, LoadConsumer, Option<IpcSender<ResourceId>>),
/// Try to make a websocket connection to a URL.
WebsocketConnect(WebSocketCommunicate, WebSocketConnectData),
WebsocketConnect(PipelineId, WebSocketCommunicate, WebSocketConnectData),
/// Store a set of cookies for a given originating URL
SetCookiesForUrl(Url, String, CookieSource),
SetCookiesForUrl(PipelineId, Url, String, CookieSource),
/// Retrieve the stored cookies for a given URL
GetCookiesForUrl(Url, IpcSender<Option<String>>, CookieSource),
GetCookiesForUrl(PipelineId, Url, IpcSender<Option<String>>, CookieSource),
/// Cancel a network request corresponding to a given `ResourceId`
Cancel(ResourceId),
/// Synchronization message solely for knowing the state of the ResourceChannelManager loop
Synchronize(IpcSender<()>),
/// Send the ConstellationChan for checking a private pipeline
SendConstellationMsgChannel(ConstellationChan<ConstellationMsg>),
/// Break the load handler loop and exit
Exit,
}
@@ -429,9 +430,10 @@ pub fn unwrap_websocket_protocol(wsp: Option<&header::WebSocketProtocol>) -> Opt
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)]
pub struct ResourceId(pub u32);

#[derive(Deserialize, Serialize)]
pub enum ConstellationMsg {
/// Queries whether a pipeline or its ancestors are private
IsPrivate(PipelineId, Sender<bool>),
IsPrivate(PipelineId, IpcSender<bool>),
}

/// Network errors that have to be exported out of the loaders
@@ -2545,7 +2545,8 @@ impl DocumentMethods for Document {

let url = self.url();
let (tx, rx) = ipc::channel().unwrap();
let _ = self.window.resource_thread().send(GetCookiesForUrl((*url).clone(), tx, NonHTTP));
let _ = self.window.resource_thread().send(GetCookiesForUrl(
self.window.pipeline(), (*url).clone(), tx, NonHTTP));
let cookies = rx.recv().unwrap();
Ok(cookies.map_or(DOMString::new(), DOMString::from))
}
@@ -2563,7 +2564,7 @@ impl DocumentMethods for Document {
let url = self.url();
let _ = self.window
.resource_thread()
.send(SetCookiesForUrl((*url).clone(), String::from(cookie), NonHTTP));
.send(SetCookiesForUrl(self.window.pipeline(), (*url).clone(), String::from(cookie), NonHTTP));
Ok(())
}

@@ -29,6 +29,7 @@ use js::jsapi::{JSAutoCompartment, JSAutoRequest, RootedValue};
use js::jsapi::{JS_GetArrayBufferData, JS_NewArrayBuffer};
use js::jsval::UndefinedValue;
use libc::{uint32_t, uint8_t};
use msg::constellation_msg::PipelineId;
use net_traits::ControlMsg::{WebsocketConnect, SetCookiesForUrl};
use net_traits::CookieSource::HTTP;
use net_traits::MessageData;
@@ -267,12 +268,13 @@ impl WebSocket {
};

let resource_thread = global.resource_thread();
let _ = resource_thread.send(WebsocketConnect(connect, connect_data));
let _ = resource_thread.send(WebsocketConnect(global.pipeline(), connect, connect_data));

*ws.sender.borrow_mut() = Some(dom_action_sender);

let moved_address = address.clone();
let sender = global.networking_task_source();
let pipeline = global.pipeline();
thread::spawn(move || {
while let Ok(event) = dom_event_receiver.recv() {
match event {
@@ -281,6 +283,7 @@ impl WebSocket {
address: moved_address.clone(),
headers: headers,
protocols: protocols,
pipeline: pipeline,
};
sender.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, open_thread)).unwrap();
},
@@ -464,6 +467,7 @@ struct ConnectionEstablishedTask {
address: Trusted<WebSocket>,
protocols: Vec<String>,
headers: Headers,
pipeline: PipelineId,
}

impl Runnable for ConnectionEstablishedTask {
@@ -494,7 +498,8 @@ impl Runnable for ConnectionEstablishedTask {
if let Some(cookies) = self.headers.get_raw("set-cookie") {
for cookie in cookies.iter() {
if let Ok(cookie_value) = String::from_utf8(cookie.clone()) {
let _ = ws.global().r().resource_thread().send(SetCookiesForUrl(ws.url.clone(),
let _ = ws.global().r().resource_thread().send(SetCookiesForUrl(self.pipeline,
ws.url.clone(),
cookie_value,
HTTP));
}
@@ -6496,6 +6496,12 @@
"url": "/_mozilla/mozilla/mozbrowser/mozbrowsershowmodalprompt_event.html"
}
],
"mozilla/mozbrowser/private_browsing.html": [
{
"path": "mozilla/mozbrowser/private_browsing.html",
"url": "/_mozilla/mozilla/mozbrowser/private_browsing.html"
}
],
"mozilla/mozbrowser/redirect.html": [
{
"path": "mozilla/mozbrowser/redirect.html",
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.