mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Put Blob URL online
This commit is contained in:
parent
4b78b9adab
commit
fdc3a8e3ac
17 changed files with 260 additions and 191 deletions
|
@ -15,7 +15,7 @@ use encoding::all::UTF_8;
|
|||
use encoding::types::{EncoderTrap, Encoding};
|
||||
use ipc_channel::ipc;
|
||||
use net_traits::IpcSend;
|
||||
use net_traits::blob_url_store::BlobBuf;
|
||||
use net_traits::blob_url_store::{BlobBuf, get_blob_origin};
|
||||
use net_traits::filemanager_thread::{FileManagerThreadMsg, SelectedFileId, RelativePos};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::cell::Cell;
|
||||
|
@ -174,7 +174,7 @@ impl Blob {
|
|||
match *self.blob_impl.borrow() {
|
||||
BlobImpl::File(ref f) => {
|
||||
let global = self.global();
|
||||
let origin = global.r().get_url().origin().unicode_serialization();
|
||||
let origin = get_blob_origin(&global.r().get_url());
|
||||
let filemanager = global.r().resource_threads().sender();
|
||||
let (tx, rx) = ipc::channel().unwrap();
|
||||
|
||||
|
@ -185,7 +185,9 @@ impl Blob {
|
|||
Err(_) => SelectedFileId("".to_string()) // Return a dummy id on error
|
||||
}
|
||||
}
|
||||
BlobImpl::Memory(ref slice) => self.promote_to_file(slice),
|
||||
BlobImpl::Memory(ref slice) => {
|
||||
self.promote(slice, true)
|
||||
}
|
||||
BlobImpl::Sliced(ref parent, ref rel_pos) => {
|
||||
match *parent.blob_impl.borrow() {
|
||||
BlobImpl::Sliced(_, _) => {
|
||||
|
@ -196,7 +198,7 @@ impl Blob {
|
|||
BlobImpl::File(ref f) =>
|
||||
self.create_sliced_url_id(&f.id, rel_pos),
|
||||
BlobImpl::Memory(ref bytes) => {
|
||||
let parent_id = parent.promote_to_file(bytes);
|
||||
let parent_id = parent.promote(bytes, false);
|
||||
*self.blob_impl.borrow_mut() = BlobImpl::Sliced(parent.clone(), rel_pos.clone());
|
||||
self.create_sliced_url_id(&parent_id, rel_pos)
|
||||
}
|
||||
|
@ -206,10 +208,12 @@ impl Blob {
|
|||
}
|
||||
|
||||
/// Promite memory-based Blob to file-based,
|
||||
/// The bytes in data slice will be transferred to file manager thread
|
||||
fn promote_to_file(&self, bytes: &[u8]) -> SelectedFileId {
|
||||
/// The bytes in data slice will be transferred to file manager thread.
|
||||
/// Depending on set_valid, the returned FileID can be part of
|
||||
/// valid or invalid Blob URL.
|
||||
fn promote(&self, bytes: &[u8], set_valid: bool) -> SelectedFileId {
|
||||
let global = self.global();
|
||||
let origin = global.r().get_url().origin().unicode_serialization();
|
||||
let origin = get_blob_origin(&global.r().get_url());
|
||||
let filemanager = global.r().resource_threads().sender();
|
||||
|
||||
let blob_buf = BlobBuf {
|
||||
|
@ -220,7 +224,7 @@ impl Blob {
|
|||
};
|
||||
|
||||
let (tx, rx) = ipc::channel().unwrap();
|
||||
let _ = filemanager.send(FileManagerThreadMsg::PromoteMemory(blob_buf, tx, origin.clone()));
|
||||
let _ = filemanager.send(FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, tx, origin.clone()));
|
||||
|
||||
match rx.recv().unwrap() {
|
||||
Ok(new_id) => SelectedFileId(new_id.0),
|
||||
|
@ -234,7 +238,7 @@ impl Blob {
|
|||
rel_pos: &RelativePos) -> SelectedFileId {
|
||||
let global = self.global();
|
||||
|
||||
let origin = global.r().get_url().origin().unicode_serialization();
|
||||
let origin = get_blob_origin(&global.r().get_url());
|
||||
|
||||
let filemanager = global.r().resource_threads().sender();
|
||||
let (tx, rx) = ipc::channel().unwrap();
|
||||
|
@ -252,7 +256,7 @@ impl Blob {
|
|||
fn clean_up_file_resource(&self) {
|
||||
if let BlobImpl::File(ref f) = *self.blob_impl.borrow() {
|
||||
let global = self.global();
|
||||
let origin = global.r().get_url().origin().unicode_serialization();
|
||||
let origin = get_blob_origin(&global.r().get_url());
|
||||
|
||||
let filemanager = global.r().resource_threads().sender();
|
||||
let (tx, rx) = ipc::channel().unwrap();
|
||||
|
@ -275,19 +279,15 @@ impl Drop for Blob {
|
|||
fn read_file(global: GlobalRef, id: SelectedFileId) -> Result<Vec<u8>, ()> {
|
||||
let file_manager = global.filemanager_thread();
|
||||
let (chan, recv) = ipc::channel().map_err(|_|())?;
|
||||
let origin = global.get_url().origin().unicode_serialization();
|
||||
let msg = FileManagerThreadMsg::ReadFile(chan, id, origin);
|
||||
let origin = get_blob_origin(&global.get_url());
|
||||
let check_url_validity = false;
|
||||
let msg = FileManagerThreadMsg::ReadFile(chan, id, check_url_validity, origin);
|
||||
let _ = file_manager.send(msg);
|
||||
|
||||
let result = match recv.recv() {
|
||||
Ok(ret) => ret,
|
||||
Err(e) => {
|
||||
debug!("File manager thread has problem {:?}", e);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
result.map_err(|_|())
|
||||
match recv.recv().unwrap() {
|
||||
Ok(blob_buf) => Ok(blob_buf.bytes),
|
||||
Err(_) => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract bytes from BlobParts, used by Blob and File constructor
|
||||
|
@ -389,7 +389,7 @@ fn is_ascii_printable(string: &str) -> bool {
|
|||
/// Bump the reference counter in file manager thread
|
||||
fn inc_ref_id(global: GlobalRef, id: SelectedFileId) {
|
||||
let file_manager = global.filemanager_thread();
|
||||
let origin = global.get_url().origin().unicode_serialization();
|
||||
let origin = get_blob_origin(&global.get_url());
|
||||
let msg = FileManagerThreadMsg::IncRef(id, origin);
|
||||
let _ = file_manager.send(msg);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ use ipc_channel::ipc::{self, IpcSender};
|
|||
use mime_guess;
|
||||
use msg::constellation_msg::Key;
|
||||
use net_traits::IpcSend;
|
||||
use net_traits::blob_url_store::get_blob_origin;
|
||||
use net_traits::filemanager_thread::{FileManagerThreadMsg, FilterPattern};
|
||||
use script_traits::ScriptMsg as ConstellationMsg;
|
||||
use std::borrow::ToOwned;
|
||||
|
@ -749,7 +750,7 @@ impl HTMLInputElement {
|
|||
// Select files by invoking UI or by passed in argument
|
||||
fn select_files(&self, opt_test_paths: Option<Vec<DOMString>>) {
|
||||
let window = window_from_node(self);
|
||||
let origin = window.get_url().origin().unicode_serialization();
|
||||
let origin = get_blob_origin(&window.get_url());
|
||||
let filemanager = window.resource_threads().sender();
|
||||
|
||||
let mut files: Vec<Root<File>> = vec![];
|
||||
|
@ -770,13 +771,6 @@ impl HTMLInputElement {
|
|||
for selected in selected_files {
|
||||
files.push(File::new_from_selected(window.r(), selected));
|
||||
}
|
||||
|
||||
target.fire_event("input",
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
target.fire_event("change",
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
},
|
||||
Err(err) => error = Some(err),
|
||||
};
|
||||
|
@ -799,13 +793,6 @@ impl HTMLInputElement {
|
|||
match recv.recv().expect("IpcSender side error") {
|
||||
Ok(selected) => {
|
||||
files.push(File::new_from_selected(window.r(), selected));
|
||||
|
||||
target.fire_event("input",
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
target.fire_event("change",
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
},
|
||||
Err(err) => error = Some(err),
|
||||
};
|
||||
|
@ -816,6 +803,13 @@ impl HTMLInputElement {
|
|||
} else {
|
||||
let filelist = FileList::new(window.r(), files);
|
||||
self.filelist.set(Some(&filelist));
|
||||
|
||||
target.fire_event("input",
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
target.fire_event("change",
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ use dom::urlhelper::UrlHelper;
|
|||
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::{FileOrigin, SelectedFileId, FileManagerThreadMsg};
|
||||
use net_traits::blob_url_store::{get_blob_origin, parse_blob_url};
|
||||
use net_traits::filemanager_thread::{SelectedFileId, FileManagerThreadMsg};
|
||||
use std::borrow::ToOwned;
|
||||
use std::default::Default;
|
||||
use url::quirks::domain_to_unicode;
|
||||
|
@ -117,7 +117,7 @@ impl URL {
|
|||
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 = URL::get_blob_origin(&global.get_url());
|
||||
let origin = get_blob_origin(&global.get_url());
|
||||
|
||||
if blob.IsClosed() {
|
||||
// Generate a dummy id
|
||||
|
@ -141,10 +141,10 @@ impl URL {
|
|||
|
||||
NOTE: The first step is unnecessary, since closed blobs do not exist in the store
|
||||
*/
|
||||
let origin = global.get_url().origin().unicode_serialization();
|
||||
let origin = get_blob_origin(&global.get_url());
|
||||
|
||||
if let Ok(url) = Url::parse(&url) {
|
||||
if let Some((id, _)) = parse_blob_url(&url) {
|
||||
if let Ok((id, _, _)) = parse_blob_url(&url) {
|
||||
let filemanager = global.resource_threads().sender();
|
||||
let id = SelectedFileId(id.simple().to_string());
|
||||
let (tx, rx) = ipc::channel().unwrap();
|
||||
|
@ -172,18 +172,6 @@ impl URL {
|
|||
|
||||
result
|
||||
}
|
||||
|
||||
/* 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) -> FileOrigin {
|
||||
if url.scheme() == "file" {
|
||||
"file://".to_string()
|
||||
} else {
|
||||
url.origin().unicode_serialization()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl URLMethods for URL {
|
||||
|
|
|
@ -368,6 +368,12 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
// Step 11 - abort existing requests
|
||||
self.terminate_ongoing_fetch();
|
||||
|
||||
// TODO(izgzhen): In the WPT test: FileAPI/blob/Blob-XHR-revoke.html,
|
||||
// the xhr.open(url) is expected to hold a reference to the URL,
|
||||
// thus renders following revocations invalid. Though we won't
|
||||
// implement this for now, if ever needed, we should check blob
|
||||
// scheme and trigger corresponding actions here.
|
||||
|
||||
// Step 12
|
||||
*self.request_method.borrow_mut() = parsed_method;
|
||||
*self.request_url.borrow_mut() = Some(parsed_url);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue