mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Completely abstract sending responses over channels vs. listeners.
This commit is contained in:
parent
1644436557
commit
7517aac9e9
4 changed files with 61 additions and 21 deletions
|
@ -2,17 +2,16 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use net_traits::{LoadData, Metadata, ProgressMsg, ResponseSenders};
|
use net_traits::{LoadData, Metadata, ResponseSenders};
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
use resource_task::{start_sending, start_sending_sniffed};
|
use resource_task::{start_sending, start_sending_sniffed, ProgressSender};
|
||||||
|
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
|
|
||||||
static READ_SIZE: usize = 8192;
|
static READ_SIZE: usize = 8192;
|
||||||
|
@ -34,7 +33,7 @@ fn read_block(reader: &mut File) -> Result<ReadStatus, String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_all(reader: &mut File, progress_chan: &Sender<ProgressMsg>)
|
fn read_all(reader: &mut File, progress_chan: &ProgressSender)
|
||||||
-> Result<(), String> {
|
-> Result<(), String> {
|
||||||
loop {
|
loop {
|
||||||
match try!(read_block(reader)) {
|
match try!(read_block(reader)) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ use cookie;
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
|
|
||||||
use net_traits::{ControlMsg, LoadData, LoadResponse, ResponseSenders, LoadConsumer};
|
use net_traits::{ControlMsg, LoadData, LoadResponse, ResponseSenders, LoadConsumer};
|
||||||
use net_traits::{Metadata, ProgressMsg, ResourceTask};
|
use net_traits::{Metadata, ProgressMsg, ResourceTask, AsyncResponseTarget, ResponseAction};
|
||||||
use net_traits::ProgressMsg::Done;
|
use net_traits::ProgressMsg::Done;
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
|
@ -58,22 +58,44 @@ pub fn global_init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ProgressSender {
|
||||||
|
Channel(Sender<ProgressMsg>),
|
||||||
|
Listener(Box<AsyncResponseTarget>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProgressSender {
|
||||||
|
//XXXjdm return actual error
|
||||||
|
pub fn send(&self, msg: ProgressMsg) -> Result<(), ()> {
|
||||||
|
match *self {
|
||||||
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message.
|
/// For use by loaders in responding to a Load message.
|
||||||
pub fn start_sending(start_chan: ResponseSenders, metadata: Metadata) -> Sender<ProgressMsg> {
|
pub fn start_sending(start_chan: ResponseSenders, metadata: Metadata) -> ProgressSender {
|
||||||
start_sending_opt(start_chan, metadata).ok().unwrap()
|
start_sending_opt(start_chan, metadata).ok().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message that allows content sniffing.
|
/// For use by loaders in responding to a Load message that allows content sniffing.
|
||||||
pub fn start_sending_sniffed(start_chan: ResponseSenders, metadata: Metadata,
|
pub fn start_sending_sniffed(start_chan: ResponseSenders, metadata: Metadata,
|
||||||
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
||||||
-> Sender<ProgressMsg> {
|
-> ProgressSender {
|
||||||
start_sending_sniffed_opt(start_chan, metadata, classifier, partial_body).ok().unwrap()
|
start_sending_sniffed_opt(start_chan, metadata, classifier, partial_body).ok().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message that allows content sniffing.
|
/// For use by loaders in responding to a Load message that allows content sniffing.
|
||||||
pub fn start_sending_sniffed_opt(start_chan: ResponseSenders, mut metadata: Metadata,
|
pub fn start_sending_sniffed_opt(start_chan: ResponseSenders, mut metadata: Metadata,
|
||||||
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
||||||
-> Result<Sender<ProgressMsg>, ()> {
|
-> Result<ProgressSender, ()> {
|
||||||
if opts::get().sniff_mime_types {
|
if opts::get().sniff_mime_types {
|
||||||
// TODO: should be calculated in the resource loader, from pull requeset #4094
|
// TODO: should be calculated in the resource loader, from pull requeset #4094
|
||||||
let nosniff = false;
|
let nosniff = false;
|
||||||
|
@ -94,7 +116,7 @@ pub fn start_sending_sniffed_opt(start_chan: ResponseSenders, mut metadata: Meta
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message.
|
/// For use by loaders in responding to a Load message.
|
||||||
pub fn start_sending_opt(start_chan: ResponseSenders, metadata: Metadata) -> Result<Sender<ProgressMsg>, ()> {
|
pub fn start_sending_opt(start_chan: ResponseSenders, metadata: Metadata) -> Result<ProgressSender, ()> {
|
||||||
match start_chan {
|
match start_chan {
|
||||||
ResponseSenders::Channel(start_chan) => {
|
ResponseSenders::Channel(start_chan) => {
|
||||||
let (progress_chan, progress_port) = channel();
|
let (progress_chan, progress_port) = channel();
|
||||||
|
@ -103,11 +125,14 @@ pub fn start_sending_opt(start_chan: ResponseSenders, metadata: Metadata) -> Res
|
||||||
progress_port: progress_port,
|
progress_port: progress_port,
|
||||||
});
|
});
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => Ok(progress_chan),
|
Ok(_) => Ok(ProgressSender::Channel(progress_chan)),
|
||||||
Err(_) => Err(())
|
Err(_) => Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResponseSenders::Listener(_) => panic!(),
|
ResponseSenders::Listener(target) => {
|
||||||
|
target.invoke_with_listener(ResponseAction::HeadersAvailable(metadata));
|
||||||
|
Ok(ProgressSender::Listener(target))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,24 @@ pub trait AsyncResponseListener {
|
||||||
fn response_complete(&self, status: Result<(), String>);
|
fn response_complete(&self, status: Result<(), String>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ResponseAction {
|
||||||
|
HeadersAvailable(Metadata),
|
||||||
|
DataAvailable(Vec<u8>),
|
||||||
|
ResponseComplete(Result<(), String>)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponseAction {
|
||||||
|
pub fn process(self, listener: &AsyncResponseListener) {
|
||||||
|
match self {
|
||||||
|
ResponseAction::HeadersAvailable(m) => listener.headers_available(m),
|
||||||
|
ResponseAction::DataAvailable(d) => listener.data_available(d),
|
||||||
|
ResponseAction::ResponseComplete(r) => listener.response_complete(r),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait AsyncResponseTarget {
|
pub trait AsyncResponseTarget {
|
||||||
fn get_listener(&self) -> &AsyncResponseListener;
|
fn invoke_with_listener(&self, action: ResponseAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum LoadConsumer {
|
pub enum LoadConsumer {
|
||||||
|
@ -174,7 +190,7 @@ pub enum CookieSource {
|
||||||
|
|
||||||
pub enum ResponseSenders {
|
pub enum ResponseSenders {
|
||||||
Channel(Sender<LoadResponse>),
|
Channel(Sender<LoadResponse>),
|
||||||
Listener(Box<AsyncResponseTarget + Send>),
|
Listener(Box<AsyncResponseTarget+ Send>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseSenders {
|
impl ResponseSenders {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use net::image_cache_task::*;
|
||||||
use net_traits::image_cache_task::ImageResponseMsg::*;
|
use net_traits::image_cache_task::ImageResponseMsg::*;
|
||||||
use net_traits::image_cache_task::Msg::*;
|
use net_traits::image_cache_task::Msg::*;
|
||||||
|
|
||||||
use net::resource_task::start_sending;
|
use net::resource_task::{start_sending, ProgressSender};
|
||||||
use net_traits::{ControlMsg, Metadata, ProgressMsg, ResourceTask, ResponseSenders};
|
use net_traits::{ControlMsg, Metadata, ProgressMsg, ResourceTask, ResponseSenders};
|
||||||
use net_traits::image_cache_task::{ImageCacheTask, ImageCacheTaskClient, ImageResponseMsg, Msg};
|
use net_traits::image_cache_task::{ImageCacheTask, ImageCacheTaskClient, ImageResponseMsg, Msg};
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
|
@ -41,7 +41,7 @@ impl ImageCacheTaskHelper for ImageCacheTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Closure {
|
trait Closure {
|
||||||
fn invoke(&self, _response: Sender<ProgressMsg>) { }
|
fn invoke(&self, _response: ProgressSender) { }
|
||||||
}
|
}
|
||||||
struct DoesNothing;
|
struct DoesNothing;
|
||||||
impl Closure for DoesNothing { }
|
impl Closure for DoesNothing { }
|
||||||
|
@ -50,7 +50,7 @@ struct JustSendOK {
|
||||||
url_requested_chan: Sender<()>,
|
url_requested_chan: Sender<()>,
|
||||||
}
|
}
|
||||||
impl Closure for JustSendOK {
|
impl Closure for JustSendOK {
|
||||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
fn invoke(&self, response: ProgressSender) {
|
||||||
self.url_requested_chan.send(()).unwrap();
|
self.url_requested_chan.send(()).unwrap();
|
||||||
response.send(Done(Ok(()))).unwrap();
|
response.send(Done(Ok(()))).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ impl Closure for JustSendOK {
|
||||||
|
|
||||||
struct SendTestImage;
|
struct SendTestImage;
|
||||||
impl Closure for SendTestImage {
|
impl Closure for SendTestImage {
|
||||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
fn invoke(&self, response: ProgressSender) {
|
||||||
response.send(Payload(test_image_bin())).unwrap();
|
response.send(Payload(test_image_bin())).unwrap();
|
||||||
response.send(Done(Ok(()))).unwrap();
|
response.send(Done(Ok(()))).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ impl Closure for SendTestImage {
|
||||||
|
|
||||||
struct SendBogusImage;
|
struct SendBogusImage;
|
||||||
impl Closure for SendBogusImage {
|
impl Closure for SendBogusImage {
|
||||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
fn invoke(&self, response: ProgressSender) {
|
||||||
response.send(Payload(vec!())).unwrap();
|
response.send(Payload(vec!())).unwrap();
|
||||||
response.send(Done(Ok(()))).unwrap();
|
response.send(Done(Ok(()))).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ impl Closure for SendBogusImage {
|
||||||
|
|
||||||
struct SendTestImageErr;
|
struct SendTestImageErr;
|
||||||
impl Closure for SendTestImageErr {
|
impl Closure for SendTestImageErr {
|
||||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
fn invoke(&self, response: ProgressSender) {
|
||||||
response.send(Payload(test_image_bin())).unwrap();
|
response.send(Payload(test_image_bin())).unwrap();
|
||||||
response.send(Done(Err("".to_string()))).unwrap();
|
response.send(Done(Err("".to_string()))).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ struct WaitSendTestImage {
|
||||||
wait_port: Receiver<()>,
|
wait_port: Receiver<()>,
|
||||||
}
|
}
|
||||||
impl Closure for WaitSendTestImage {
|
impl Closure for WaitSendTestImage {
|
||||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
fn invoke(&self, response: ProgressSender) {
|
||||||
// Don't send the data until after the client requests
|
// Don't send the data until after the client requests
|
||||||
// the image
|
// the image
|
||||||
self.wait_port.recv().unwrap();
|
self.wait_port.recv().unwrap();
|
||||||
|
@ -97,7 +97,7 @@ struct WaitSendTestImageErr {
|
||||||
wait_port: Receiver<()>,
|
wait_port: Receiver<()>,
|
||||||
}
|
}
|
||||||
impl Closure for WaitSendTestImageErr {
|
impl Closure for WaitSendTestImageErr {
|
||||||
fn invoke(&self, response: Sender<ProgressMsg>) {
|
fn invoke(&self, response: ProgressSender) {
|
||||||
// Don't send the data until after the client requests
|
// Don't send the data until after the client requests
|
||||||
// the image
|
// the image
|
||||||
self.wait_port.recv().unwrap();
|
self.wait_port.recv().unwrap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue