aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/net/filemanager_thread.rs28
-rw-r--r--components/net_traits/blob_url_store.rs11
-rw-r--r--components/net_traits/filemanager_thread.rs4
-rw-r--r--components/script/blob_url_store.rs59
-rw-r--r--components/script/dom/url.rs91
-rw-r--r--components/script/dom/webidls/URL.webidl5
-rw-r--r--components/script/dom/window.rs5
-rw-r--r--components/script/dom/worker.rs5
-rw-r--r--components/script/dom/workerglobalscope.rs5
-rw-r--r--components/script/lib.rs1
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;