mirror of
https://github.com/servo/servo.git
synced 2025-08-07 22:45:34 +01:00
adding interface for custom responses
This commit is contained in:
parent
bcea0ada27
commit
3766cd1673
17 changed files with 663 additions and 146 deletions
|
@ -5,8 +5,9 @@
|
|||
use about_loader;
|
||||
use mime_classifier::MIMEClassifier;
|
||||
use mime_guess::guess_mime_type;
|
||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||
use net_traits::ProgressMsg::{Done, Payload};
|
||||
use net_traits::{LoadConsumer, LoadData, Metadata, NetworkError};
|
||||
use net_traits::{LoadConsumer, LoadData, Metadata, NetworkError, LoadOrigin, RequestSource};
|
||||
use resource_thread::{CancellationListener, ProgressSender};
|
||||
use resource_thread::{send_error, start_sending_sniffed_opt};
|
||||
use std::borrow::ToOwned;
|
||||
|
@ -30,6 +31,22 @@ enum LoadResult {
|
|||
Finished,
|
||||
}
|
||||
|
||||
struct FileLoadOrigin;
|
||||
impl LoadOrigin for FileLoadOrigin {
|
||||
fn referrer_url(&self) -> Option<Url> {
|
||||
None
|
||||
}
|
||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||
None
|
||||
}
|
||||
fn request_source(&self) -> RequestSource {
|
||||
RequestSource::None
|
||||
}
|
||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn read_block(reader: &mut File) -> Result<ReadStatus, String> {
|
||||
let mut buf = vec![0; READ_SIZE];
|
||||
match reader.read(&mut buf) {
|
||||
|
@ -84,11 +101,12 @@ pub fn factory(load_data: LoadData,
|
|||
// http://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open
|
||||
// but, we'll go for a "file not found!"
|
||||
let url = Url::parse("about:not-found").unwrap();
|
||||
let load_data_404 = LoadData::new(load_data.context, url, None, None, None);
|
||||
let load_data_404 = LoadData::new(load_data.context, url, &FileLoadOrigin);
|
||||
about_loader::factory(load_data_404, senders, classifier, cancel_listener);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if cancel_listener.is_cancelled() {
|
||||
if let Ok(progress_chan) = get_progress_chan(load_data, file_path,
|
||||
senders, classifier, &[]) {
|
||||
|
@ -96,6 +114,7 @@ pub fn factory(load_data: LoadData,
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
match read_block(reader) {
|
||||
Ok(ReadStatus::Partial(buf)) => {
|
||||
let progress_chan = get_progress_chan(load_data, file_path,
|
||||
|
|
|
@ -13,15 +13,16 @@ use flate2::read::{DeflateDecoder, GzDecoder};
|
|||
use hsts::{HstsEntry, HstsList, secure_url};
|
||||
use hyper::Error as HttpError;
|
||||
use hyper::client::{Pool, Request, Response};
|
||||
use hyper::header::{Accept, AcceptEncoding, ContentLength, ContentType, Host, Referer};
|
||||
use hyper::header::{Accept, AcceptEncoding, ContentLength, ContentEncoding, ContentType, Host, Referer};
|
||||
use hyper::header::{Authorization, Basic};
|
||||
use hyper::header::{ContentEncoding, Encoding, Header, Headers, Quality, QualityItem};
|
||||
use hyper::header::{Encoding, Header, Headers, Quality, QualityItem};
|
||||
use hyper::header::{Location, SetCookie, StrictTransportSecurity, UserAgent, qitem};
|
||||
use hyper::http::RawStatus;
|
||||
use hyper::method::Method;
|
||||
use hyper::mime::{Mime, SubLevel, TopLevel};
|
||||
use hyper::net::Fresh;
|
||||
use hyper::status::{StatusClass, StatusCode};
|
||||
use ipc_channel::ipc;
|
||||
use log;
|
||||
use mime_classifier::MIMEClassifier;
|
||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||
|
@ -29,7 +30,7 @@ use net_traits::ProgressMsg::{Done, Payload};
|
|||
use net_traits::hosts::replace_hosts;
|
||||
use net_traits::response::HttpsState;
|
||||
use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadContext, LoadData};
|
||||
use net_traits::{Metadata, NetworkError};
|
||||
use net_traits::{Metadata, NetworkError, RequestSource, CustomResponse};
|
||||
use openssl::ssl::error::{SslError, OpensslError};
|
||||
use profile_traits::time::{ProfilerCategory, profile, ProfilerChan, TimerMetadata};
|
||||
use profile_traits::time::{TimerMetadataReflowType, TimerMetadataFrameType};
|
||||
|
@ -39,7 +40,7 @@ use std::boxed::FnBox;
|
|||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::io::{self, Cursor, Read, Write};
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use time;
|
||||
|
@ -149,6 +150,17 @@ fn load_for_consumer(load_data: LoadData,
|
|||
}
|
||||
}
|
||||
|
||||
pub struct WrappedHttpResponse {
|
||||
pub response: Response
|
||||
}
|
||||
|
||||
impl Read for WrappedHttpResponse {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.response.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HttpResponse: Read {
|
||||
fn headers(&self) -> &Headers;
|
||||
fn status(&self) -> StatusCode;
|
||||
|
@ -173,20 +185,6 @@ pub trait HttpResponse: Read {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct WrappedHttpResponse {
|
||||
pub response: Response
|
||||
}
|
||||
|
||||
impl Read for WrappedHttpResponse {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.response.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl HttpResponse for WrappedHttpResponse {
|
||||
fn headers(&self) -> &Headers {
|
||||
&self.response.headers
|
||||
|
@ -205,6 +203,34 @@ impl HttpResponse for WrappedHttpResponse {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ReadableCustomResponse {
|
||||
headers: Headers,
|
||||
raw_status: RawStatus,
|
||||
body: Cursor<Vec<u8>>
|
||||
}
|
||||
|
||||
pub fn to_readable_response(custom_response: CustomResponse) -> ReadableCustomResponse {
|
||||
ReadableCustomResponse {
|
||||
headers: custom_response.headers,
|
||||
raw_status: custom_response.raw_status,
|
||||
body: Cursor::new(custom_response.body)
|
||||
}
|
||||
}
|
||||
|
||||
impl HttpResponse for ReadableCustomResponse {
|
||||
fn headers(&self) -> &Headers { &self.headers }
|
||||
fn status(&self) -> StatusCode {
|
||||
StatusCode::Ok
|
||||
}
|
||||
fn status_raw(&self) -> &RawStatus { &self.raw_status }
|
||||
}
|
||||
|
||||
impl Read for ReadableCustomResponse {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.body.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HttpRequestFactory {
|
||||
type R: HttpRequest;
|
||||
|
||||
|
@ -466,13 +492,13 @@ fn update_sts_list_from_response(url: &Url, response: &HttpResponse, hsts_list:
|
|||
}
|
||||
}
|
||||
|
||||
pub struct StreamedResponse<R: HttpResponse> {
|
||||
decoder: Decoder<R>,
|
||||
pub struct StreamedResponse {
|
||||
decoder: Decoder,
|
||||
pub metadata: Metadata
|
||||
}
|
||||
|
||||
|
||||
impl<R: HttpResponse> Read for StreamedResponse<R> {
|
||||
impl Read for StreamedResponse {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
match self.decoder {
|
||||
|
@ -484,12 +510,12 @@ impl<R: HttpResponse> Read for StreamedResponse<R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: HttpResponse> StreamedResponse<R> {
|
||||
fn new(m: Metadata, d: Decoder<R>) -> StreamedResponse<R> {
|
||||
impl StreamedResponse {
|
||||
fn new(m: Metadata, d: Decoder) -> StreamedResponse {
|
||||
StreamedResponse { metadata: m, decoder: d }
|
||||
}
|
||||
|
||||
fn from_http_response(response: R, m: Metadata) -> Result<StreamedResponse<R>, LoadError> {
|
||||
fn from_http_response(response: Box<HttpResponse>, m: Metadata) -> Result<StreamedResponse, LoadError> {
|
||||
let decoder = match response.content_encoding() {
|
||||
Some(Encoding::Gzip) => {
|
||||
let result = GzDecoder::new(response);
|
||||
|
@ -515,11 +541,11 @@ impl<R: HttpResponse> StreamedResponse<R> {
|
|||
}
|
||||
}
|
||||
|
||||
enum Decoder<R: Read> {
|
||||
Gzip(GzDecoder<R>),
|
||||
Deflate(DeflateDecoder<R>),
|
||||
Brotli(Decompressor<R>),
|
||||
Plain(R)
|
||||
enum Decoder {
|
||||
Gzip(GzDecoder<Box<HttpResponse>>),
|
||||
Deflate(DeflateDecoder<Box<HttpResponse>>),
|
||||
Brotli(Decompressor<Box<HttpResponse>>),
|
||||
Plain(Box<HttpResponse>)
|
||||
}
|
||||
|
||||
fn send_request_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||
|
@ -771,7 +797,7 @@ pub fn load<A, B>(load_data: &LoadData,
|
|||
request_factory: &HttpRequestFactory<R=A>,
|
||||
user_agent: String,
|
||||
cancel_listener: &CancellationListener)
|
||||
-> Result<StreamedResponse<A::R>, LoadError> where A: HttpRequest + 'static, B: UIProvider {
|
||||
-> Result<StreamedResponse, LoadError> where A: HttpRequest + 'static, B: UIProvider {
|
||||
let max_redirects = prefs::get_pref("network.http.redirection-limit").as_i64().unwrap() as u32;
|
||||
let mut iters = 0;
|
||||
// URL of the document being loaded, as seen by all the higher-level code.
|
||||
|
@ -785,6 +811,20 @@ pub fn load<A, B>(load_data: &LoadData,
|
|||
return Err(LoadError::new(doc_url, LoadErrorType::Cancelled));
|
||||
}
|
||||
|
||||
let (msg_sender, msg_receiver) = ipc::channel().unwrap();
|
||||
match load_data.source {
|
||||
RequestSource::Window(ref sender) | RequestSource::Worker(ref sender) => {
|
||||
sender.send(msg_sender.clone()).unwrap();
|
||||
let received_msg = msg_receiver.recv().unwrap();
|
||||
if let Some(custom_response) = received_msg {
|
||||
let metadata = Metadata::default(doc_url.clone());
|
||||
let readable_response = to_readable_response(custom_response);
|
||||
return StreamedResponse::from_http_response(box readable_response, metadata);
|
||||
}
|
||||
}
|
||||
RequestSource::None => {}
|
||||
}
|
||||
|
||||
// If the URL is a view-source scheme then the scheme data contains the
|
||||
// real URL that should be used for which the source is to be viewed.
|
||||
// Change our existing URL to that and keep note that we are viewing
|
||||
|
@ -942,7 +982,7 @@ pub fn load<A, B>(load_data: &LoadData,
|
|||
metadata.headers.clone(), metadata.status.clone(),
|
||||
pipeline_id);
|
||||
}
|
||||
return StreamedResponse::from_http_response(response, metadata)
|
||||
return StreamedResponse::from_http_response(box response, metadata)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
use immeta::load_from_buf;
|
||||
use ipc_channel::ipc::{self, IpcSender, IpcReceiver};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||
use net_traits::image::base::{Image, ImageMetadata, load_from_memory, PixelFormat};
|
||||
use net_traits::image_cache_thread::ImageResponder;
|
||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState};
|
||||
use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
|
||||
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadData, CoreResourceThread};
|
||||
use net_traits::{ResponseAction, LoadContext, NetworkError};
|
||||
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadData, CoreResourceThread, LoadOrigin};
|
||||
use net_traits::{ResponseAction, LoadContext, NetworkError, RequestSource};
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
|
@ -304,6 +305,23 @@ fn convert_format(format: PixelFormat) -> webrender_traits::ImageFormat {
|
|||
}
|
||||
}
|
||||
|
||||
struct ImageCacheOrigin;
|
||||
impl LoadOrigin for ImageCacheOrigin {
|
||||
fn referrer_url(&self) -> Option<Url> {
|
||||
None
|
||||
}
|
||||
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||
None
|
||||
}
|
||||
fn request_source(&self) -> RequestSource {
|
||||
RequestSource::None
|
||||
}
|
||||
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl ImageCache {
|
||||
fn run(core_resource_thread: CoreResourceThread,
|
||||
webrender_api: Option<webrender_traits::RenderApi>,
|
||||
|
@ -520,7 +538,9 @@ impl ImageCache {
|
|||
CacheResult::Miss => {
|
||||
// A new load request! Request the load from
|
||||
// the resource thread.
|
||||
let load_data = LoadData::new(LoadContext::Image, (*ref_url).clone(), None, None, None);
|
||||
let load_data = LoadData::new(LoadContext::Image,
|
||||
(*ref_url).clone(),
|
||||
&ImageCacheOrigin);
|
||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||
let response_target = AsyncResponseTarget {
|
||||
sender: action_sender,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue