mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Auto merge of #13961 - servo:sync-fetch, r=jdm
Move remaining users of the legacy networking stack to fetch. Fixes #13931. Fixes #13714.
This commit is contained in:
commit
56f4a691db
15 changed files with 155 additions and 233 deletions
|
@ -25,7 +25,6 @@ ipc-channel = "0.5"
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.3.5"
|
log = "0.3.5"
|
||||||
mime = "0.2"
|
|
||||||
msg = {path = "../msg"}
|
msg = {path = "../msg"}
|
||||||
net_traits = {path = "../net_traits"}
|
net_traits = {path = "../net_traits"}
|
||||||
ordered-float = "0.2.2"
|
ordered-float = "0.2.2"
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
use font_template::{FontTemplate, FontTemplateDescriptor};
|
use font_template::{FontTemplate, FontTemplateDescriptor};
|
||||||
use fontsan;
|
use fontsan;
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use net_traits::{CoreResourceThread, FetchResponseMsg, fetch_async};
|
||||||
use mime::{TopLevel, SubLevel};
|
use net_traits::request::{Destination, RequestInit, Type as RequestType};
|
||||||
use net_traits::{AsyncResponseTarget, LoadContext, CoreResourceThread, ResponseAction, load_async};
|
|
||||||
use platform::font_context::FontContextHandle;
|
use platform::font_context::FontContextHandle;
|
||||||
use platform::font_list::SANS_SERIF_FONT_FAMILY;
|
use platform::font_list::SANS_SERIF_FONT_FAMILY;
|
||||||
use platform::font_list::for_each_available_family;
|
use platform::font_list::for_each_available_family;
|
||||||
|
@ -25,7 +24,6 @@ use string_cache::Atom;
|
||||||
use style::font_face::{EffectiveSources, Source};
|
use style::font_face::{EffectiveSources, Source};
|
||||||
use style::properties::longhands::font_family::computed_value::FontFamily;
|
use style::properties::longhands::font_family::computed_value::FontFamily;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::prefs::PREFS;
|
|
||||||
use util::thread::spawn_named;
|
use util::thread::spawn_named;
|
||||||
use webrender_traits;
|
use webrender_traits;
|
||||||
|
|
||||||
|
@ -206,49 +204,33 @@ impl FontCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
match src {
|
match src {
|
||||||
Source::Url(ref url_source) => {
|
Source::Url(url_source) => {
|
||||||
let url = &url_source.url;
|
// https://drafts.csswg.org/css-fonts/#font-fetching-requirements
|
||||||
let (data_sender, data_receiver) = ipc::channel().unwrap();
|
let url = url_source.url;
|
||||||
let data_target = AsyncResponseTarget {
|
let request = RequestInit {
|
||||||
sender: data_sender,
|
url: url.clone(),
|
||||||
|
type_: RequestType::Font,
|
||||||
|
destination: Destination::Font,
|
||||||
|
origin: url.clone(),
|
||||||
|
.. RequestInit::default()
|
||||||
};
|
};
|
||||||
load_async(LoadContext::Font,
|
|
||||||
self.core_resource_thread.clone(),
|
|
||||||
url.clone(),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
data_target);
|
|
||||||
let channel_to_self = self.channel_to_self.clone();
|
let channel_to_self = self.channel_to_self.clone();
|
||||||
let url = (*url).clone();
|
|
||||||
let bytes = Mutex::new(Vec::new());
|
let bytes = Mutex::new(Vec::new());
|
||||||
let response_valid = Mutex::new(false);
|
let response_valid = Mutex::new(false);
|
||||||
ROUTER.add_route(data_receiver.to_opaque(), box move |message| {
|
fetch_async(request, &self.core_resource_thread, move |response| {
|
||||||
let response: ResponseAction = message.to().unwrap();
|
|
||||||
match response {
|
match response {
|
||||||
ResponseAction::HeadersAvailable(meta_result) => {
|
FetchResponseMsg::ProcessRequestBody |
|
||||||
let is_response_valid = match meta_result {
|
FetchResponseMsg::ProcessRequestEOF => (),
|
||||||
Ok(ref metadata) => {
|
FetchResponseMsg::ProcessResponse(meta_result) => {
|
||||||
metadata.content_type.as_ref().map_or(false, |content_type| {
|
*response_valid.lock().unwrap() = meta_result.is_ok();
|
||||||
let mime = &content_type.0;
|
|
||||||
is_supported_font_type(&(mime.0).0, &mime.1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(_) => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
info!("{} font with MIME type {}",
|
|
||||||
if is_response_valid { "Loading" } else { "Ignoring" },
|
|
||||||
meta_result.map(|ref meta| format!("{:?}", meta.content_type))
|
|
||||||
.unwrap_or(format!("<Network Error>")));
|
|
||||||
*response_valid.lock().unwrap() = is_response_valid;
|
|
||||||
}
|
}
|
||||||
ResponseAction::DataAvailable(new_bytes) => {
|
FetchResponseMsg::ProcessResponseChunk(new_bytes) => {
|
||||||
if *response_valid.lock().unwrap() {
|
if *response_valid.lock().unwrap() {
|
||||||
bytes.lock().unwrap().extend(new_bytes.into_iter())
|
bytes.lock().unwrap().extend(new_bytes.into_iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResponseAction::ResponseComplete(response) => {
|
FetchResponseMsg::ProcessResponseEOF(response) => {
|
||||||
if response.is_err() || !*response_valid.lock().unwrap() {
|
if response.is_err() || !*response_valid.lock().unwrap() {
|
||||||
let msg = Command::AddWebFont(family_name.clone(), sources.clone(), sender.clone());
|
let msg = Command::AddWebFont(family_name.clone(), sources.clone(), sender.clone());
|
||||||
channel_to_self.send(msg).unwrap();
|
channel_to_self.send(msg).unwrap();
|
||||||
|
@ -480,25 +462,6 @@ impl FontCacheThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// derived from http://stackoverflow.com/a/10864297/3830
|
|
||||||
fn is_supported_font_type(toplevel: &TopLevel, sublevel: &SubLevel) -> bool {
|
|
||||||
if !PREFS.get("network.mime.sniff").as_boolean().unwrap_or(false) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
match (toplevel, sublevel) {
|
|
||||||
(&TopLevel::Application, &SubLevel::Ext(ref ext)) => {
|
|
||||||
match &ext[..] {
|
|
||||||
//FIXME: once sniffing is enabled by default, we shouldn't need nonstandard
|
|
||||||
// MIME types here.
|
|
||||||
"font-sfnt" | "x-font-ttf" | "x-font-truetype" | "x-font-opentype" => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)]
|
||||||
pub struct LowercaseString {
|
pub struct LowercaseString {
|
||||||
|
|
|
@ -62,7 +62,6 @@ extern crate lazy_static;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate mime;
|
|
||||||
extern crate msg;
|
extern crate msg;
|
||||||
extern crate net_traits;
|
extern crate net_traits;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
|
|
|
@ -492,8 +492,8 @@ fn basic_fetch<UI: 'static + UIProvider>(request: Rc<Request>,
|
||||||
},
|
},
|
||||||
|
|
||||||
"ftp" => {
|
"ftp" => {
|
||||||
// XXXManishearth handle these
|
debug!("ftp is not implemented");
|
||||||
panic!("Unimplemented scheme for Fetch")
|
Response::network_error(NetworkError::Internal("Unexpected scheme".into()))
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => Response::network_error(NetworkError::Internal("Unexpected scheme".into()))
|
_ => Response::network_error(NetworkError::Internal("Unexpected scheme".into()))
|
||||||
|
|
|
@ -5,13 +5,12 @@
|
||||||
use immeta::load_from_buf;
|
use immeta::load_from_buf;
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
use net_traits::{CoreResourceThread, NetworkError, fetch_async, FetchResponseMsg, FetchMetadata, Metadata};
|
||||||
use net_traits::{AsyncResponseTarget, CoreResourceMsg, CoreResourceThread, LoadConsumer, LoadData, LoadOrigin};
|
|
||||||
use net_traits::{LoadContext, NetworkError, ResponseAction};
|
|
||||||
use net_traits::image::base::{Image, ImageMetadata, PixelFormat, load_from_memory};
|
use net_traits::image::base::{Image, ImageMetadata, PixelFormat, load_from_memory};
|
||||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState};
|
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState};
|
||||||
use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
|
use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
|
||||||
use net_traits::image_cache_thread::ImageResponder;
|
use net_traits::image_cache_thread::ImageResponder;
|
||||||
|
use net_traits::request::{Destination, RequestInit, Type as RequestType};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
|
@ -226,6 +225,15 @@ impl ImageListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A legacy type that's mostly redundant with FetchResponseMsg.
|
||||||
|
// FIXME(#13717): remove this type.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
enum ResponseAction {
|
||||||
|
HeadersAvailable(Result<Metadata, NetworkError>),
|
||||||
|
DataAvailable(Vec<u8>),
|
||||||
|
ResponseComplete(Result<(), NetworkError>)
|
||||||
|
}
|
||||||
|
|
||||||
struct ResourceLoadInfo {
|
struct ResourceLoadInfo {
|
||||||
action: ResponseAction,
|
action: ResponseAction,
|
||||||
key: LoadKey,
|
key: LoadKey,
|
||||||
|
@ -305,19 +313,6 @@ fn convert_format(format: PixelFormat) -> webrender_traits::ImageFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImageCacheOrigin;
|
|
||||||
impl LoadOrigin for ImageCacheOrigin {
|
|
||||||
fn referrer_url(&self) -> Option<Url> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_placeholder_image(webrender_api: &webrender_traits::RenderApi) -> io::Result<Arc<Image>> {
|
fn get_placeholder_image(webrender_api: &webrender_traits::RenderApi) -> io::Result<Arc<Image>> {
|
||||||
let mut placeholder_path = try!(resources_dir_path());
|
let mut placeholder_path = try!(resources_dir_path());
|
||||||
placeholder_path.push("rippy.png");
|
placeholder_path.push("rippy.png");
|
||||||
|
@ -530,25 +525,41 @@ impl ImageCache {
|
||||||
CacheResult::Miss => {
|
CacheResult::Miss => {
|
||||||
// A new load request! Request the load from
|
// A new load request! Request the load from
|
||||||
// the resource thread.
|
// the resource thread.
|
||||||
let load_data = LoadData::new(LoadContext::Image,
|
// https://html.spec.whatwg.org/multipage/#update-the-image-data
|
||||||
(*ref_url).clone(),
|
// step 12.
|
||||||
&ImageCacheOrigin);
|
let request = RequestInit {
|
||||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
url: (*ref_url).clone(),
|
||||||
let response_target = AsyncResponseTarget {
|
type_: RequestType::Image,
|
||||||
sender: action_sender,
|
destination: Destination::Image,
|
||||||
|
origin: (*ref_url).clone(),
|
||||||
|
.. RequestInit::default()
|
||||||
};
|
};
|
||||||
let msg = CoreResourceMsg::Load(load_data,
|
|
||||||
LoadConsumer::Listener(response_target),
|
|
||||||
None);
|
|
||||||
let progress_sender = self.progress_sender.clone();
|
let progress_sender = self.progress_sender.clone();
|
||||||
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
fetch_async(request, &self.core_resource_thread, move |action| {
|
||||||
let action: ResponseAction = message.to().unwrap();
|
let action = match action {
|
||||||
|
FetchResponseMsg::ProcessRequestBody |
|
||||||
|
FetchResponseMsg::ProcessRequestEOF => return,
|
||||||
|
FetchResponseMsg::ProcessResponse(meta_result) => {
|
||||||
|
ResponseAction::HeadersAvailable(meta_result.map(|m| {
|
||||||
|
match m {
|
||||||
|
FetchMetadata::Unfiltered(m) => m,
|
||||||
|
FetchMetadata::Filtered { unsafe_, .. } => unsafe_
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
FetchResponseMsg::ProcessResponseChunk(new_bytes) => {
|
||||||
|
ResponseAction::DataAvailable(new_bytes)
|
||||||
|
}
|
||||||
|
FetchResponseMsg::ProcessResponseEOF(response) => {
|
||||||
|
ResponseAction::ResponseComplete(response)
|
||||||
|
}
|
||||||
|
};
|
||||||
progress_sender.send(ResourceLoadInfo {
|
progress_sender.send(ResourceLoadInfo {
|
||||||
action: action,
|
action: action,
|
||||||
key: load_key,
|
key: load_key,
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
});
|
});
|
||||||
self.core_resource_thread.send(msg).unwrap();
|
|
||||||
}
|
}
|
||||||
CacheResult::Hit => {
|
CacheResult::Hit => {
|
||||||
// Request is already on its way.
|
// Request is already on its way.
|
||||||
|
|
|
@ -24,8 +24,8 @@ use hyper::mime::{Mime, SubLevel, TopLevel};
|
||||||
use hyper_serde::Serde;
|
use hyper_serde::Serde;
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender};
|
||||||
use mime_classifier::{ApacheBugFlag, MimeClassifier, NoSniffFlag};
|
use mime_classifier::{ApacheBugFlag, MimeClassifier, NoSniffFlag};
|
||||||
use net_traits::{AsyncResponseTarget, CoreResourceThread, Metadata, ProgressMsg, ResponseAction};
|
use net_traits::{CookieSource, CoreResourceThread, Metadata, ProgressMsg};
|
||||||
use net_traits::{CookieSource, CoreResourceMsg, FetchResponseMsg, FetchTaskTarget, LoadConsumer};
|
use net_traits::{CoreResourceMsg, FetchResponseMsg, FetchTaskTarget, LoadConsumer};
|
||||||
use net_traits::{CustomResponseMediator, LoadData, LoadResponse, NetworkError, ResourceId};
|
use net_traits::{CustomResponseMediator, LoadData, LoadResponse, NetworkError, ResourceId};
|
||||||
use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData};
|
use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData};
|
||||||
use net_traits::LoadContext;
|
use net_traits::LoadContext;
|
||||||
|
@ -57,7 +57,6 @@ const TFD_PROVIDER: &'static TFDProvider = &TFDProvider;
|
||||||
|
|
||||||
pub enum ProgressSender {
|
pub enum ProgressSender {
|
||||||
Channel(IpcSender<ProgressMsg>),
|
Channel(IpcSender<ProgressMsg>),
|
||||||
Listener(AsyncResponseTarget),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -73,14 +72,6 @@ impl ProgressSender {
|
||||||
pub fn send(&self, msg: ProgressMsg) -> Result<(), ()> {
|
pub fn send(&self, msg: ProgressMsg) -> Result<(), ()> {
|
||||||
match *self {
|
match *self {
|
||||||
ProgressSender::Channel(ref c) => c.send(msg).map_err(|_| ()),
|
ProgressSender::Channel(ref c) => c.send(msg).map_err(|_| ()),
|
||||||
ProgressSender::Listener(ref b) => {
|
|
||||||
let action = match msg {
|
|
||||||
ProgressMsg::Payload(buf) => ResponseAction::DataAvailable(buf),
|
|
||||||
ProgressMsg::Done(status) => ResponseAction::ResponseComplete(status),
|
|
||||||
};
|
|
||||||
b.invoke_with_listener(action);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +80,7 @@ pub fn send_error(url: Url, err: NetworkError, start_chan: LoadConsumer) {
|
||||||
let mut metadata: Metadata = Metadata::default(url);
|
let mut metadata: Metadata = Metadata::default(url);
|
||||||
metadata.status = None;
|
metadata.status = None;
|
||||||
|
|
||||||
if let Ok(p) = start_sending_opt(start_chan, metadata, Some(err.clone())) {
|
if let Ok(p) = start_sending_opt(start_chan, metadata) {
|
||||||
p.send(Done(Err(err))).unwrap();
|
p.send(Done(Err(err))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,14 +121,13 @@ pub fn start_sending_sniffed_opt(start_chan: LoadConsumer, mut metadata: Metadat
|
||||||
Some(Serde(ContentType(Mime(mime_tp, mime_sb, vec![]))));
|
Some(Serde(ContentType(Mime(mime_tp, mime_sb, vec![]))));
|
||||||
}
|
}
|
||||||
|
|
||||||
start_sending_opt(start_chan, metadata, None)
|
start_sending_opt(start_chan, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message.
|
/// For use by loaders in responding to a Load message.
|
||||||
/// It takes an optional NetworkError, so that we can extract the SSL Validation errors
|
/// It takes an optional NetworkError, so that we can extract the SSL Validation errors
|
||||||
/// and take it to the HTML parser
|
/// and take it to the HTML parser
|
||||||
fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata,
|
fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata) -> Result<ProgressSender, ()> {
|
||||||
network_error: Option<NetworkError>) -> Result<ProgressSender, ()> {
|
|
||||||
match start_chan {
|
match start_chan {
|
||||||
LoadConsumer::Channel(start_chan) => {
|
LoadConsumer::Channel(start_chan) => {
|
||||||
let (progress_chan, progress_port) = ipc::channel().unwrap();
|
let (progress_chan, progress_port) = ipc::channel().unwrap();
|
||||||
|
@ -150,16 +140,6 @@ fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata,
|
||||||
Err(_) => Err(())
|
Err(_) => Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LoadConsumer::Listener(target) => {
|
|
||||||
match network_error {
|
|
||||||
Some(NetworkError::SslValidation(url, reason)) => {
|
|
||||||
let error = NetworkError::SslValidation(url, reason);
|
|
||||||
target.invoke_with_listener(ResponseAction::HeadersAvailable(Err(error)));
|
|
||||||
}
|
|
||||||
_ => target.invoke_with_listener(ResponseAction::HeadersAvailable(Ok(metadata))),
|
|
||||||
}
|
|
||||||
Ok(ProgressSender::Listener(target))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ use hyper::method::Method;
|
||||||
use hyper::mime::{Attr, Mime};
|
use hyper::mime::{Attr, Mime};
|
||||||
use hyper_serde::Serde;
|
use hyper_serde::Serde;
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
|
use ipc_channel::router::ROUTER;
|
||||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
use request::{Request, RequestInit};
|
use request::{Request, RequestInit};
|
||||||
use response::{HttpsState, Response};
|
use response::{HttpsState, Response};
|
||||||
|
@ -262,18 +263,6 @@ pub trait Action<Listener> {
|
||||||
fn process(self, listener: &mut Listener);
|
fn process(self, listener: &mut Listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data for passing between threads/processes to indicate a particular action to
|
|
||||||
/// take on a provided network listener.
|
|
||||||
#[derive(Deserialize, Serialize)]
|
|
||||||
pub enum ResponseAction {
|
|
||||||
/// Invoke headers_available
|
|
||||||
HeadersAvailable(Result<Metadata, NetworkError>),
|
|
||||||
/// Invoke data_available
|
|
||||||
DataAvailable(Vec<u8>),
|
|
||||||
/// Invoke response_complete
|
|
||||||
ResponseComplete(Result<(), NetworkError>)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: FetchResponseListener> Action<T> for FetchResponseMsg {
|
impl<T: FetchResponseListener> Action<T> for FetchResponseMsg {
|
||||||
/// Execute the default action on a provided listener.
|
/// Execute the default action on a provided listener.
|
||||||
fn process(self, listener: &mut T) {
|
fn process(self, listener: &mut T) {
|
||||||
|
@ -287,24 +276,10 @@ impl<T: FetchResponseListener> Action<T> for FetchResponseMsg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A target for async networking events. Commonly used to dispatch a runnable event to another
|
|
||||||
/// thread storing the wrapped closure for later execution.
|
|
||||||
#[derive(Deserialize, Serialize)]
|
|
||||||
pub struct AsyncResponseTarget {
|
|
||||||
pub sender: IpcSender<ResponseAction>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsyncResponseTarget {
|
|
||||||
pub fn invoke_with_listener(&self, action: ResponseAction) {
|
|
||||||
self.sender.send(action).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A wrapper for a network load that can either be channel or event-based.
|
/// A wrapper for a network load that can either be channel or event-based.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum LoadConsumer {
|
pub enum LoadConsumer {
|
||||||
Channel(IpcSender<LoadResponse>),
|
Channel(IpcSender<LoadResponse>),
|
||||||
Listener(AsyncResponseTarget),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle to a resource thread
|
/// Handle to a resource thread
|
||||||
|
@ -446,40 +421,17 @@ pub enum CoreResourceMsg {
|
||||||
Exit(IpcSender<()>),
|
Exit(IpcSender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LoadOriginData {
|
|
||||||
pipeline: Option<PipelineId>,
|
|
||||||
referrer_policy: Option<ReferrerPolicy>,
|
|
||||||
referrer_url: Option<Url>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LoadOrigin for LoadOriginData {
|
|
||||||
fn referrer_url(&self) -> Option<Url> {
|
|
||||||
self.referrer_url.clone()
|
|
||||||
}
|
|
||||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
|
||||||
self.referrer_policy.clone()
|
|
||||||
}
|
|
||||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
|
||||||
self.pipeline
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Instruct the resource thread to make a new request.
|
/// Instruct the resource thread to make a new request.
|
||||||
pub fn load_async(context: LoadContext,
|
pub fn fetch_async<F>(request: RequestInit,
|
||||||
core_resource_thread: CoreResourceThread,
|
core_resource_thread: &CoreResourceThread,
|
||||||
url: Url,
|
f: F)
|
||||||
pipeline: Option<PipelineId>,
|
where F: Fn(FetchResponseMsg) + Send + 'static
|
||||||
referrer_policy: Option<ReferrerPolicy>,
|
{
|
||||||
referrer_url: Option<Url>,
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
listener: AsyncResponseTarget) {
|
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||||
let load = LoadOriginData {
|
f(message.to().unwrap());
|
||||||
pipeline: pipeline,
|
});
|
||||||
referrer_policy: referrer_policy,
|
core_resource_thread.send(CoreResourceMsg::Fetch(request, action_sender)).unwrap();
|
||||||
referrer_url: referrer_url
|
|
||||||
};
|
|
||||||
let load_data = LoadData::new(context, url, &load);
|
|
||||||
let consumer = LoadConsumer::Listener(listener);
|
|
||||||
core_resource_thread.send(CoreResourceMsg::Load(load_data, consumer, None)).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Message sent in response to `Load`. Contains metadata, and a port
|
/// Message sent in response to `Load`. Contains metadata, and a port
|
||||||
|
@ -590,22 +542,28 @@ pub enum ProgressMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function for synchronously loading a whole resource.
|
/// Convenience function for synchronously loading a whole resource.
|
||||||
pub fn load_whole_resource(context: LoadContext,
|
pub fn load_whole_resource(request: RequestInit,
|
||||||
core_resource_thread: &CoreResourceThread,
|
core_resource_thread: &CoreResourceThread)
|
||||||
url: Url,
|
-> Result<(Metadata, Vec<u8>), NetworkError> {
|
||||||
load_origin: &LoadOrigin)
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
-> Result<(Metadata, Vec<u8>), NetworkError> {
|
core_resource_thread.send(CoreResourceMsg::Fetch(request, action_sender)).unwrap();
|
||||||
let (start_chan, start_port) = ipc::channel().unwrap();
|
|
||||||
let load_data = LoadData::new(context, url, load_origin);
|
|
||||||
core_resource_thread.send(CoreResourceMsg::Load(load_data, LoadConsumer::Channel(start_chan), None)).unwrap();
|
|
||||||
let response = start_port.recv().unwrap();
|
|
||||||
|
|
||||||
let mut buf = vec!();
|
let mut buf = vec!();
|
||||||
|
let mut metadata = None;
|
||||||
loop {
|
loop {
|
||||||
match response.progress_port.recv().unwrap() {
|
match action_receiver.recv().unwrap() {
|
||||||
ProgressMsg::Payload(data) => buf.extend_from_slice(&data),
|
FetchResponseMsg::ProcessRequestBody |
|
||||||
ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)),
|
FetchResponseMsg::ProcessRequestEOF => (),
|
||||||
ProgressMsg::Done(Err(e)) => return Err(e)
|
FetchResponseMsg::ProcessResponse(Ok(m)) => {
|
||||||
|
metadata = Some(match m {
|
||||||
|
FetchMetadata::Unfiltered(m) => m,
|
||||||
|
FetchMetadata::Filtered { unsafe_, .. } => unsafe_
|
||||||
|
})
|
||||||
|
},
|
||||||
|
FetchResponseMsg::ProcessResponseChunk(data) => buf.extend_from_slice(&data),
|
||||||
|
FetchResponseMsg::ProcessResponseEOF(Ok(())) => return Ok((metadata.unwrap(), buf)),
|
||||||
|
FetchResponseMsg::ProcessResponse(Err(e)) |
|
||||||
|
FetchResponseMsg::ProcessResponseEOF(Err(e)) => return Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,8 @@ use js::jsapi::{JSAutoCompartment, JSContext};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::{IpcSend, LoadContext, load_whole_resource};
|
use net_traits::{IpcSend, load_whole_resource};
|
||||||
|
use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
||||||
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
|
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
|
||||||
|
@ -160,10 +161,24 @@ impl DedicatedWorkerGlobalScope {
|
||||||
|
|
||||||
let roots = RootCollection::new();
|
let roots = RootCollection::new();
|
||||||
let _stack_roots_tls = StackRootTLS::new(&roots);
|
let _stack_roots_tls = StackRootTLS::new(&roots);
|
||||||
let (metadata, bytes) = match load_whole_resource(LoadContext::Script,
|
|
||||||
&init.resource_threads.sender(),
|
let WorkerScriptLoadOrigin { referrer_url, referrer_policy, pipeline_id } = worker_load_origin;
|
||||||
worker_url,
|
|
||||||
&worker_load_origin) {
|
let request = RequestInit {
|
||||||
|
url: worker_url.clone(),
|
||||||
|
type_: RequestType::Script,
|
||||||
|
destination: Destination::Worker,
|
||||||
|
credentials_mode: CredentialsMode::Include,
|
||||||
|
use_url_credentials: true,
|
||||||
|
origin: worker_url,
|
||||||
|
pipeline_id: pipeline_id,
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy,
|
||||||
|
.. RequestInit::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let (metadata, bytes) = match load_whole_resource(request,
|
||||||
|
&init.resource_threads.sender()) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("error loading script {}", serialized_worker_url);
|
println!("error loading script {}", serialized_worker_url);
|
||||||
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
|
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
|
||||||
|
|
|
@ -23,10 +23,11 @@ use ipc_channel::router::ROUTER;
|
||||||
use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext};
|
use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use net_traits::{LoadContext, load_whole_resource, IpcSend, CustomResponseMediator};
|
use net_traits::{load_whole_resource, IpcSend, CustomResponseMediator};
|
||||||
|
use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx, ScriptChan};
|
use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx, ScriptChan};
|
||||||
use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg};
|
use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg, WorkerScriptLoadOrigin};
|
||||||
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
|
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -151,10 +152,24 @@ impl ServiceWorkerGlobalScope {
|
||||||
thread_state::initialize(SCRIPT | IN_WORKER);
|
thread_state::initialize(SCRIPT | IN_WORKER);
|
||||||
let roots = RootCollection::new();
|
let roots = RootCollection::new();
|
||||||
let _stack_roots_tls = StackRootTLS::new(&roots);
|
let _stack_roots_tls = StackRootTLS::new(&roots);
|
||||||
let (url, source) = match load_whole_resource(LoadContext::Script,
|
|
||||||
&init.resource_threads.sender(),
|
let WorkerScriptLoadOrigin { referrer_url, referrer_policy, pipeline_id } = worker_load_origin;
|
||||||
script_url,
|
|
||||||
&worker_load_origin) {
|
let request = RequestInit {
|
||||||
|
url: script_url.clone(),
|
||||||
|
type_: RequestType::Script,
|
||||||
|
destination: Destination::ServiceWorker,
|
||||||
|
credentials_mode: CredentialsMode::Include,
|
||||||
|
use_url_credentials: true,
|
||||||
|
origin: script_url,
|
||||||
|
pipeline_id: pipeline_id,
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy,
|
||||||
|
.. RequestInit::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let (url, source) = match load_whole_resource(request,
|
||||||
|
&init.resource_threads.sender()) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("error loading script {}", serialized_worker_url);
|
println!("error loading script {}", serialized_worker_url);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -27,9 +27,8 @@ use ipc_channel::ipc::IpcSender;
|
||||||
use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime};
|
use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
use net_traits::{IpcSend, load_whole_resource};
|
||||||
use net_traits::{IpcSend, LoadOrigin};
|
use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType};
|
||||||
use net_traits::{LoadContext, load_whole_resource};
|
|
||||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, maybe_take_panic_result};
|
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, maybe_take_panic_result};
|
||||||
use script_runtime::{ScriptThreadEventCategory, PromiseJobQueue, EnqueuedPromiseCallback};
|
use script_runtime::{ScriptThreadEventCategory, PromiseJobQueue, EnqueuedPromiseCallback};
|
||||||
use script_thread::{Runnable, RunnableWrapper};
|
use script_thread::{Runnable, RunnableWrapper};
|
||||||
|
@ -179,18 +178,6 @@ impl WorkerGlobalScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoadOrigin for WorkerGlobalScope {
|
|
||||||
fn referrer_url(&self) -> Option<Url> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
|
||||||
Some(self.upcast::<GlobalScope>().pipeline_id())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
|
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
|
||||||
fn Self_(&self) -> Root<WorkerGlobalScope> {
|
fn Self_(&self) -> Root<WorkerGlobalScope> {
|
||||||
|
@ -221,10 +208,20 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
||||||
rooted!(in(self.runtime.cx()) let mut rval = UndefinedValue());
|
rooted!(in(self.runtime.cx()) let mut rval = UndefinedValue());
|
||||||
for url in urls {
|
for url in urls {
|
||||||
let global_scope = self.upcast::<GlobalScope>();
|
let global_scope = self.upcast::<GlobalScope>();
|
||||||
let (url, source) = match load_whole_resource(LoadContext::Script,
|
let request = NetRequestInit {
|
||||||
&global_scope.resource_threads().sender(),
|
url: url.clone(),
|
||||||
url,
|
type_: RequestType::Script,
|
||||||
self) {
|
destination: Destination::Script,
|
||||||
|
credentials_mode: CredentialsMode::Include,
|
||||||
|
use_url_credentials: true,
|
||||||
|
origin: self.worker_url.clone(),
|
||||||
|
pipeline_id: Some(self.upcast::<GlobalScope>().pipeline_id()),
|
||||||
|
referrer_url: None,
|
||||||
|
referrer_policy: None,
|
||||||
|
.. NetRequestInit::default()
|
||||||
|
};
|
||||||
|
let (url, source) = match load_whole_resource(request,
|
||||||
|
&global_scope.resource_threads().sender()) {
|
||||||
Err(_) => return Err(Error::Network),
|
Err(_) => return Err(Error::Network),
|
||||||
Ok((metadata, bytes)) => {
|
Ok((metadata, bytes)) => {
|
||||||
(metadata.final_url, String::from_utf8(bytes).unwrap())
|
(metadata.final_url, String::from_utf8(bytes).unwrap())
|
||||||
|
|
|
@ -53,7 +53,7 @@ use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use msg::constellation_msg::{FrameId, FrameType, Key, KeyModifiers, KeyState};
|
use msg::constellation_msg::{FrameId, FrameType, Key, KeyModifiers, KeyState};
|
||||||
use msg::constellation_msg::{PipelineId, PipelineNamespaceId, ReferrerPolicy, TraversalDirection};
|
use msg::constellation_msg::{PipelineId, PipelineNamespaceId, ReferrerPolicy, TraversalDirection};
|
||||||
use net_traits::{LoadOrigin, ResourceThreads};
|
use net_traits::ResourceThreads;
|
||||||
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
||||||
use net_traits::image::base::Image;
|
use net_traits::image::base::Image;
|
||||||
use net_traits::image_cache_thread::ImageCacheThread;
|
use net_traits::image_cache_thread::ImageCacheThread;
|
||||||
|
@ -722,15 +722,3 @@ pub struct WorkerScriptLoadOrigin {
|
||||||
/// the pipeline id of the entity requesting the load
|
/// the pipeline id of the entity requesting the load
|
||||||
pub pipeline_id: Option<PipelineId>
|
pub pipeline_id: Option<PipelineId>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoadOrigin for WorkerScriptLoadOrigin {
|
|
||||||
fn referrer_url(&self) -> Option<Url> {
|
|
||||||
self.referrer_url.clone()
|
|
||||||
}
|
|
||||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
|
||||||
self.referrer_policy.clone()
|
|
||||||
}
|
|
||||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
|
||||||
self.pipeline_id.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
1
components/servo/Cargo.lock
generated
1
components/servo/Cargo.lock
generated
|
@ -794,7 +794,6 @@ dependencies = [
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
1
ports/cef/Cargo.lock
generated
1
ports/cef/Cargo.lock
generated
|
@ -710,7 +710,6 @@ dependencies = [
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
[mime_sniffing_font_context.html]
|
[mime_sniffing_font_context.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
prefs: [network.mime.sniff:true]
|
|
||||||
|
|
|
@ -51,8 +51,8 @@ async_test(function() {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open('GET', 'resources/no_mime_type.py?Content-Type=application/xhtml%2Bxml', true);
|
xhr.open('GET', 'resources/no_mime_type.py?Content-Type=application/xhtml%2Bxml', true);
|
||||||
xhr.onload = this.step_func_done(function() {
|
xhr.onload = this.step_func_done(function() {
|
||||||
t4.step_timeout(checkFontNotLoaded.bind(t4, 'fifth', 'sixth'), 500);
|
|
||||||
assert_equals(xhr.getResponseHeader('Content-Type'), 'application/xhtml+xml');
|
assert_equals(xhr.getResponseHeader('Content-Type'), 'application/xhtml+xml');
|
||||||
|
t4.step_timeout(checkFontLoaded, 500);
|
||||||
});
|
});
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}, "XHR Content-Type has xhtml+xml");
|
}, "XHR Content-Type has xhtml+xml");
|
||||||
|
@ -61,8 +61,8 @@ async_test(function() {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open('GET', 'resources/no_mime_type.py?Content-Type=application/xml', true);
|
xhr.open('GET', 'resources/no_mime_type.py?Content-Type=application/xml', true);
|
||||||
xhr.onload = this.step_func_done(function() {
|
xhr.onload = this.step_func_done(function() {
|
||||||
t3.step_timeout(checkFontNotLoaded.bind(t3, 'third', 'fourth'), 500);
|
|
||||||
assert_equals(xhr.getResponseHeader('Content-Type'), 'application/xml');
|
assert_equals(xhr.getResponseHeader('Content-Type'), 'application/xml');
|
||||||
|
t3.step_timeout(checkFontLoaded, 500);
|
||||||
});
|
});
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}, "XHR Content-Type has xml");
|
}, "XHR Content-Type has xml");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue