mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
parent
74f8c0eeb7
commit
ba36a108c1
56 changed files with 674 additions and 518 deletions
|
@ -25,6 +25,9 @@ path = "../net"
|
|||
[dependencies.profile]
|
||||
path = "../profile"
|
||||
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.util]
|
||||
path = "../util"
|
||||
|
||||
|
|
|
@ -20,9 +20,10 @@ use msg::constellation_msg::{IFrameSandboxState, MozBrowserEvent, NavigationDire
|
|||
use msg::constellation_msg::{Key, KeyState, KeyModifiers, LoadData};
|
||||
use msg::constellation_msg::{SubpageId, WindowSizeData};
|
||||
use msg::constellation_msg::{self, ConstellationChan, Failure};
|
||||
use net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
|
||||
use net::resource_task::{self, ResourceTask};
|
||||
use net::storage_task::{StorageTask, StorageTaskMsg};
|
||||
use net::image_cache_task::ImageCacheTaskClient;
|
||||
use net_traits::{self, ResourceTask};
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use net_traits::storage_task::{StorageTask, StorageTaskMsg};
|
||||
use profile::mem;
|
||||
use profile::time;
|
||||
use script_traits::{CompositorEvent, ConstellationControlMsg};
|
||||
|
@ -392,7 +393,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
|||
pipeline.exit(PipelineExitType::Complete);
|
||||
}
|
||||
self.image_cache_task.exit();
|
||||
self.resource_task.send(resource_task::ControlMsg::Exit).unwrap();
|
||||
self.resource_task.send(net_traits::ControlMsg::Exit).unwrap();
|
||||
self.devtools_chan.as_ref().map(|chan| {
|
||||
chan.send(DevtoolsControlMsg::ServerExitMsg).unwrap();
|
||||
});
|
||||
|
|
|
@ -23,6 +23,7 @@ extern crate script_traits;
|
|||
extern crate msg;
|
||||
extern crate net;
|
||||
extern crate profile;
|
||||
extern crate net_traits;
|
||||
#[macro_use]
|
||||
extern crate util;
|
||||
extern crate gleam;
|
||||
|
|
|
@ -16,11 +16,11 @@ use gfx::font_cache_task::FontCacheTask;
|
|||
use layers::geometry::DevicePixel;
|
||||
use msg::constellation_msg::{ConstellationChan, Failure, FrameId, PipelineId, SubpageId};
|
||||
use msg::constellation_msg::{LoadData, WindowSizeData, PipelineExitType, MozBrowserEvent};
|
||||
use net::image_cache_task::ImageCacheTask;
|
||||
use net::resource_task::ResourceTask;
|
||||
use net::storage_task::StorageTask;
|
||||
use profile::mem;
|
||||
use profile::time;
|
||||
use net_traits::ResourceTask;
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use net_traits::storage_task::StorageTask;
|
||||
use std::sync::mpsc::{Receiver, channel};
|
||||
use url::Url;
|
||||
use util::geometry::{PagePx, ViewportPx};
|
||||
|
|
|
@ -11,8 +11,8 @@ path = "lib.rs"
|
|||
[dependencies.plugins]
|
||||
path = "../plugins"
|
||||
|
||||
[dependencies.net]
|
||||
path = "../net"
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.util]
|
||||
path = "../util"
|
||||
|
|
|
@ -33,7 +33,7 @@ use geom::num::Zero;
|
|||
use libc::uintptr_t;
|
||||
use paint_task::PaintLayer;
|
||||
use msg::compositor_msg::LayerId;
|
||||
use net::image::base::Image;
|
||||
use net_traits::image::base::Image;
|
||||
use util::cursor::Cursor;
|
||||
use util::linked_list::prepend_from;
|
||||
use util::geometry::{self, Au, MAX_RECT, ZERO_RECT};
|
||||
|
|
|
@ -10,7 +10,7 @@ use platform::font_context::FontContextHandle;
|
|||
|
||||
use collections::str::Str;
|
||||
use font_template::{FontTemplate, FontTemplateDescriptor};
|
||||
use net::resource_task::{ResourceTask, load_whole_resource};
|
||||
use net_traits::{ResourceTask, load_whole_resource};
|
||||
use platform::font_template::FontTemplateData;
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
|
|
|
@ -31,7 +31,7 @@ extern crate profile;
|
|||
extern crate script_traits;
|
||||
extern crate "rustc-serialize" as rustc_serialize;
|
||||
extern crate unicode;
|
||||
extern crate net;
|
||||
extern crate net_traits;
|
||||
#[macro_use]
|
||||
extern crate util;
|
||||
extern crate msg;
|
||||
|
|
|
@ -29,7 +29,7 @@ use geom::rect::Rect;
|
|||
use geom::side_offsets::SideOffsets2D;
|
||||
use geom::size::Size2D;
|
||||
use libc::types::common::c99::{uint16_t, uint32_t};
|
||||
use net::image::base::Image;
|
||||
use net_traits::image::base::Image;
|
||||
use png::PixelsByColorType;
|
||||
use std::default::Default;
|
||||
use std::f32;
|
||||
|
|
|
@ -34,8 +34,8 @@ path = "../style"
|
|||
[dependencies.plugins]
|
||||
path = "../plugins"
|
||||
|
||||
[dependencies.net]
|
||||
path = "../net"
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.profile]
|
||||
path = "../profile"
|
||||
|
|
|
@ -13,9 +13,9 @@ use gfx::display_list::OpaqueNode;
|
|||
use gfx::font_cache_task::FontCacheTask;
|
||||
use gfx::font_context::FontContext;
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use net::local_image_cache::LocalImageCache;
|
||||
use script::layout_interface::{Animation, LayoutChan};
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
use net_traits::local_image_cache::LocalImageCache;
|
||||
use std::boxed;
|
||||
use std::cell::Cell;
|
||||
use std::ptr;
|
||||
|
|
|
@ -36,7 +36,7 @@ use png::{self, PixelsByColorType};
|
|||
use msg::compositor_msg::ScrollPolicy;
|
||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use net::image::holder::ImageHolder;
|
||||
use net_traits::image::holder::ImageHolder;
|
||||
use util::cursor::Cursor;
|
||||
use util::geometry::{self, Au, ZERO_POINT, to_px, to_frac_px};
|
||||
use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
||||
|
|
|
@ -30,8 +30,8 @@ use gfx::text::text_run::{TextRun, TextRunSlice};
|
|||
use script_traits::UntrustedNodeAddress;
|
||||
use rustc_serialize::{Encodable, Encoder};
|
||||
use msg::constellation_msg::{ConstellationChan, Msg, PipelineId, SubpageId};
|
||||
use net::image::holder::ImageHolder;
|
||||
use net::local_image_cache::LocalImageCache;
|
||||
use net_traits::image::holder::ImageHolder;
|
||||
use net_traits::local_image_cache::LocalImageCache;
|
||||
use util::geometry::{self, Au, ZERO_POINT};
|
||||
use util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin, WritingMode};
|
||||
use util::range::*;
|
||||
|
|
|
@ -41,12 +41,12 @@ use log;
|
|||
use msg::compositor_msg::ScrollPolicy;
|
||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
use msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType, PipelineId};
|
||||
use net::image_cache_task::{ImageCacheTask, ImageResponseMsg};
|
||||
use net::local_image_cache::{ImageResponder, LocalImageCache};
|
||||
use net::resource_task::{ResourceTask, load_bytes_iter};
|
||||
use profile::mem::{self, Report, ReportsChan};
|
||||
use profile::time::{self, ProfilerMetadata, profile};
|
||||
use profile::time::{TimerMetadataFrameType, TimerMetadataReflowType};
|
||||
use net_traits::{load_bytes_iter, ResourceTask};
|
||||
use net_traits::image_cache_task::{ImageCacheTask, ImageResponseMsg};
|
||||
use net_traits::local_image_cache::{ImageResponder, LocalImageCache};
|
||||
use script::dom::bindings::js::LayoutJS;
|
||||
use script::dom::node::{LayoutData, Node};
|
||||
use script::layout_interface::{Animation, ContentBoxResponse, ContentBoxesResponse};
|
||||
|
|
|
@ -30,7 +30,7 @@ extern crate bitflags;
|
|||
#[macro_use]
|
||||
#[no_link]
|
||||
extern crate "plugins" as servo_plugins;
|
||||
|
||||
extern crate net_traits;
|
||||
#[macro_use]
|
||||
extern crate profile;
|
||||
|
||||
|
@ -50,7 +50,6 @@ extern crate gfx;
|
|||
extern crate layout_traits;
|
||||
extern crate libc;
|
||||
extern crate msg;
|
||||
extern crate net;
|
||||
extern crate png;
|
||||
extern crate script;
|
||||
extern crate script_traits;
|
||||
|
|
|
@ -16,8 +16,8 @@ path = "../script_traits"
|
|||
[dependencies.msg]
|
||||
path = "../msg"
|
||||
|
||||
[dependencies.net]
|
||||
path = "../net"
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.profile]
|
||||
path = "../profile"
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
extern crate gfx;
|
||||
extern crate script_traits;
|
||||
extern crate msg;
|
||||
extern crate net;
|
||||
extern crate profile;
|
||||
extern crate net_traits;
|
||||
extern crate url;
|
||||
extern crate util;
|
||||
|
||||
|
@ -18,13 +18,13 @@ extern crate util;
|
|||
use gfx::font_cache_task::FontCacheTask;
|
||||
use gfx::paint_task::PaintChan;
|
||||
use msg::constellation_msg::{ConstellationChan, Failure, PipelineId, PipelineExitType};
|
||||
use net::image_cache_task::ImageCacheTask;
|
||||
use net::resource_task::ResourceTask;
|
||||
use profile::mem;
|
||||
use profile::time;
|
||||
use net_traits::ResourceTask;
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use url::Url;
|
||||
use script_traits::{ScriptControlChan, OpaqueScriptLayoutChannel};
|
||||
use std::sync::mpsc::{Sender, Receiver};
|
||||
use url::Url;
|
||||
|
||||
/// Messages sent to the layout task from the constellation
|
||||
pub enum LayoutControlMsg {
|
||||
|
|
|
@ -10,6 +10,9 @@ path = "lib.rs"
|
|||
[dependencies.profile]
|
||||
path = "../profile"
|
||||
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.util]
|
||||
path = "../util"
|
||||
|
||||
|
@ -19,9 +22,6 @@ git = "https://github.com/servo/rust-geom"
|
|||
[dependencies.png]
|
||||
git = "https://github.com/servo/rust-png"
|
||||
|
||||
[dependencies.stb_image]
|
||||
git = "https://github.com/servo/rust-stb-image"
|
||||
|
||||
[dependencies]
|
||||
url = "0.2.16"
|
||||
time = "0.1.17"
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
* 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 resource_task::{TargetedLoadResponse, Metadata, LoadData, start_sending, ResponseSenders};
|
||||
use resource_task::ProgressMsg::Done;
|
||||
use net_traits::{LoadData, Metadata};
|
||||
use net_traits::ProgressMsg::Done;
|
||||
use resource_task::{TargetedLoadResponse, start_sending, ResponseSenders};
|
||||
use file_loader;
|
||||
|
||||
use url::Url;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//! Implementation of cookie creation and matching as specified by
|
||||
//! http://tools.ietf.org/html/rfc6265
|
||||
|
||||
use cookie_storage::CookieSource;
|
||||
use net_traits::CookieSource;
|
||||
use pub_domains::PUB_DOMAINS;
|
||||
|
||||
use cookie_rs;
|
||||
|
@ -196,7 +196,7 @@ fn test_default_path() {
|
|||
|
||||
#[test]
|
||||
fn fn_cookie_constructor() {
|
||||
use cookie_storage::CookieSource;
|
||||
use net_traits::CookieSource;
|
||||
|
||||
let url = &Url::parse("http://example.com/foo").unwrap();
|
||||
|
||||
|
|
|
@ -5,19 +5,11 @@
|
|||
//! Implementation of cookie storage as specified in
|
||||
//! http://tools.ietf.org/html/rfc6265
|
||||
|
||||
use net_traits::CookieSource;
|
||||
use url::Url;
|
||||
use cookie::Cookie;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
/// The creator of a given cookie
|
||||
#[derive(PartialEq, Copy)]
|
||||
pub enum CookieSource {
|
||||
/// An HTTP API
|
||||
HTTP,
|
||||
/// A non-HTTP API
|
||||
NonHTTP,
|
||||
}
|
||||
|
||||
pub struct CookieStorage {
|
||||
cookies: Vec<Cookie>
|
||||
}
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
* 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 resource_task::{Metadata, LoadData, TargetedLoadResponse, start_sending, ResponseSenders};
|
||||
use resource_task::ProgressMsg::{Payload, Done};
|
||||
use net_traits::{LoadData, Metadata};
|
||||
use net_traits::ProgressMsg::{Payload, Done};
|
||||
use resource_task::{TargetedLoadResponse, start_sending, ResponseSenders};
|
||||
|
||||
use rustc_serialize::base64::FromBase64;
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
* 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 resource_task::{ProgressMsg, Metadata, LoadData, start_sending, TargetedLoadResponse, ResponseSenders};
|
||||
use resource_task::ProgressMsg::{Payload, Done};
|
||||
use net_traits::{LoadData, Metadata, ProgressMsg};
|
||||
use net_traits::ProgressMsg::{Payload, Done};
|
||||
use resource_task::{start_sending, TargetedLoadResponse, ResponseSenders};
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::io;
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
* 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 cookie_storage::CookieSource;
|
||||
use resource_task::{Metadata, TargetedLoadResponse, LoadData, start_sending_opt, ResponseSenders, ProgressMsg};
|
||||
use resource_task::ControlMsg;
|
||||
use resource_task::ProgressMsg::{Payload, Done};
|
||||
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata};
|
||||
use net_traits::ProgressMsg;
|
||||
use net_traits::ProgressMsg::{Payload, Done};
|
||||
use resource_task::{TargetedLoadResponse, start_sending_opt, ResponseSenders};
|
||||
|
||||
use log;
|
||||
use std::collections::HashSet;
|
||||
|
@ -38,7 +38,7 @@ pub fn factory(cookies_chan: Sender<ControlMsg>)
|
|||
}
|
||||
|
||||
fn send_error(url: Url, err: String, senders: ResponseSenders) {
|
||||
let mut metadata = Metadata::default(url);
|
||||
let mut metadata: Metadata = Metadata::default(url);
|
||||
metadata.status = None;
|
||||
|
||||
match start_sending_opt(senders, metadata) {
|
||||
|
@ -283,7 +283,7 @@ reason: \"certificate verify failed\" }]";
|
|||
if viewing_source {
|
||||
adjusted_headers.set(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![])));
|
||||
}
|
||||
let mut metadata = Metadata::default(url);
|
||||
let mut metadata: Metadata = Metadata::default(url);
|
||||
metadata.set_content_type(match adjusted_headers.get() {
|
||||
Some(&ContentType(ref mime)) => Some(mime),
|
||||
None => None
|
||||
|
|
|
@ -2,82 +2,36 @@
|
|||
* 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 image::base::{Image, load_from_memory};
|
||||
use resource_task;
|
||||
use resource_task::{LoadData, ResourceTask};
|
||||
use resource_task::ProgressMsg::{Payload, Done};
|
||||
|
||||
use net_traits::ResourceTask;
|
||||
use net_traits::image::base::{Image, load_from_memory};
|
||||
use net_traits::image_cache_task::{ImageResponseMsg, ImageCacheTask, Msg};
|
||||
use net_traits::image_cache_task::{load_image_data};
|
||||
use profile::time::{self, profile};
|
||||
use url::Url;
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::mem::replace;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use url::Url;
|
||||
use util::resource_files::resources_dir_path;
|
||||
use util::task::spawn_named;
|
||||
use util::taskpool::TaskPool;
|
||||
|
||||
pub enum Msg {
|
||||
/// Tell the cache that we may need a particular image soon. Must be posted
|
||||
/// before Decode
|
||||
Prefetch(Url),
|
||||
|
||||
/// Tell the cache to decode an image. Must be posted before GetImage/WaitForImage
|
||||
Decode(Url),
|
||||
|
||||
/// Request an Image object for a URL. If the image is not is not immediately
|
||||
/// available then ImageNotReady is returned.
|
||||
GetImage(Url, Sender<ImageResponseMsg>),
|
||||
|
||||
/// Wait for an image to become available (or fail to load).
|
||||
WaitForImage(Url, Sender<ImageResponseMsg>),
|
||||
|
||||
/// Clients must wait for a response before shutting down the ResourceTask
|
||||
Exit(Sender<()>),
|
||||
|
||||
/// Used by the prefetch tasks to post back image binaries
|
||||
StorePrefetchedImageData(Url, Result<Vec<u8>, ()>),
|
||||
|
||||
/// Used by the decoder tasks to post decoded images back to the cache
|
||||
StoreImage(Url, Option<Arc<Box<Image>>>),
|
||||
|
||||
/// For testing
|
||||
WaitForStore(Sender<()>),
|
||||
|
||||
/// For testing
|
||||
WaitForStorePrefetched(Sender<()>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum ImageResponseMsg {
|
||||
ImageReady(Arc<Box<Image>>),
|
||||
ImageNotReady,
|
||||
ImageFailed
|
||||
}
|
||||
|
||||
impl PartialEq for ImageResponseMsg {
|
||||
fn eq(&self, other: &ImageResponseMsg) -> bool {
|
||||
match (self, other) {
|
||||
(&ImageResponseMsg::ImageReady(..), &ImageResponseMsg::ImageReady(..)) => panic!("unimplemented comparison"),
|
||||
(&ImageResponseMsg::ImageNotReady, &ImageResponseMsg::ImageNotReady) => true,
|
||||
(&ImageResponseMsg::ImageFailed, &ImageResponseMsg::ImageFailed) => true,
|
||||
|
||||
(&ImageResponseMsg::ImageReady(..), _) | (&ImageResponseMsg::ImageNotReady, _) | (&ImageResponseMsg::ImageFailed, _) => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ImageCacheTask {
|
||||
chan: Sender<Msg>,
|
||||
}
|
||||
|
||||
impl ImageCacheTask {
|
||||
pub fn new(resource_task: ResourceTask, task_pool: TaskPool,
|
||||
pub trait ImageCacheTaskFactory {
|
||||
fn new(resource_task: ResourceTask, task_pool: TaskPool,
|
||||
time_profiler_chan: time::ProfilerChan,
|
||||
load_placeholder: LoadPlaceholder) -> ImageCacheTask {
|
||||
load_placeholder: LoadPlaceholder) -> Self;
|
||||
fn new_sync(resource_task: ResourceTask, task_pool: TaskPool,
|
||||
time_profiler_chan: time::ProfilerChan,
|
||||
load_placeholder: LoadPlaceholder) -> Self;
|
||||
}
|
||||
|
||||
impl ImageCacheTaskFactory for ImageCacheTask {
|
||||
fn new(resource_task: ResourceTask, task_pool: TaskPool,
|
||||
time_profiler_chan: time::ProfilerChan,
|
||||
load_placeholder: LoadPlaceholder) -> ImageCacheTask {
|
||||
let (chan, port) = channel();
|
||||
let chan_clone = chan.clone();
|
||||
|
||||
|
@ -101,14 +55,14 @@ impl ImageCacheTask {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_sync(resource_task: ResourceTask, task_pool: TaskPool,
|
||||
time_profiler_chan: time::ProfilerChan,
|
||||
load_placeholder: LoadPlaceholder) -> ImageCacheTask {
|
||||
fn new_sync(resource_task: ResourceTask, task_pool: TaskPool,
|
||||
time_profiler_chan: time::ProfilerChan,
|
||||
load_placeholder: LoadPlaceholder) -> ImageCacheTask {
|
||||
let (chan, port) = channel();
|
||||
|
||||
spawn_named("ImageCacheTask (sync)".to_owned(), move || {
|
||||
let inner_cache = ImageCacheTask::new(resource_task, task_pool,
|
||||
time_profiler_chan, load_placeholder);
|
||||
let inner_cache: ImageCacheTask = ImageCacheTaskFactory::new(resource_task, task_pool,
|
||||
time_profiler_chan, load_placeholder);
|
||||
|
||||
loop {
|
||||
let msg: Msg = port.recv().unwrap();
|
||||
|
@ -387,7 +341,6 @@ impl ImageCache {
|
|||
panic!("incorrect state in store_image")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn purge_waiters<F>(&mut self, url: Url, f: F) where F: Fn() -> ImageResponseMsg {
|
||||
|
@ -440,10 +393,8 @@ impl ImageCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub trait ImageCacheTaskClient {
|
||||
fn exit(&self);
|
||||
}
|
||||
|
@ -456,61 +407,6 @@ impl ImageCacheTaskClient for ImageCacheTask {
|
|||
}
|
||||
}
|
||||
|
||||
impl ImageCacheTask {
|
||||
pub fn send(&self, msg: Msg) {
|
||||
self.chan.send(msg).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn wait_for_store(&self) -> Receiver<()> {
|
||||
let (chan, port) = channel();
|
||||
self.send(Msg::WaitForStore(chan));
|
||||
port
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn wait_for_store_prefetched(&self) -> Receiver<()> {
|
||||
let (chan, port) = channel();
|
||||
self.send(Msg::WaitForStorePrefetched(chan));
|
||||
port
|
||||
}
|
||||
}
|
||||
|
||||
fn load_image_data(url: Url, resource_task: ResourceTask, placeholder: &[u8]) -> Result<Vec<u8>, ()> {
|
||||
let (response_chan, response_port) = channel();
|
||||
resource_task.send(resource_task::ControlMsg::Load(LoadData::new(url.clone(), response_chan))).unwrap();
|
||||
|
||||
let mut image_data = vec!();
|
||||
|
||||
let progress_port = response_port.recv().unwrap().progress_port;
|
||||
loop {
|
||||
match progress_port.recv().unwrap() {
|
||||
Payload(data) => {
|
||||
image_data.push_all(&data);
|
||||
}
|
||||
Done(Ok(..)) => {
|
||||
return Ok(image_data);
|
||||
}
|
||||
Done(Err(..)) => {
|
||||
// Failure to load the requested image will return the
|
||||
// placeholder instead. In case it failed to load at init(),
|
||||
// we still recover and return Err() but nothing will be drawn.
|
||||
if placeholder.len() != 0 {
|
||||
debug!("image_cache_task: failed to load {:?}, use placeholder instead.", url);
|
||||
// Clean in case there was an error after started loading the image.
|
||||
image_data.clear();
|
||||
image_data.push_all(&placeholder);
|
||||
return Ok(image_data);
|
||||
} else {
|
||||
debug!("image_cache_task: invalid placeholder.");
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn spawn_listener<F, A>(f: F) -> Sender<A>
|
||||
where F: FnOnce(Receiver<A>) + Send + 'static,
|
||||
A: Send + 'static
|
||||
|
@ -529,21 +425,46 @@ pub fn spawn_listener<F, A>(f: F) -> Sender<A>
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::ImageResponseMsg::*;
|
||||
use super::Msg::*;
|
||||
use net_traits::image_cache_task::ImageResponseMsg::*;
|
||||
use net_traits::image_cache_task::Msg::*;
|
||||
|
||||
use resource_task;
|
||||
use resource_task::{ResourceTask, Metadata, start_sending, ResponseSenders};
|
||||
use resource_task::ProgressMsg::{Payload, Done};
|
||||
use resource_task::{start_sending, ResponseSenders};
|
||||
use net_traits::{ControlMsg, Metadata, ProgressMsg, ResourceTask};
|
||||
use net_traits::image_cache_task::{ImageCacheTask, ImageResponseMsg, Msg};
|
||||
use net_traits::ProgressMsg::{Payload, Done};
|
||||
use sniffer_task;
|
||||
use image::base::test_image_bin;
|
||||
use profile::time;
|
||||
use std::sync::mpsc::{Sender, channel, Receiver};
|
||||
use url::Url;
|
||||
use util::taskpool::TaskPool;
|
||||
|
||||
static TEST_IMAGE: &'static [u8] = include_bytes!("test.jpeg");
|
||||
|
||||
pub fn test_image_bin() -> Vec<u8> {
|
||||
TEST_IMAGE.iter().map(|&x| x).collect()
|
||||
}
|
||||
|
||||
trait ImageCacheTaskHelper {
|
||||
fn wait_for_store(&self) -> Receiver<()>;
|
||||
fn wait_for_store_prefetched(&self) -> Receiver<()>;
|
||||
}
|
||||
|
||||
impl ImageCacheTaskHelper for ImageCacheTask {
|
||||
fn wait_for_store(&self) -> Receiver<()> {
|
||||
let (chan, port) = channel();
|
||||
self.send(Msg::WaitForStore(chan));
|
||||
port
|
||||
}
|
||||
|
||||
fn wait_for_store_prefetched(&self) -> Receiver<()> {
|
||||
let (chan, port) = channel();
|
||||
self.send(Msg::WaitForStorePrefetched(chan));
|
||||
port
|
||||
}
|
||||
}
|
||||
|
||||
trait Closure {
|
||||
fn invoke(&self, _response: Sender<resource_task::ProgressMsg>) { }
|
||||
fn invoke(&self, _response: Sender<ProgressMsg>) { }
|
||||
}
|
||||
struct DoesNothing;
|
||||
impl Closure for DoesNothing { }
|
||||
|
@ -552,7 +473,7 @@ mod tests {
|
|||
url_requested_chan: Sender<()>,
|
||||
}
|
||||
impl Closure for JustSendOK {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
||||
self.url_requested_chan.send(());
|
||||
response.send(Done(Ok(())));
|
||||
}
|
||||
|
@ -560,7 +481,7 @@ mod tests {
|
|||
|
||||
struct SendTestImage;
|
||||
impl Closure for SendTestImage {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
||||
response.send(Payload(test_image_bin()));
|
||||
response.send(Done(Ok(())));
|
||||
}
|
||||
|
@ -568,7 +489,7 @@ mod tests {
|
|||
|
||||
struct SendBogusImage;
|
||||
impl Closure for SendBogusImage {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
||||
response.send(Payload(vec!()));
|
||||
response.send(Done(Ok(())));
|
||||
}
|
||||
|
@ -576,7 +497,7 @@ mod tests {
|
|||
|
||||
struct SendTestImageErr;
|
||||
impl Closure for SendTestImageErr {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
||||
response.send(Payload(test_image_bin()));
|
||||
response.send(Done(Err("".to_string())));
|
||||
}
|
||||
|
@ -586,7 +507,7 @@ mod tests {
|
|||
wait_port: Receiver<()>,
|
||||
}
|
||||
impl Closure for WaitSendTestImage {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
||||
// Don't send the data until after the client requests
|
||||
// the image
|
||||
self.wait_port.recv().unwrap();
|
||||
|
@ -599,7 +520,7 @@ mod tests {
|
|||
wait_port: Receiver<()>,
|
||||
}
|
||||
impl Closure for WaitSendTestImageErr {
|
||||
fn invoke(&self, response: Sender<resource_task::ProgressMsg>) {
|
||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
||||
// Don't send the data until after the client requests
|
||||
// the image
|
||||
self.wait_port.recv().unwrap();
|
||||
|
@ -609,10 +530,10 @@ mod tests {
|
|||
}
|
||||
|
||||
fn mock_resource_task<T: Closure + Send + 'static>(on_load: Box<T>) -> ResourceTask {
|
||||
spawn_listener(move |port: Receiver<resource_task::ControlMsg>| {
|
||||
spawn_listener(move |port: Receiver<ControlMsg>| {
|
||||
loop {
|
||||
match port.recv().unwrap() {
|
||||
resource_task::ControlMsg::Load(response) => {
|
||||
ControlMsg::Load(response) => {
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
let senders = ResponseSenders {
|
||||
immediate_consumer: sniffer_task,
|
||||
|
@ -622,7 +543,7 @@ mod tests {
|
|||
Url::parse("file:///fake").unwrap()));
|
||||
on_load.invoke(chan);
|
||||
}
|
||||
resource_task::ControlMsg::Exit => break,
|
||||
ControlMsg::Exit => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -637,10 +558,12 @@ mod tests {
|
|||
fn should_exit_on_request() {
|
||||
let mock_resource_task = mock_resource_task(box DoesNothing);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Ignore);
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -648,7 +571,9 @@ mod tests {
|
|||
fn should_panic_if_unprefetched_image_is_requested() {
|
||||
let mock_resource_task = mock_resource_task(box DoesNothing);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
let (chan, port) = channel();
|
||||
|
@ -662,13 +587,15 @@ mod tests {
|
|||
|
||||
let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan});
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url));
|
||||
url_requested.recv().unwrap();
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -677,14 +604,16 @@ mod tests {
|
|||
|
||||
let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan});
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Ignore);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
image_cache_task.send(Prefetch(url));
|
||||
url_requested.recv().unwrap();
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
match url_requested.try_recv() {
|
||||
Err(_) => (),
|
||||
Ok(_) => panic!(),
|
||||
|
@ -697,7 +626,9 @@ mod tests {
|
|||
|
||||
let mock_resource_task = mock_resource_task(box WaitSendTestImage{wait_port: wait_port});
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Ignore);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
@ -707,14 +638,16 @@ mod tests {
|
|||
assert!(response_port.recv().unwrap() == ImageResponseMsg::ImageNotReady);
|
||||
wait_chan.send(());
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_decoded_image_data_if_data_has_arrived() {
|
||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
let join_port = image_cache_task.wait_for_store();
|
||||
|
@ -733,14 +666,16 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_decoded_image_data_for_multiple_requests() {
|
||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
let join_port = image_cache_task.wait_for_store();
|
||||
|
@ -761,7 +696,7 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -770,10 +705,10 @@ mod tests {
|
|||
|
||||
let (resource_task_exited_chan, resource_task_exited) = channel();
|
||||
|
||||
let mock_resource_task = spawn_listener(move |port: Receiver<resource_task::ControlMsg>| {
|
||||
let mock_resource_task = spawn_listener(move |port: Receiver<ControlMsg>| {
|
||||
loop {
|
||||
match port.recv().unwrap() {
|
||||
resource_task::ControlMsg::Load(response) => {
|
||||
ControlMsg::Load(response) => {
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
let senders = ResponseSenders {
|
||||
immediate_consumer: sniffer_task,
|
||||
|
@ -785,7 +720,7 @@ mod tests {
|
|||
chan.send(Done(Ok(())));
|
||||
image_bin_sent_chan.send(());
|
||||
}
|
||||
resource_task::ControlMsg::Exit => {
|
||||
ControlMsg::Exit => {
|
||||
resource_task_exited_chan.send(());
|
||||
break
|
||||
}
|
||||
|
@ -794,7 +729,9 @@ mod tests {
|
|||
}
|
||||
});
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Ignore);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
@ -805,7 +742,7 @@ mod tests {
|
|||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
|
||||
resource_task_exited.recv().unwrap();
|
||||
|
||||
|
@ -822,10 +759,10 @@ mod tests {
|
|||
let (image_bin_sent_chan, image_bin_sent) = channel();
|
||||
|
||||
let (resource_task_exited_chan, resource_task_exited) = channel();
|
||||
let mock_resource_task = spawn_listener(move |port: Receiver<resource_task::ControlMsg>| {
|
||||
let mock_resource_task = spawn_listener(move |port: Receiver<ControlMsg>| {
|
||||
loop {
|
||||
match port.recv().unwrap() {
|
||||
resource_task::ControlMsg::Load(response) => {
|
||||
ControlMsg::Load(response) => {
|
||||
let sniffer_task = sniffer_task::new_sniffer_task();
|
||||
let senders = ResponseSenders {
|
||||
immediate_consumer: sniffer_task,
|
||||
|
@ -837,7 +774,7 @@ mod tests {
|
|||
chan.send(Done(Err("".to_string())));
|
||||
image_bin_sent_chan.send(());
|
||||
}
|
||||
resource_task::ControlMsg::Exit => {
|
||||
ControlMsg::Exit => {
|
||||
resource_task_exited_chan.send(());
|
||||
break
|
||||
}
|
||||
|
@ -846,7 +783,9 @@ mod tests {
|
|||
}
|
||||
});
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Ignore);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
@ -859,7 +798,7 @@ mod tests {
|
|||
image_cache_task.send(Decode(url.clone()));
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
|
||||
resource_task_exited.recv().unwrap();
|
||||
|
||||
|
@ -875,7 +814,9 @@ mod tests {
|
|||
fn should_return_failed_if_image_bin_cannot_be_fetched() {
|
||||
let mock_resource_task = mock_resource_task(box SendTestImageErr);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
let join_port = image_cache_task.wait_for_store_prefetched();
|
||||
|
@ -894,14 +835,16 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_failed_for_multiple_get_image_requests_if_image_bin_cannot_be_fetched() {
|
||||
let mock_resource_task = mock_resource_task(box SendTestImageErr);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
let join_port = image_cache_task.wait_for_store_prefetched();
|
||||
|
@ -928,14 +871,16 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_failed_if_image_decode_fails() {
|
||||
let mock_resource_task = mock_resource_task(box SendBogusImage);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
let join_port = image_cache_task.wait_for_store();
|
||||
|
@ -956,14 +901,16 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_return_image_on_wait_if_image_is_already_loaded() {
|
||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
let join_port = image_cache_task.wait_for_store();
|
||||
|
@ -982,7 +929,7 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -991,7 +938,9 @@ mod tests {
|
|||
|
||||
let mock_resource_task = mock_resource_task(box WaitSendTestImage {wait_port: wait_port});
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Ignore);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
@ -1008,7 +957,7 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1017,7 +966,9 @@ mod tests {
|
|||
|
||||
let mock_resource_task = mock_resource_task(box WaitSendTestImageErr{wait_port: wait_port});
|
||||
|
||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Ignore);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Ignore);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
@ -1034,14 +985,16 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_cache_should_wait_for_images() {
|
||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||
|
||||
let image_cache_task = ImageCacheTask::new_sync(mock_resource_task.clone(), TaskPool::new(4), profiler(), LoadPlaceholder::Preload);
|
||||
let image_cache_task: ImageCacheTask = ImageCacheTaskFactory::new_sync(mock_resource_task.clone(),
|
||||
TaskPool::new(4), profiler(),
|
||||
LoadPlaceholder::Preload);
|
||||
let url = Url::parse("file:///").unwrap();
|
||||
|
||||
image_cache_task.send(Prefetch(url.clone()));
|
||||
|
@ -1055,6 +1008,6 @@ mod tests {
|
|||
}
|
||||
|
||||
image_cache_task.exit();
|
||||
mock_resource_task.send(resource_task::ControlMsg::Exit);
|
||||
mock_resource_task.send(ControlMsg::Exit);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#![plugin(regex_macros)]
|
||||
|
||||
extern crate net_traits;
|
||||
extern crate "cookie" as cookie_rs;
|
||||
extern crate collections;
|
||||
extern crate flate2;
|
||||
|
@ -30,22 +31,11 @@ extern crate openssl;
|
|||
extern crate profile;
|
||||
extern crate "rustc-serialize" as rustc_serialize;
|
||||
extern crate util;
|
||||
extern crate stb_image;
|
||||
extern crate time;
|
||||
extern crate url;
|
||||
|
||||
extern crate regex;
|
||||
|
||||
/// Image handling.
|
||||
///
|
||||
/// It may be surprising that this goes in the network crate as opposed to the graphics crate.
|
||||
/// However, image handling is generally very integrated with the network stack (especially where
|
||||
/// caching is involved) and as a result it must live in here.
|
||||
pub mod image {
|
||||
pub mod base;
|
||||
pub mod holder;
|
||||
}
|
||||
|
||||
pub mod about_loader;
|
||||
pub mod file_loader;
|
||||
pub mod http_loader;
|
||||
|
@ -53,7 +43,6 @@ pub mod data_loader;
|
|||
pub mod cookie;
|
||||
pub mod cookie_storage;
|
||||
pub mod image_cache_task;
|
||||
pub mod local_image_cache;
|
||||
pub mod pub_domains;
|
||||
pub mod resource_task;
|
||||
pub mod storage_task;
|
||||
|
|
|
@ -10,19 +10,20 @@ use file_loader;
|
|||
use http_loader;
|
||||
use sniffer_task;
|
||||
use sniffer_task::SnifferTask;
|
||||
use cookie_storage::{CookieStorage, CookieSource};
|
||||
use cookie_storage::CookieStorage;
|
||||
use cookie;
|
||||
|
||||
use net_traits::{ControlMsg, LoadData, LoadResponse};
|
||||
use net_traits::{Metadata, ProgressMsg, ResourceTask};
|
||||
use net_traits::ProgressMsg::Done;
|
||||
use util::task::spawn_named;
|
||||
|
||||
use hyper::header::UserAgent;
|
||||
use hyper::header::{Headers, Header, SetCookie};
|
||||
use hyper::http::RawStatus;
|
||||
use hyper::method::Method;
|
||||
use hyper::mime::{Mime, Attr};
|
||||
use hyper::header::{Header, SetCookie};
|
||||
#[cfg(test)]
|
||||
use url::Url;
|
||||
|
||||
use std::borrow::{ToOwned, IntoCow};
|
||||
use std::borrow::ToOwned;
|
||||
use std::boxed;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
@ -57,110 +58,6 @@ pub fn global_init() {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum ControlMsg {
|
||||
/// Request the data associated with a particular URL
|
||||
Load(LoadData),
|
||||
/// Store a set of cookies for a given originating URL
|
||||
SetCookiesForUrl(Url, String, CookieSource),
|
||||
/// Retrieve the stored cookies for a given URL
|
||||
GetCookiesForUrl(Url, Sender<Option<String>>, CookieSource),
|
||||
Exit
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LoadData {
|
||||
pub url: Url,
|
||||
pub method: Method,
|
||||
/// Headers that will apply to the initial request only
|
||||
pub headers: Headers,
|
||||
/// Headers that will apply to the initial request and any redirects
|
||||
pub preserved_headers: Headers,
|
||||
pub data: Option<Vec<u8>>,
|
||||
pub cors: Option<ResourceCORSData>,
|
||||
pub consumer: Sender<LoadResponse>,
|
||||
}
|
||||
|
||||
impl LoadData {
|
||||
pub fn new(url: Url, consumer: Sender<LoadResponse>) -> LoadData {
|
||||
LoadData {
|
||||
url: url,
|
||||
method: Method::Get,
|
||||
headers: Headers::new(),
|
||||
preserved_headers: Headers::new(),
|
||||
data: None,
|
||||
cors: None,
|
||||
consumer: consumer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ResourceCORSData {
|
||||
/// CORS Preflight flag
|
||||
pub preflight: bool,
|
||||
/// Origin of CORS Request
|
||||
pub origin: Url
|
||||
}
|
||||
|
||||
/// Metadata about a loaded resource, such as is obtained from HTTP headers.
|
||||
#[derive(Clone)]
|
||||
pub struct Metadata {
|
||||
/// Final URL after redirects.
|
||||
pub final_url: Url,
|
||||
|
||||
/// MIME type / subtype.
|
||||
pub content_type: Option<(String, String)>,
|
||||
|
||||
/// Character set.
|
||||
pub charset: Option<String>,
|
||||
|
||||
/// Headers
|
||||
pub headers: Option<Headers>,
|
||||
|
||||
/// HTTP Status
|
||||
pub status: Option<RawStatus>,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
/// Metadata with defaults for everything optional.
|
||||
pub fn default(url: Url) -> Metadata {
|
||||
Metadata {
|
||||
final_url: url,
|
||||
content_type: None,
|
||||
charset: None,
|
||||
headers: None,
|
||||
// http://fetch.spec.whatwg.org/#concept-response-status-message
|
||||
status: Some(RawStatus(200, "OK".into_cow())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract the parts of a Mime that we care about.
|
||||
pub fn set_content_type(&mut self, content_type: Option<&Mime>) {
|
||||
match content_type {
|
||||
None => (),
|
||||
Some(&Mime(ref type_, ref subtype, ref parameters)) => {
|
||||
self.content_type = Some((type_.to_string(), subtype.to_string()));
|
||||
for &(ref k, ref v) in parameters.iter() {
|
||||
if &Attr::Charset == k {
|
||||
self.charset = Some(v.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Message sent in response to `Load`. Contains metadata, and a port
|
||||
/// for receiving the data.
|
||||
///
|
||||
/// Even if loading fails immediately, we send one of these and the
|
||||
/// progress_port will provide the error.
|
||||
pub struct LoadResponse {
|
||||
/// Metadata, such as from HTTP headers.
|
||||
pub metadata: Metadata,
|
||||
/// Port for reading data.
|
||||
pub progress_port: Receiver<ProgressMsg>,
|
||||
}
|
||||
/// A LoadResponse directed at a particular consumer
|
||||
pub struct TargetedLoadResponse {
|
||||
pub load_response: LoadResponse,
|
||||
|
@ -173,15 +70,6 @@ pub struct ResponseSenders {
|
|||
pub eventual_consumer: Sender<LoadResponse>,
|
||||
}
|
||||
|
||||
/// Messages sent in response to a `Load` message
|
||||
#[derive(PartialEq,Debug)]
|
||||
pub enum ProgressMsg {
|
||||
/// Binary data - there may be multiple of these
|
||||
Payload(Vec<u8>),
|
||||
/// Indicates loading is complete, either successfully or not
|
||||
Done(Result<(), String>)
|
||||
}
|
||||
|
||||
/// For use by loaders in responding to a Load message.
|
||||
pub fn start_sending(senders: ResponseSenders, metadata: Metadata) -> Sender<ProgressMsg> {
|
||||
start_sending_opt(senders, metadata).ok().unwrap()
|
||||
|
@ -203,26 +91,6 @@ pub fn start_sending_opt(senders: ResponseSenders, metadata: Metadata) -> Result
|
|||
}
|
||||
}
|
||||
|
||||
/// Convenience function for synchronously loading a whole resource.
|
||||
pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||
-> Result<(Metadata, Vec<u8>), String> {
|
||||
let (start_chan, start_port) = channel();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan))).unwrap();
|
||||
let response = start_port.recv().unwrap();
|
||||
|
||||
let mut buf = vec!();
|
||||
loop {
|
||||
match response.progress_port.recv().unwrap() {
|
||||
ProgressMsg::Payload(data) => buf.push_all(&data),
|
||||
ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)),
|
||||
ProgressMsg::Done(Err(e)) => return Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle to a resource task
|
||||
pub type ResourceTask = Sender<ControlMsg>;
|
||||
|
||||
/// Create a ResourceTask
|
||||
pub fn new_resource_task(user_agent: Option<String>) -> ResourceTask {
|
||||
let (setup_chan, setup_port) = channel();
|
||||
|
@ -355,36 +223,6 @@ impl ResourceManager {
|
|||
}
|
||||
}
|
||||
|
||||
/// Load a URL asynchronously and iterate over chunks of bytes from the response.
|
||||
pub fn load_bytes_iter(resource_task: &ResourceTask, url: Url) -> (Metadata, ProgressMsgPortIterator) {
|
||||
let (input_chan, input_port) = channel();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url, input_chan))).unwrap();
|
||||
|
||||
let response = input_port.recv().unwrap();
|
||||
let iter = ProgressMsgPortIterator { progress_port: response.progress_port };
|
||||
(response.metadata, iter)
|
||||
}
|
||||
|
||||
/// Iterator that reads chunks of bytes from a ProgressMsg port
|
||||
pub struct ProgressMsgPortIterator {
|
||||
progress_port: Receiver<ProgressMsg>
|
||||
}
|
||||
|
||||
impl Iterator for ProgressMsgPortIterator {
|
||||
type Item = Vec<u8>;
|
||||
|
||||
fn next(&mut self) -> Option<Vec<u8>> {
|
||||
match self.progress_port.recv().unwrap() {
|
||||
ProgressMsg::Payload(data) => Some(data),
|
||||
ProgressMsg::Done(Ok(())) => None,
|
||||
ProgressMsg::Done(Err(e)) => {
|
||||
error!("error receiving bytes: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exit() {
|
||||
let resource_task = new_resource_task(None);
|
||||
|
|
|
@ -3,48 +3,15 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use url::Url;
|
||||
|
||||
use net_traits::storage_task::{StorageTask, StorageTaskMsg, StorageType};
|
||||
use util::str::DOMString;
|
||||
use util::task::spawn_named;
|
||||
|
||||
#[derive(Copy)]
|
||||
pub enum StorageType {
|
||||
Session,
|
||||
Local
|
||||
}
|
||||
|
||||
/// Request operations on the storage data associated with a particular url
|
||||
pub enum StorageTaskMsg {
|
||||
/// gets the number of key/value pairs present in the associated storage data
|
||||
Length(Sender<u32>, Url, StorageType),
|
||||
|
||||
/// gets the name of the key at the specified index in the associated storage data
|
||||
Key(Sender<Option<DOMString>>, Url, StorageType, u32),
|
||||
|
||||
/// gets the value associated with the given key in the associated storage data
|
||||
GetItem(Sender<Option<DOMString>>, Url, StorageType, DOMString),
|
||||
|
||||
/// sets the value of the given key in the associated storage data
|
||||
/// TODO throw QuotaExceededError in case of error
|
||||
SetItem(Sender<(bool, Option<DOMString>)>, Url, StorageType, DOMString, DOMString),
|
||||
|
||||
/// removes the key/value pair for the given key in the associated storage data
|
||||
RemoveItem(Sender<Option<DOMString>>, Url, StorageType, DOMString),
|
||||
|
||||
/// clears the associated storage data by removing all the key/value pairs
|
||||
Clear(Sender<bool>, Url, StorageType),
|
||||
|
||||
/// shut down this task
|
||||
Exit
|
||||
}
|
||||
|
||||
/// Handle to a storage task
|
||||
pub type StorageTask = Sender<StorageTaskMsg>;
|
||||
|
||||
pub trait StorageTaskFactory {
|
||||
fn new() -> Self;
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
27
components/net_traits/Cargo.toml
Normal file
27
components/net_traits/Cargo.toml
Normal file
|
@ -0,0 +1,27 @@
|
|||
[package]
|
||||
name = "net_traits"
|
||||
version = "0.0.1"
|
||||
authors = ["The Servo Project Developers"]
|
||||
|
||||
[lib]
|
||||
name = "net_traits"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.geom]
|
||||
git = "https://github.com/servo/rust-geom"
|
||||
|
||||
[dependencies.png]
|
||||
git = "https://github.com/servo/rust-png"
|
||||
|
||||
[dependencies.profile]
|
||||
path = "../profile"
|
||||
|
||||
[dependencies.util]
|
||||
path = "../util"
|
||||
|
||||
[dependencies.stb_image]
|
||||
git = "https://github.com/servo/rust-stb-image"
|
||||
|
||||
[dependencies]
|
||||
url = "0.2.16"
|
||||
hyper = "0.3"
|
|
@ -2,22 +2,15 @@
|
|||
* 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 std::iter::range_step;
|
||||
use stb_image::image as stb_image;
|
||||
use png;
|
||||
use stb_image::image as stb_image2;
|
||||
use std::iter::range_step;
|
||||
use util::vec::byte_swap;
|
||||
|
||||
// FIXME: Images must not be copied every frame. Instead we should atomically
|
||||
// reference count them.
|
||||
pub type Image = png::Image;
|
||||
|
||||
|
||||
static TEST_IMAGE: &'static [u8] = include_bytes!("test.jpeg");
|
||||
|
||||
pub fn test_image_bin() -> Vec<u8> {
|
||||
TEST_IMAGE.iter().map(|&x| x).collect()
|
||||
}
|
||||
|
||||
// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
|
||||
fn byte_swap_and_premultiply(data: &mut [u8]) {
|
||||
let length = data.len();
|
||||
|
@ -56,8 +49,8 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
|||
// Can't remember why we do this. Maybe it's what cairo wants
|
||||
static FORCE_DEPTH: uint = 4;
|
||||
|
||||
match stb_image::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
|
||||
stb_image::LoadResult::ImageU8(mut image) => {
|
||||
match stb_image2::load_from_memory_with_depth(buffer, FORCE_DEPTH, true) {
|
||||
stb_image2::LoadResult::ImageU8(mut image) => {
|
||||
assert!(image.depth == 4);
|
||||
// handle gif separately because the alpha-channel has to be premultiplied
|
||||
if is_gif(buffer) {
|
||||
|
@ -71,11 +64,11 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
|||
pixels: png::PixelsByColorType::RGBA8(image.data)
|
||||
})
|
||||
}
|
||||
stb_image::LoadResult::ImageF32(_image) => {
|
||||
stb_image2::LoadResult::ImageF32(_image) => {
|
||||
error!("HDR images not implemented");
|
||||
None
|
||||
}
|
||||
stb_image::LoadResult::Error(e) => {
|
||||
stb_image2::LoadResult::Error(e) => {
|
||||
error!("stb_image failed: {}", e);
|
||||
None
|
||||
}
|
||||
|
@ -89,3 +82,5 @@ fn is_gif(buffer: &[u8]) -> bool {
|
|||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
|
106
components/net_traits/image_cache_task.rs
Normal file
106
components/net_traits/image_cache_task.rs
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* 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/. */
|
||||
|
||||
use image::base::Image;
|
||||
use {ControlMsg, LoadData, ProgressMsg, ResourceTask};
|
||||
use url::Url;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
|
||||
pub enum Msg {
|
||||
/// Tell the cache that we may need a particular image soon. Must be posted
|
||||
/// before Decode
|
||||
Prefetch(Url),
|
||||
|
||||
/// Tell the cache to decode an image. Must be posted before GetImage/WaitForImage
|
||||
Decode(Url),
|
||||
|
||||
/// Request an Image object for a URL. If the image is not is not immediately
|
||||
/// available then ImageNotReady is returned.
|
||||
GetImage(Url, Sender<ImageResponseMsg>),
|
||||
|
||||
/// Wait for an image to become available (or fail to load).
|
||||
WaitForImage(Url, Sender<ImageResponseMsg>),
|
||||
|
||||
/// Clients must wait for a response before shutting down the ResourceTask
|
||||
Exit(Sender<()>),
|
||||
|
||||
/// Used by the prefetch tasks to post back image binaries
|
||||
StorePrefetchedImageData(Url, Result<Vec<u8>, ()>),
|
||||
|
||||
/// Used by the decoder tasks to post decoded images back to the cache
|
||||
StoreImage(Url, Option<Arc<Box<Image>>>),
|
||||
|
||||
/// For testing
|
||||
WaitForStore(Sender<()>),
|
||||
|
||||
/// For testing
|
||||
WaitForStorePrefetched(Sender<()>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum ImageResponseMsg {
|
||||
ImageReady(Arc<Box<Image>>),
|
||||
ImageNotReady,
|
||||
ImageFailed
|
||||
}
|
||||
|
||||
impl PartialEq for ImageResponseMsg {
|
||||
fn eq(&self, other: &ImageResponseMsg) -> bool {
|
||||
match (self, other) {
|
||||
(&ImageResponseMsg::ImageReady(..), &ImageResponseMsg::ImageReady(..)) => panic!("unimplemented comparison"),
|
||||
(&ImageResponseMsg::ImageNotReady, &ImageResponseMsg::ImageNotReady) => true,
|
||||
(&ImageResponseMsg::ImageFailed, &ImageResponseMsg::ImageFailed) => true,
|
||||
|
||||
(&ImageResponseMsg::ImageReady(..), _) | (&ImageResponseMsg::ImageNotReady, _) | (&ImageResponseMsg::ImageFailed, _) => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ImageCacheTask {
|
||||
pub chan: Sender<Msg>,
|
||||
}
|
||||
|
||||
impl ImageCacheTask {
|
||||
pub fn send(&self, msg: Msg) {
|
||||
self.chan.send(msg).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_image_data(url: Url, resource_task: ResourceTask, placeholder: &[u8]) -> Result<Vec<u8>, ()> {
|
||||
let (response_chan, response_port) = channel();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url.clone(), response_chan))).unwrap();
|
||||
|
||||
let mut image_data = vec!();
|
||||
|
||||
let progress_port = response_port.recv().unwrap().progress_port;
|
||||
loop {
|
||||
match progress_port.recv().unwrap() {
|
||||
ProgressMsg::Payload(data) => {
|
||||
image_data.push_all(&data);
|
||||
}
|
||||
ProgressMsg::Done(Ok(..)) => {
|
||||
return Ok(image_data);
|
||||
}
|
||||
ProgressMsg::Done(Err(..)) => {
|
||||
// Failure to load the requested image will return the
|
||||
// placeholder instead. In case it failed to load at init(),
|
||||
// we still recover and return Err() but nothing will be drawn.
|
||||
if placeholder.len() != 0 {
|
||||
debug!("image_cache_task: failed to load {:?}, use placeholder instead.", url);
|
||||
// Clean in case there was an error after started loading the image.
|
||||
image_data.clear();
|
||||
image_data.push_all(&placeholder);
|
||||
return Ok(image_data);
|
||||
} else {
|
||||
debug!("image_cache_task: invalid placeholder.");
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
218
components/net_traits/lib.rs
Normal file
218
components/net_traits/lib.rs
Normal file
|
@ -0,0 +1,218 @@
|
|||
/* 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/. */
|
||||
|
||||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(core)]
|
||||
#![feature(int_uint)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(std_misc)]
|
||||
|
||||
extern crate geom;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate png;
|
||||
extern crate profile;
|
||||
extern crate stb_image;
|
||||
extern crate url;
|
||||
extern crate util;
|
||||
|
||||
use hyper::header::Headers;
|
||||
use hyper::http::RawStatus;
|
||||
use hyper::method::Method;
|
||||
use hyper::mime::{Mime, Attr};
|
||||
use url::Url;
|
||||
|
||||
use std::borrow::IntoCow;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
|
||||
pub mod image_cache_task;
|
||||
pub mod local_image_cache;
|
||||
pub mod storage_task;
|
||||
|
||||
/// Image handling.
|
||||
///
|
||||
/// It may be surprising that this goes in the network crate as opposed to the graphics crate.
|
||||
/// However, image handling is generally very integrated with the network stack (especially where
|
||||
/// caching is involved) and as a result it must live in here.
|
||||
pub mod image {
|
||||
pub mod base;
|
||||
pub mod holder;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LoadData {
|
||||
pub url: Url,
|
||||
pub method: Method,
|
||||
/// Headers that will apply to the initial request only
|
||||
pub headers: Headers,
|
||||
/// Headers that will apply to the initial request and any redirects
|
||||
pub preserved_headers: Headers,
|
||||
pub data: Option<Vec<u8>>,
|
||||
pub cors: Option<ResourceCORSData>,
|
||||
pub consumer: Sender<LoadResponse>,
|
||||
}
|
||||
|
||||
impl LoadData {
|
||||
pub fn new(url: Url, consumer: Sender<LoadResponse>) -> LoadData {
|
||||
LoadData {
|
||||
url: url,
|
||||
method: Method::Get,
|
||||
headers: Headers::new(),
|
||||
preserved_headers: Headers::new(),
|
||||
data: None,
|
||||
cors: None,
|
||||
consumer: consumer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle to a resource task
|
||||
pub type ResourceTask = Sender<ControlMsg>;
|
||||
|
||||
pub enum ControlMsg {
|
||||
/// Request the data associated with a particular URL
|
||||
Load(LoadData),
|
||||
/// Store a set of cookies for a given originating URL
|
||||
SetCookiesForUrl(Url, String, CookieSource),
|
||||
/// Retrieve the stored cookies for a given URL
|
||||
GetCookiesForUrl(Url, Sender<Option<String>>, CookieSource),
|
||||
Exit
|
||||
}
|
||||
|
||||
/// Message sent in response to `Load`. Contains metadata, and a port
|
||||
/// for receiving the data.
|
||||
///
|
||||
/// Even if loading fails immediately, we send one of these and the
|
||||
/// progress_port will provide the error.
|
||||
pub struct LoadResponse {
|
||||
/// Metadata, such as from HTTP headers.
|
||||
pub metadata: Metadata,
|
||||
/// Port for reading data.
|
||||
pub progress_port: Receiver<ProgressMsg>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ResourceCORSData {
|
||||
/// CORS Preflight flag
|
||||
pub preflight: bool,
|
||||
/// Origin of CORS Request
|
||||
pub origin: Url
|
||||
}
|
||||
|
||||
/// Metadata about a loaded resource, such as is obtained from HTTP headers.
|
||||
#[derive(Clone)]
|
||||
pub struct Metadata {
|
||||
/// Final URL after redirects.
|
||||
pub final_url: Url,
|
||||
|
||||
/// MIME type / subtype.
|
||||
pub content_type: Option<(String, String)>,
|
||||
|
||||
/// Character set.
|
||||
pub charset: Option<String>,
|
||||
|
||||
/// Headers
|
||||
pub headers: Option<Headers>,
|
||||
|
||||
/// HTTP Status
|
||||
pub status: Option<RawStatus>,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
/// Metadata with defaults for everything optional.
|
||||
pub fn default(url: Url) -> Self {
|
||||
Metadata {
|
||||
final_url: url,
|
||||
content_type: None,
|
||||
charset: None,
|
||||
headers: None,
|
||||
// http://fetch.spec.whatwg.org/#concept-response-status-message
|
||||
status: Some(RawStatus(200, "OK".into_cow())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract the parts of a Mime that we care about.
|
||||
pub fn set_content_type(&mut self, content_type: Option<&Mime>) {
|
||||
match content_type {
|
||||
None => (),
|
||||
Some(&Mime(ref type_, ref subtype, ref parameters)) => {
|
||||
self.content_type = Some((type_.to_string(), subtype.to_string()));
|
||||
for &(ref k, ref v) in parameters.iter() {
|
||||
if &Attr::Charset == k {
|
||||
self.charset = Some(v.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The creator of a given cookie
|
||||
#[derive(PartialEq, Copy)]
|
||||
pub enum CookieSource {
|
||||
/// An HTTP API
|
||||
HTTP,
|
||||
/// A non-HTTP API
|
||||
NonHTTP,
|
||||
}
|
||||
|
||||
/// Messages sent in response to a `Load` message
|
||||
#[derive(PartialEq,Debug)]
|
||||
pub enum ProgressMsg {
|
||||
/// Binary data - there may be multiple of these
|
||||
Payload(Vec<u8>),
|
||||
/// Indicates loading is complete, either successfully or not
|
||||
Done(Result<(), String>)
|
||||
}
|
||||
|
||||
/// Convenience function for synchronously loading a whole resource.
|
||||
pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||
-> Result<(Metadata, Vec<u8>), String> {
|
||||
let (start_chan, start_port) = channel();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan))).unwrap();
|
||||
let response = start_port.recv().unwrap();
|
||||
|
||||
let mut buf = vec!();
|
||||
loop {
|
||||
match response.progress_port.recv().unwrap() {
|
||||
ProgressMsg::Payload(data) => buf.push_all(&data),
|
||||
ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)),
|
||||
ProgressMsg::Done(Err(e)) => return Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Load a URL asynchronously and iterate over chunks of bytes from the response.
|
||||
pub fn load_bytes_iter(resource_task: &ResourceTask, url: Url) -> (Metadata, ProgressMsgPortIterator) {
|
||||
let (input_chan, input_port) = channel();
|
||||
resource_task.send(ControlMsg::Load(LoadData::new(url, input_chan))).unwrap();
|
||||
|
||||
let response = input_port.recv().unwrap();
|
||||
let iter = ProgressMsgPortIterator { progress_port: response.progress_port };
|
||||
(response.metadata, iter)
|
||||
}
|
||||
|
||||
/// Iterator that reads chunks of bytes from a ProgressMsg port
|
||||
pub struct ProgressMsgPortIterator {
|
||||
progress_port: Receiver<ProgressMsg>
|
||||
}
|
||||
|
||||
impl Iterator for ProgressMsgPortIterator {
|
||||
type Item = Vec<u8>;
|
||||
|
||||
fn next(&mut self) -> Option<Vec<u8>> {
|
||||
match self.progress_port.recv().unwrap() {
|
||||
ProgressMsg::Payload(data) => Some(data),
|
||||
ProgressMsg::Done(Ok(())) => None,
|
||||
ProgressMsg::Done(Err(e)) => {
|
||||
error!("error receiving bytes: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8,14 +8,14 @@ extra message traffic, it also avoids waiting on the same image
|
|||
multiple times and thus triggering reflows multiple times.
|
||||
*/
|
||||
|
||||
use image_cache_task::{ImageCacheTask, ImageResponseMsg, Msg};
|
||||
use image_cache_task::{ImageResponseMsg, ImageCacheTask, Msg};
|
||||
use url::Url;
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::sync::mpsc::{Receiver, channel};
|
||||
use std::sync::mpsc::{channel, Receiver};
|
||||
use util::task::spawn_named;
|
||||
use url::Url;
|
||||
|
||||
pub trait ImageResponder<NodeAddress: Send> {
|
||||
fn respond(&self) -> Box<Fn(ImageResponseMsg, NodeAddress)+Send>;
|
||||
|
@ -166,3 +166,5 @@ impl<NodeAddress: Send + 'static> LocalImageCache<NodeAddress> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
44
components/net_traits/storage_task.rs
Normal file
44
components/net_traits/storage_task.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* 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/. */
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
use url::Url;
|
||||
|
||||
use util::str::DOMString;
|
||||
|
||||
#[derive(Copy)]
|
||||
pub enum StorageType {
|
||||
Session,
|
||||
Local
|
||||
}
|
||||
|
||||
/// Request operations on the storage data associated with a particular url
|
||||
pub enum StorageTaskMsg {
|
||||
/// gets the number of key/value pairs present in the associated storage data
|
||||
Length(Sender<u32>, Url, StorageType),
|
||||
|
||||
/// gets the name of the key at the specified index in the associated storage data
|
||||
Key(Sender<Option<DOMString>>, Url, StorageType, u32),
|
||||
|
||||
/// gets the value associated with the given key in the associated storage data
|
||||
GetItem(Sender<Option<DOMString>>, Url, StorageType, DOMString),
|
||||
|
||||
/// sets the value of the given key in the associated storage data
|
||||
/// TODO throw QuotaExceededError in case of error
|
||||
SetItem(Sender<(bool, Option<DOMString>)>, Url, StorageType, DOMString, DOMString),
|
||||
|
||||
/// removes the key/value pair for the given key in the associated storage data
|
||||
RemoveItem(Sender<Option<DOMString>>, Url, StorageType, DOMString),
|
||||
|
||||
/// clears the associated storage data by removing all the key/value pairs
|
||||
Clear(Sender<bool>, Url, StorageType),
|
||||
|
||||
/// shut down this task
|
||||
Exit
|
||||
}
|
||||
|
||||
/// Handle to a storage task
|
||||
pub type StorageTask = Sender<StorageTaskMsg>;
|
||||
|
||||
|
|
@ -21,8 +21,8 @@ path = "../util"
|
|||
[dependencies.msg]
|
||||
path = "../msg"
|
||||
|
||||
[dependencies.net]
|
||||
path = "../net"
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.profile]
|
||||
path = "../profile"
|
||||
|
|
|
@ -15,8 +15,7 @@ use dom::window::{self, WindowHelpers};
|
|||
use script_task::ScriptChan;
|
||||
|
||||
use msg::constellation_msg::WorkerId;
|
||||
|
||||
use net::resource_task::ResourceTask;
|
||||
use net_traits::ResourceTask;
|
||||
|
||||
use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
|
||||
use js::glue::{GetGlobalForObjectCrossCompartment};
|
||||
|
|
|
@ -48,8 +48,8 @@ use js::rust::{Cx, rt};
|
|||
use layout_interface::{LayoutRPC, LayoutChan};
|
||||
use libc;
|
||||
use msg::constellation_msg::{PipelineId, SubpageId, WindowSizeData, WorkerId};
|
||||
use net::image_cache_task::ImageCacheTask;
|
||||
use net::storage_task::StorageType;
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use net_traits::storage_task::StorageType;
|
||||
use script_traits::ScriptControlChan;
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
use msg::compositor_msg::ScriptListener;
|
||||
|
|
|
@ -24,7 +24,7 @@ use dom::workerglobalscope::WorkerGlobalScopeTypeId;
|
|||
use script_task::{ScriptTask, ScriptChan, ScriptMsg, TimerSource};
|
||||
use script_task::StackRootTLS;
|
||||
|
||||
use net::resource_task::{ResourceTask, load_whole_resource};
|
||||
use net_traits::{load_whole_resource, ResourceTask};
|
||||
use util::task::spawn_named;
|
||||
use util::task_state;
|
||||
use util::task_state::{SCRIPT, IN_WORKER};
|
||||
|
|
|
@ -63,8 +63,8 @@ use msg::compositor_msg::ScriptListener;
|
|||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
use msg::constellation_msg::{ConstellationChan, Key, KeyState, KeyModifiers, MozBrowserEvent};
|
||||
use msg::constellation_msg::{SUPER, ALT, SHIFT, CONTROL};
|
||||
use net::resource_task::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
|
||||
use net::cookie_storage::CookieSource::NonHTTP;
|
||||
use net_traits::CookieSource::NonHTTP;
|
||||
use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
|
||||
use script_task::Runnable;
|
||||
use script_traits::{MouseButton, UntrustedNodeAddress};
|
||||
use util::{opts, namespace};
|
||||
|
|
|
@ -18,7 +18,7 @@ use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
|
|||
use dom::node::{Node, NodeTypeId, NodeHelpers, NodeDamage, window_from_node};
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom::window::WindowHelpers;
|
||||
use net::image_cache_task;
|
||||
use net_traits::image_cache_task;
|
||||
use util::geometry::to_px;
|
||||
use util::str::DOMString;
|
||||
use string_cache::Atom;
|
||||
|
|
|
@ -20,8 +20,7 @@ use dom::node::{Node, NodeTypeId, NodeHelpers, window_from_node};
|
|||
use dom::validitystate::ValidityState;
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
|
||||
use net::image_cache_task;
|
||||
use net::image_cache_task::ImageCacheTask;
|
||||
use net_traits::image_cache_task::{self, ImageCacheTask};
|
||||
use util::str::DOMString;
|
||||
use string_cache::Atom;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ use script_task::{ScriptMsg, Runnable};
|
|||
use encoding::all::UTF_8;
|
||||
use encoding::label::encoding_from_whatwg_label;
|
||||
use encoding::types::{Encoding, EncodingRef, DecoderTrap};
|
||||
use net::resource_task::{load_whole_resource, Metadata};
|
||||
use net_traits::{load_whole_resource, Metadata};
|
||||
use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec};
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::Cell;
|
||||
|
|
|
@ -15,10 +15,8 @@ use dom::storageevent::StorageEvent;
|
|||
use dom::urlhelper::UrlHelper;
|
||||
use dom::window::WindowHelpers;
|
||||
use util::str::DOMString;
|
||||
use net::storage_task::StorageTask;
|
||||
use net::storage_task::StorageType;
|
||||
use net::storage_task::StorageTaskMsg;
|
||||
use page::IterablePage;
|
||||
use net_traits::storage_task::{StorageTask, StorageTaskMsg, StorageType};
|
||||
use std::sync::mpsc::channel;
|
||||
use url::Url;
|
||||
|
||||
|
|
|
@ -37,9 +37,9 @@ use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
|
|||
use devtools_traits::DevtoolsControlChan;
|
||||
use msg::compositor_msg::ScriptListener;
|
||||
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData, WorkerId};
|
||||
use net::image_cache_task::ImageCacheTask;
|
||||
use net::resource_task::ResourceTask;
|
||||
use net::storage_task::{StorageTask, StorageType};
|
||||
use net_traits::ResourceTask;
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use net_traits::storage_task::{StorageTask, StorageType};
|
||||
use util::geometry::{self, Au, MAX_RECT};
|
||||
use util::opts;
|
||||
use util::str::{DOMString,HTML_SPACE_CHARACTERS};
|
||||
|
|
|
@ -20,8 +20,7 @@ use script_task::{ScriptChan, TimerSource};
|
|||
use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
|
||||
|
||||
use msg::constellation_msg::WorkerId;
|
||||
|
||||
use net::resource_task::{ResourceTask, load_whole_resource};
|
||||
use net_traits::{load_whole_resource, ResourceTask};
|
||||
use util::str::DOMString;
|
||||
|
||||
use js::jsapi::JSContext;
|
||||
|
|
|
@ -42,9 +42,9 @@ use js::jsapi::{JS_ParseJSON, JSContext};
|
|||
use js::jsapi::JS_ClearPendingException;
|
||||
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||
|
||||
use net::resource_task::{ResourceTask, ResourceCORSData, LoadData, LoadResponse};
|
||||
use net::resource_task::ControlMsg::Load;
|
||||
use net::resource_task::ProgressMsg::{Payload, Done};
|
||||
use net_traits::ControlMsg::Load;
|
||||
use net_traits::ProgressMsg::{Payload, Done};
|
||||
use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadResponse};
|
||||
use cors::{allow_cross_origin_request, CORSRequest, RequestMode};
|
||||
use util::str::DOMString;
|
||||
use util::task::spawn_named;
|
||||
|
|
|
@ -39,7 +39,7 @@ extern crate hyper;
|
|||
extern crate js;
|
||||
extern crate libc;
|
||||
extern crate msg;
|
||||
extern crate net;
|
||||
extern crate net_traits;
|
||||
extern crate "rustc-serialize" as rustc_serialize;
|
||||
extern crate time;
|
||||
extern crate canvas;
|
||||
|
|
|
@ -26,7 +26,7 @@ use parse::Parser;
|
|||
use encoding::all::UTF_8;
|
||||
use encoding::types::{Encoding, DecoderTrap};
|
||||
|
||||
use net::resource_task::{ProgressMsg, LoadResponse};
|
||||
use net_traits::{ProgressMsg, LoadResponse};
|
||||
use util::task_state;
|
||||
use util::task_state::IN_HTML_PARSER;
|
||||
use std::ascii::AsciiExt;
|
||||
|
|
|
@ -60,10 +60,10 @@ use msg::constellation_msg::{ConstellationChan};
|
|||
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId};
|
||||
use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType};
|
||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||
use net::image_cache_task::ImageCacheTask;
|
||||
use net::resource_task::{ResourceTask, ControlMsg, LoadResponse};
|
||||
use net::resource_task::LoadData as NetLoadData;
|
||||
use net::storage_task::StorageTask;
|
||||
use net_traits::{ResourceTask, ControlMsg, LoadResponse};
|
||||
use net_traits::LoadData as NetLoadData;
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use net_traits::storage_task::StorageTask;
|
||||
use string_cache::Atom;
|
||||
use util::geometry::to_frac_px;
|
||||
use util::smallvec::SmallVec;
|
||||
|
|
|
@ -10,8 +10,8 @@ path = "lib.rs"
|
|||
[dependencies.msg]
|
||||
path = "../msg"
|
||||
|
||||
[dependencies.net]
|
||||
path = "../net"
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.util]
|
||||
path = "../util"
|
||||
|
|
|
@ -6,7 +6,7 @@ extern crate devtools_traits;
|
|||
extern crate geom;
|
||||
extern crate libc;
|
||||
extern crate msg;
|
||||
extern crate net;
|
||||
extern crate net_traits;
|
||||
extern crate util;
|
||||
extern crate url;
|
||||
|
||||
|
@ -21,9 +21,9 @@ use msg::constellation_msg::{ConstellationChan, PipelineId, Failure, WindowSizeD
|
|||
use msg::constellation_msg::{LoadData, SubpageId, Key, KeyState, KeyModifiers};
|
||||
use msg::constellation_msg::{MozBrowserEvent, PipelineExitType};
|
||||
use msg::compositor_msg::ScriptListener;
|
||||
use net::image_cache_task::ImageCacheTask;
|
||||
use net::resource_task::ResourceTask;
|
||||
use net::storage_task::StorageTask;
|
||||
use net_traits::ResourceTask;
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
use net_traits::storage_task::StorageTask;
|
||||
use util::smallvec::SmallVec1;
|
||||
use std::any::Any;
|
||||
use std::sync::mpsc::{Sender, Receiver};
|
||||
|
|
27
components/servo/Cargo.lock
generated
27
components/servo/Cargo.lock
generated
|
@ -11,6 +11,7 @@ dependencies = [
|
|||
"layout 0.0.1",
|
||||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"png 0.1.0 (git+https://github.com/servo/rust-png)",
|
||||
"profile 0.0.1",
|
||||
"script 0.0.1",
|
||||
|
@ -98,6 +99,7 @@ dependencies = [
|
|||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"png 0.1.0 (git+https://github.com/servo/rust-png)",
|
||||
"profile 0.0.1",
|
||||
"script_traits 0.0.1",
|
||||
|
@ -321,7 +323,7 @@ dependencies = [
|
|||
"layers 0.1.0 (git+https://github.com/servo/rust-layers)",
|
||||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"plugins 0.0.1",
|
||||
"png 0.1.0 (git+https://github.com/servo/rust-png)",
|
||||
"profile 0.0.1",
|
||||
|
@ -527,7 +529,7 @@ dependencies = [
|
|||
"layout_traits 0.0.1",
|
||||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"plugins 0.0.1",
|
||||
"png 0.1.0 (git+https://github.com/servo/rust-png)",
|
||||
"profile 0.0.1",
|
||||
|
@ -548,7 +550,7 @@ version = "0.0.1"
|
|||
dependencies = [
|
||||
"gfx 0.0.1",
|
||||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"profile 0.0.1",
|
||||
"script_traits 0.0.1",
|
||||
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -639,18 +641,31 @@ dependencies = [
|
|||
"flate2 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
||||
"hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net_traits 0.0.1",
|
||||
"openssl 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"png 0.1.0 (git+https://github.com/servo/rust-png)",
|
||||
"profile 0.0.1",
|
||||
"regex 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex_macros 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
|
||||
"time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net_traits"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
||||
"hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"png 0.1.0 (git+https://github.com/servo/rust-png)",
|
||||
"profile 0.0.1",
|
||||
"stb_image 0.1.0 (git+https://github.com/servo/rust-stb-image)",
|
||||
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.5.1"
|
||||
|
@ -785,7 +800,7 @@ dependencies = [
|
|||
"js 0.1.0 (git+https://github.com/servo/rust-mozjs)",
|
||||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"plugins 0.0.1",
|
||||
"profile 0.0.1",
|
||||
"rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -808,7 +823,7 @@ dependencies = [
|
|||
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
||||
"libc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
]
|
||||
|
|
|
@ -48,6 +48,9 @@ path = "../compositing"
|
|||
[dependencies.net]
|
||||
path = "../net"
|
||||
|
||||
[dependencies.net_traits]
|
||||
path = "../net_traits"
|
||||
|
||||
[dependencies.msg]
|
||||
path = "../msg"
|
||||
|
||||
|
|
|
@ -2,7 +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/. */
|
||||
|
||||
#![feature(libc, path, rustc_private, thread_local)]
|
||||
#![feature(libc, rustc_private, thread_local)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
@ -10,6 +10,7 @@ extern crate log;
|
|||
extern crate compositing;
|
||||
extern crate devtools;
|
||||
extern crate net;
|
||||
extern crate net_traits;
|
||||
extern crate msg;
|
||||
extern crate profile;
|
||||
#[macro_use]
|
||||
|
@ -33,11 +34,15 @@ use msg::constellation_msg::ConstellationChan;
|
|||
use script::dom::bindings::codegen::RegisterBindings;
|
||||
|
||||
#[cfg(not(test))]
|
||||
use net::image_cache_task::{ImageCacheTask, LoadPlaceholder};
|
||||
use net::image_cache_task::{ImageCacheTaskFactory, LoadPlaceholder};
|
||||
#[cfg(not(test))]
|
||||
use net::storage_task::StorageTaskFactory;
|
||||
#[cfg(not(test))]
|
||||
use net::resource_task::new_resource_task;
|
||||
#[cfg(not(test))]
|
||||
use net::storage_task::{StorageTaskFactory, StorageTask};
|
||||
use net_traits::image_cache_task::ImageCacheTask;
|
||||
#[cfg(not(test))]
|
||||
use net_traits::storage_task::StorageTask;
|
||||
#[cfg(not(test))]
|
||||
use gfx::font_cache_task::FontCacheTask;
|
||||
#[cfg(not(test))]
|
||||
|
@ -82,12 +87,12 @@ impl Browser {
|
|||
// If we are emitting an output file, then we need to block on
|
||||
// image load or we risk emitting an output file missing the
|
||||
// image.
|
||||
let image_cache_task = if opts.output_file.is_some() {
|
||||
ImageCacheTask::new_sync(resource_task.clone(), shared_task_pool,
|
||||
time_profiler_chan.clone(), LoadPlaceholder::Preload)
|
||||
let image_cache_task: ImageCacheTask = if opts.output_file.is_some() {
|
||||
ImageCacheTaskFactory::new_sync(resource_task.clone(), shared_task_pool,
|
||||
time_profiler_chan.clone(), LoadPlaceholder::Preload)
|
||||
} else {
|
||||
ImageCacheTask::new(resource_task.clone(), shared_task_pool,
|
||||
time_profiler_chan.clone(), LoadPlaceholder::Preload)
|
||||
ImageCacheTaskFactory::new(resource_task.clone(), shared_task_pool,
|
||||
time_profiler_chan.clone(), LoadPlaceholder::Preload)
|
||||
};
|
||||
|
||||
let font_cache_task = FontCacheTask::new(resource_task.clone());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue