diff options
Diffstat (limited to 'src/components/net/resource_task.rs')
-rw-r--r-- | src/components/net/resource_task.rs | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/src/components/net/resource_task.rs b/src/components/net/resource_task.rs index ffe8648ce80..5a738df59bf 100644 --- a/src/components/net/resource_task.rs +++ b/src/components/net/resource_task.rs @@ -9,31 +9,69 @@ use http_loader; use std::cell::Cell; use std::comm::{Chan, Port, SharedChan}; +use std::comm; use extra::url::Url; use util::spawn_listener; pub enum ControlMsg { /// Request the data associated with a particular URL - Load(Url, Chan<ProgressMsg>), + Load(Url, Chan<LoadResponse>), Exit } +/// Metadata about a loaded resource, such as is obtained from HTTP headers. +pub struct Metadata { + /// Final URL after redirects. + final_url: Url, + + // Other fields (e.g. content type, charset) will go here. +} + +impl Metadata { + /// Metadata with defaults for everything optional. + pub fn default(url: Url) -> Metadata { + Metadata { + final_url: url, + } + } +} + +/// 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. + metadata: Metadata, + /// Port for reading data. + progress_port: Port<ProgressMsg>, +} + /// Messages sent in response to a `Load` message #[deriving(Eq)] pub enum ProgressMsg { - /// URL changed due to a redirect. There can be zero or more of these, - /// but they are guaranteed to arrive before messages of any other type. - UrlChange(Url), /// Binary data - there may be multiple of these Payload(~[u8]), /// Indicates loading is complete, either successfully or not Done(Result<(), ()>) } +/// For use by loaders in responding to a Load message. +pub fn start_sending(start_chan: Chan<LoadResponse>, + metadata: Metadata) -> Chan<ProgressMsg> { + let (progress_port, progress_chan) = comm::stream(); + start_chan.send(LoadResponse { + metadata: metadata, + progress_port: progress_port, + }); + progress_chan +} + /// Handle to a resource task pub type ResourceTask = SharedChan<ControlMsg>; -pub type LoaderTask = ~fn(url: Url, Chan<ProgressMsg>); +pub type LoaderTask = ~fn(url: Url, Chan<LoadResponse>); /** Creates a task to load a specific resource @@ -81,8 +119,8 @@ impl ResourceManager { fn start(&self) { loop { match self.from_client.recv() { - Load(url, progress_chan) => { - self.load(url.clone(), progress_chan) + Load(url, start_chan) => { + self.load(url.clone(), start_chan) } Exit => { break @@ -91,16 +129,15 @@ impl ResourceManager { } } - fn load(&self, url: Url, progress_chan: Chan<ProgressMsg>) { - + fn load(&self, url: Url, start_chan: Chan<LoadResponse>) { match self.get_loader_factory(&url) { Some(loader_factory) => { debug!("resource_task: loading url: %s", url.to_str()); - loader_factory(url, progress_chan); + loader_factory(url, start_chan); } None => { debug!("resource_task: no loader for scheme %s", url.scheme); - progress_chan.send(Done(Err(()))); + start_sending(start_chan, Metadata::default(url)).send(Done(Err(()))); } } } @@ -140,7 +177,8 @@ fn test_bad_scheme() { #[test] fn should_delegate_to_scheme_loader() { let payload = ~[1, 2, 3]; - let loader_factory = |_url: Url, progress_chan: Chan<ProgressMsg>| { + let loader_factory = |url: Url, start_chan: Chan<LoadResponse>| { + let progress_chan = start_sending(start_chan, Metadata::default(url)); progress_chan.send(Payload(payload.clone())); progress_chan.send(Done(Ok(()))); }; |