1
0
Fork 0
mirror of https://github.com/servo/servo.git synced 2025-08-02 04:00:32 +01:00

Auto merge of - izgzhen:blob-url-revocation-fix, r=Manishearth

Add FileID validity setting/checking logic to Blob URL implementation

r? @Manishearth

---
<!-- 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

<!-- Either: -->
- [ ] 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/12378)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-07-11 00:13:45 -07:00 committed by GitHub
commit 42e90f7db9
4 changed files with 149 additions and 44 deletions
components/script/dom

View file

@ -151,9 +151,23 @@ impl Blob {
}
}
pub fn get_id(&self) -> SelectedFileId {
/// Get a FileID representing the Blob content,
/// used by URL.createObjectURL
pub fn get_blob_url_id(&self) -> SelectedFileId {
match *self.blob_impl.borrow() {
BlobImpl::File(ref id, _) => id.clone(),
BlobImpl::File(ref id, _) => {
let global = self.global();
let origin = global.r().get_url().origin().unicode_serialization();
let filemanager = global.r().resource_threads().sender();
let (tx, rx) = ipc::channel().unwrap();
let _ = filemanager.send(FileManagerThreadMsg::ActivateBlobURL(id.clone(), tx, origin.clone()));
match rx.recv().unwrap() {
Ok(_) => id.clone(),
Err(_) => SelectedFileId("".to_string()) // Return a dummy id on error
}
}
BlobImpl::Memory(ref slice) => self.promote_to_file(slice),
BlobImpl::Sliced(ref parent, ref rel_pos) => {
match *parent.blob_impl.borrow() {
@ -163,11 +177,11 @@ impl Blob {
SelectedFileId("".to_string())
}
BlobImpl::File(ref parent_id, _) =>
self.create_sliced_id(parent_id, rel_pos),
self.create_sliced_url_id(parent_id, rel_pos),
BlobImpl::Memory(ref bytes) => {
let parent_id = parent.promote_to_file(bytes);
*self.blob_impl.borrow_mut() = BlobImpl::Sliced(parent.clone(), rel_pos.clone());
self.create_sliced_id(&parent_id, rel_pos)
self.create_sliced_url_id(&parent_id, rel_pos)
}
}
}
@ -188,7 +202,7 @@ impl Blob {
};
let (tx, rx) = ipc::channel().unwrap();
let _ = filemanager.send(FileManagerThreadMsg::TransferMemory(entry, tx, origin.clone()));
let _ = filemanager.send(FileManagerThreadMsg::PromoteMemory(entry, tx, origin.clone()));
match rx.recv().unwrap() {
Ok(new_id) => SelectedFileId(new_id.0),
@ -197,23 +211,47 @@ impl Blob {
}
}
fn create_sliced_id(&self, parent_id: &SelectedFileId,
rel_pos: &RelativePos) -> SelectedFileId {
/// Get a FileID representing sliced parent-blob content
fn create_sliced_url_id(&self, parent_id: &SelectedFileId,
rel_pos: &RelativePos) -> SelectedFileId {
let global = self.global();
let origin = global.r().get_url().origin().unicode_serialization();
let filemanager = global.r().resource_threads().sender();
let (tx, rx) = ipc::channel().unwrap();
let msg = FileManagerThreadMsg::AddSlicedEntry(parent_id.clone(),
rel_pos.clone(),
tx, origin.clone());
let msg = FileManagerThreadMsg::AddSlicedURLEntry(parent_id.clone(),
rel_pos.clone(),
tx, origin.clone());
let _ = filemanager.send(msg);
let new_id = rx.recv().unwrap().unwrap();
// Return the indirect id reference
SelectedFileId(new_id.0)
}
/// Cleanups at the time of destruction/closing
fn clean_up_file_resource(&self) {
if let BlobImpl::File(ref id, _) = *self.blob_impl.borrow() {
let global = self.global();
let origin = global.r().get_url().origin().unicode_serialization();
let filemanager = global.r().resource_threads().sender();
let (tx, rx) = ipc::channel().unwrap();
let msg = FileManagerThreadMsg::DecRef(id.clone(), origin, tx);
let _ = filemanager.send(msg);
let _ = rx.recv().unwrap();
}
}
}
impl Drop for Blob {
fn drop(&mut self) {
if !self.IsClosed() {
self.clean_up_file_resource();
}
}
}
fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<Vec<u8>, ()> {
@ -307,8 +345,8 @@ impl BlobMethods for Blob {
// Step 2
self.isClosed_.set(true);
// TODO Step 3 if Blob URL Store is implemented
// Step 3
self.clean_up_file_resource();
}
}

View file

@ -16,7 +16,7 @@ use dom::urlsearchparams::URLSearchParams;
use ipc_channel::ipc;
use net_traits::IpcSend;
use net_traits::blob_url_store::parse_blob_url;
use net_traits::filemanager_thread::{SelectedFileId, FileManagerThreadMsg};
use net_traits::filemanager_thread::{FileOrigin, SelectedFileId, FileManagerThreadMsg};
use std::borrow::ToOwned;
use std::default::Default;
use url::quirks::domain_to_unicode;
@ -125,7 +125,7 @@ impl URL {
return DOMString::from(URL::unicode_serialization_blob_url(&origin, &id));
}
let id = blob.get_id();
let id = blob.get_blob_url_id();
DOMString::from(URL::unicode_serialization_blob_url(&origin, &id.0))
}
@ -148,7 +148,7 @@ impl URL {
let filemanager = global.resource_threads().sender();
let id = SelectedFileId(id.simple().to_string());
let (tx, rx) = ipc::channel().unwrap();
let msg = FileManagerThreadMsg::DecRef(id, origin, tx);
let msg = FileManagerThreadMsg::RevokeBlobURL(id, origin, tx);
let _ = filemanager.send(msg);
let _ = rx.recv().unwrap();
@ -173,12 +173,11 @@ impl URL {
result
}
// XXX: change String to FileOrigin
/* NOTE(izgzhen): WebKit will return things like blob:file:///XXX
while Chrome will return blob:null/XXX
This is not well-specified, and I prefer the WebKit way here
*/
fn get_blob_origin(url: &Url) -> String {
fn get_blob_origin(url: &Url) -> FileOrigin {
if url.scheme() == "file" {
"file://".to_string()
} else {