diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/net/filemanager_thread.rs | 28 | ||||
-rw-r--r-- | components/net_traits/blob_url_store.rs | 11 | ||||
-rw-r--r-- | components/net_traits/filemanager_thread.rs | 4 | ||||
-rw-r--r-- | components/script/blob_url_store.rs | 59 | ||||
-rw-r--r-- | components/script/dom/url.rs | 91 | ||||
-rw-r--r-- | components/script/dom/webidls/URL.webidl | 5 | ||||
-rw-r--r-- | components/script/dom/window.rs | 5 | ||||
-rw-r--r-- | components/script/dom/worker.rs | 5 | ||||
-rw-r--r-- | components/script/dom/workerglobalscope.rs | 5 | ||||
-rw-r--r-- | components/script/lib.rs | 1 |
10 files changed, 141 insertions, 73 deletions
diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index 6cc47adf060..56cf0ca62c8 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -6,7 +6,7 @@ use blob_loader; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use mime_classifier::MIMEClassifier; use mime_guess::guess_mime_type_opt; -use net_traits::blob_url_store::{BlobURLStoreEntry, BlobURLStoreError}; +use net_traits::blob_url_store::{BlobURLStoreEntry, BlobURLStoreError, BlobURLStoreMsg}; use net_traits::filemanager_thread::{FileManagerThreadMsg, FileManagerResult, FilterPattern}; use net_traits::filemanager_thread::{SelectedFile, FileManagerThreadError, SelectedFileId}; use std::collections::HashMap; @@ -16,7 +16,7 @@ use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; #[cfg(any(target_os = "macos", target_os = "linux"))] use tinyfiledialogs; -use url::Origin; +use url::{Url, Origin}; use util::thread::spawn_named; use uuid::Uuid; @@ -105,6 +105,7 @@ impl<UI: 'static + UIProvider> FileManager<UI> { } } FileManagerThreadMsg::DeleteFileID(id) => self.delete_fileid(id), + FileManagerThreadMsg::BlobURLStoreMsg(msg) => self.blob_url_store.write().unwrap().process(msg), FileManagerThreadMsg::LoadBlob(load_data, consumer) => { blob_loader::load(load_data, consumer, self.blob_url_store.clone(), @@ -232,6 +233,29 @@ impl BlobURLStore { } } + fn process(&mut self, msg: BlobURLStoreMsg) { + match msg { + BlobURLStoreMsg::AddEntry(entry, origin_str, sender) => { + match Url::parse(&origin_str) { + Ok(base_url) => { + let id = Uuid::new_v4(); + self.add_entry(id, base_url.origin(), entry); + + let _ = sender.send(Ok(id.simple().to_string())); + } + Err(_) => { + let _ = sender.send(Err(BlobURLStoreError::InvalidOrigin)); + } + } + } + BlobURLStoreMsg::DeleteEntry(id) => { + if let Ok(id) = Uuid::parse_str(&id) { + self.delete_entry(id); + } + }, + } + } + pub fn request(&self, id: Uuid, origin: &Origin) -> Result<&BlobURLStoreEntry, BlobURLStoreError> { match self.entries.get(&id) { Some(ref pair) => { diff --git a/components/net_traits/blob_url_store.rs b/components/net_traits/blob_url_store.rs index 71d8c11b2de..34f609ab10e 100644 --- a/components/net_traits/blob_url_store.rs +++ b/components/net_traits/blob_url_store.rs @@ -2,6 +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 ipc_channel::ipc::IpcSender; use std::str::FromStr; use url::Url; use uuid::Uuid; @@ -15,6 +16,16 @@ pub enum BlobURLStoreError { InvalidOrigin, } +#[derive(Serialize, Deserialize)] +pub enum BlobURLStoreMsg { + /// Add an entry and send back the associated uuid + /// XXX: Second field is an unicode-serialized Origin, it is a temporary workaround + /// and should not be trusted. See issue https://github.com/servo/servo/issues/11722 + AddEntry(BlobURLStoreEntry, String, IpcSender<Result<String, BlobURLStoreError>>), + /// Delete an entry by uuid + DeleteEntry(String), +} + /// Blob URL store entry, a packaged form of Blob DOM object #[derive(Clone, Serialize, Deserialize)] pub struct BlobURLStoreEntry { diff --git a/components/net_traits/filemanager_thread.rs b/components/net_traits/filemanager_thread.rs index 122b99511b9..e4d0cb591f2 100644 --- a/components/net_traits/filemanager_thread.rs +++ b/components/net_traits/filemanager_thread.rs @@ -2,6 +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 blob_url_store::BlobURLStoreMsg; use ipc_channel::ipc::IpcSender; use std::path::PathBuf; use super::{LoadConsumer, LoadData}; @@ -35,6 +36,9 @@ pub enum FileManagerThreadMsg { /// Delete the FileID entry DeleteFileID(SelectedFileId), + // Blob URL message + BlobURLStoreMsg(BlobURLStoreMsg), + /// Load resource by Blob URL LoadBlob(LoadData, LoadConsumer), diff --git a/components/script/blob_url_store.rs b/components/script/blob_url_store.rs deleted file mode 100644 index 7f6f34ea406..00000000000 --- a/components/script/blob_url_store.rs +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -#![allow(dead_code)] - -use dom::bindings::js::JS; -use dom::blob::Blob; -use origin::Origin; -use std::collections::HashMap; -use uuid::Uuid; - -#[must_root] -#[derive(JSTraceable, HeapSizeOf)] -struct EntryPair(Origin, JS<Blob>); - -// HACK: to work around the HeapSizeOf of Uuid -#[derive(PartialEq, HeapSizeOf, Eq, Hash, JSTraceable)] -struct BlobUrlId(#[ignore_heap_size_of = "defined in uuid"] Uuid); - -#[must_root] -#[derive(JSTraceable, HeapSizeOf)] -pub struct BlobURLStore { - entries: HashMap<BlobUrlId, EntryPair>, -} - -pub enum BlobURLStoreError { - InvalidKey, - InvalidOrigin, -} - -impl BlobURLStore { - pub fn new() -> BlobURLStore { - BlobURLStore { - entries: HashMap::new(), - } - } - - pub fn request(&self, id: Uuid, origin: &Origin) -> Result<&Blob, BlobURLStoreError> { - match self.entries.get(&BlobUrlId(id)) { - Some(ref pair) => { - if pair.0.same_origin(origin) { - Ok(&pair.1) - } else { - Err(BlobURLStoreError::InvalidOrigin) - } - } - None => Err(BlobURLStoreError::InvalidKey) - } - } - - pub fn add_entry(&mut self, id: Uuid, origin: Origin, blob: &Blob) { - self.entries.insert(BlobUrlId(id), EntryPair(origin, JS::from_ref(blob))); - } - - pub fn delete_entry(&mut self, id: Uuid) { - self.entries.remove(&BlobUrlId(id)); - } -} diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs index 8ecffe60b33..c6d23bd7d4c 100644 --- a/components/script/dom/url.rs +++ b/components/script/dom/url.rs @@ -3,18 +3,25 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::cell::DOMRefCell; +use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods; use dom::bindings::codegen::Bindings::URLBinding::{self, URLMethods}; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; +use dom::blob::Blob; use dom::urlhelper::UrlHelper; use dom::urlsearchparams::URLSearchParams; +use ipc_channel::ipc; +use net_traits::IpcSend; +use net_traits::blob_url_store::{BlobURLStoreEntry, BlobURLStoreMsg, parse_blob_url}; +use net_traits::filemanager_thread::FileManagerThreadMsg; use std::borrow::ToOwned; use std::default::Default; use url::quirks::domain_to_unicode; use url::{Host, Url}; +use uuid::Uuid; // https://url.spec.whatwg.org/#url #[dom_struct] @@ -105,6 +112,90 @@ impl URL { pub fn DomainToUnicode(_: GlobalRef, origin: USVString) -> USVString { USVString(domain_to_unicode(&origin.0)) } + + // https://w3c.github.io/FileAPI/#dfn-createObjectURL + pub fn CreateObjectURL(global: GlobalRef, blob: &Blob) -> DOMString { + /// XXX: Second field is an unicode-serialized Origin, it is a temporary workaround + /// and should not be trusted. See issue https://github.com/servo/servo/issues/11722 + let origin = global.get_url().origin().unicode_serialization(); + + if blob.IsClosed() { + // Generate a dummy id + let id = Uuid::new_v4().simple().to_string(); + return DOMString::from(URL::unicode_serialization_blob_url(&origin, &id)); + } + + let filemanager = global.resource_threads().sender(); + + let slice = blob.get_slice_or_empty(); + let bytes = slice.get_bytes(); + + let entry = BlobURLStoreEntry { + type_string: blob.Type().to_string(), + filename: None, // XXX: the filename is currently only in File object now + size: blob.Size(), + bytes: bytes.to_vec(), + }; + + let (tx, rx) = ipc::channel().unwrap(); + + let msg = BlobURLStoreMsg::AddEntry(entry, origin.clone(), tx); + + let _ = filemanager.send(FileManagerThreadMsg::BlobURLStoreMsg(msg)); + + match rx.recv().unwrap() { + Ok(id) => { + DOMString::from(URL::unicode_serialization_blob_url(&origin, &id)) + } + Err(_) => { + // Generate a dummy id + let id = Uuid::new_v4().simple().to_string(); + DOMString::from(URL::unicode_serialization_blob_url(&origin, &id)) + } + } + } + + // https://w3c.github.io/FileAPI/#dfn-revokeObjectURL + pub fn RevokeObjectURL(global: GlobalRef, url: DOMString) { + /* + If the url refers to a Blob that has a readability state of CLOSED OR + if the value provided for the url argument is not a Blob URL, OR + if the value provided for the url argument does not have an entry in the Blob URL Store, + + this method call does nothing. User agents may display a message on the error console. + + NOTE: The first step is unnecessary, since closed blobs do not exist in the store + */ + + match Url::parse(&url) { + Ok(url) => match parse_blob_url(&url) { + Some((id, _)) => { + let filemanager = global.resource_threads().sender(); + let msg = BlobURLStoreMsg::DeleteEntry(id.simple().to_string()); + let _ = filemanager.send(FileManagerThreadMsg::BlobURLStoreMsg(msg)); + } + None => {} + }, + Err(_) => {} + } + } + + // https://w3c.github.io/FileAPI/#unicodeSerializationOfBlobURL + fn unicode_serialization_blob_url(origin: &str, id: &str) -> String { + // Step 1, 2 + let mut result = "blob:".to_string(); + + // Step 3 + result.push_str(origin); + + // Step 4 + result.push('/'); + + // Step 5 + result.push_str(id); + + result + } } impl URLMethods for URL { diff --git a/components/script/dom/webidls/URL.webidl b/components/script/dom/webidls/URL.webidl index dc4c71f512e..88f8704ef93 100644 --- a/components/script/dom/webidls/URL.webidl +++ b/components/script/dom/webidls/URL.webidl @@ -23,6 +23,11 @@ interface URL { readonly attribute URLSearchParams searchParams; attribute USVString hash; + // https://w3c.github.io/FileAPI/#creating-revoking + static DOMString createObjectURL(Blob blob); + // static DOMString createFor(Blob blob); + static void revokeObjectURL(DOMString url); + // This is only doing as well as gecko right now. // https://github.com/servo/servo/issues/7590 is on file for // adding attribute stringifier support. diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 486ad45bde4..03fbe2b2a2b 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::Au; -use blob_url_store::BlobURLStore; use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType, WorkerId}; use dom::bindings::callback::ExceptionHandling; use dom::bindings::cell::DOMRefCell; @@ -167,9 +166,6 @@ pub struct Window { scheduler_chan: IpcSender<TimerEventRequest>, timers: OneshotTimers, - /// Blob URL store - blob_url_store: DOMRefCell<BlobURLStore>, - next_worker_id: Cell<WorkerId>, /// For sending messages to the memory profiler. @@ -1641,7 +1637,6 @@ impl Window { console: Default::default(), crypto: Default::default(), navigator: Default::default(), - blob_url_store: DOMRefCell::new(BlobURLStore::new()), image_cache_thread: image_cache_thread, mem_profiler_chan: mem_profiler_chan, time_profiler_chan: time_profiler_chan, diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 5762e2aa63f..a136f4ec8ca 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -147,7 +147,10 @@ impl WorkerMethods for Worker { fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { let data = try!(StructuredCloneData::write(cx, message)); let address = Trusted::new(self); - self.sender.send((address, WorkerScriptMsg::DOMMessage(data))).unwrap(); + + // NOTE: step 9 of https://html.spec.whatwg.org/multipage/#dom-messageport-postmessage + // indicates that a nonexistent communication channel should result in a silent error. + let _ = self.sender.send((address, WorkerScriptMsg::DOMMessage(data))); Ok(()) } diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index b10916a4b6e..0ca45c509b7 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -2,9 +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 blob_url_store::BlobURLStore; use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId, DevtoolsPageInfo}; -use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::FunctionBinding::Function; use dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods; use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception}; @@ -115,8 +113,6 @@ pub struct WorkerGlobalScope { console: MutNullableHeap<JS<Console>>, crypto: MutNullableHeap<JS<Crypto>>, timers: OneshotTimers, - /// Blob URL store - blob_url_store: DOMRefCell<BlobURLStore>, #[ignore_heap_size_of = "Defined in std"] mem_profiler_chan: mem::ProfilerChan, @@ -177,7 +173,6 @@ impl WorkerGlobalScope { console: Default::default(), crypto: Default::default(), timers: OneshotTimers::new(timer_event_chan, init.scheduler_chan.clone()), - blob_url_store: DOMRefCell::new(BlobURLStore::new()), mem_profiler_chan: init.mem_profiler_chan, time_profiler_chan: init.time_profiler_chan, to_devtools_sender: init.to_devtools_sender, diff --git a/components/script/lib.rs b/components/script/lib.rs index 267ab46aafb..307376854ca 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -86,7 +86,6 @@ extern crate webrender_traits; extern crate websocket; extern crate xml5ever; -mod blob_url_store; pub mod bluetooth_blacklist; pub mod clipboard_provider; mod devtools; |