mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #10961 - creativcoder:custom_response_iface, r=jdm
adding interface for custom responses Fixes #10960 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10961) <!-- Reviewable:end -->
This commit is contained in:
commit
1a34137ac4
17 changed files with 663 additions and 146 deletions
|
@ -6,7 +6,7 @@ use font_template::{FontTemplate, FontTemplateDescriptor};
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use mime::{TopLevel, SubLevel};
|
use mime::{TopLevel, SubLevel};
|
||||||
use net_traits::{AsyncResponseTarget, LoadContext, PendingAsyncLoad, CoreResourceThread, ResponseAction};
|
use net_traits::{AsyncResponseTarget, LoadContext, PendingAsyncLoad, CoreResourceThread, ResponseAction, RequestSource};
|
||||||
use platform::font_context::FontContextHandle;
|
use platform::font_context::FontContextHandle;
|
||||||
use platform::font_list::SANS_SERIF_FONT_FAMILY;
|
use platform::font_list::SANS_SERIF_FONT_FAMILY;
|
||||||
use platform::font_list::for_each_available_family;
|
use platform::font_list::for_each_available_family;
|
||||||
|
@ -186,7 +186,8 @@ impl FontCache {
|
||||||
url.clone(),
|
url.clone(),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None);
|
None,
|
||||||
|
RequestSource::None);
|
||||||
let (data_sender, data_receiver) = ipc::channel().unwrap();
|
let (data_sender, data_receiver) = ipc::channel().unwrap();
|
||||||
let data_target = AsyncResponseTarget {
|
let data_target = AsyncResponseTarget {
|
||||||
sender: data_sender,
|
sender: data_sender,
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
use about_loader;
|
use about_loader;
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
use mime_guess::guess_mime_type;
|
use mime_guess::guess_mime_type;
|
||||||
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
use net_traits::ProgressMsg::{Done, Payload};
|
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::{CancellationListener, ProgressSender};
|
||||||
use resource_thread::{send_error, start_sending_sniffed_opt};
|
use resource_thread::{send_error, start_sending_sniffed_opt};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
@ -30,6 +31,22 @@ enum LoadResult {
|
||||||
Finished,
|
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> {
|
fn read_block(reader: &mut File) -> Result<ReadStatus, String> {
|
||||||
let mut buf = vec![0; READ_SIZE];
|
let mut buf = vec![0; READ_SIZE];
|
||||||
match reader.read(&mut buf) {
|
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
|
// http://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open
|
||||||
// but, we'll go for a "file not found!"
|
// but, we'll go for a "file not found!"
|
||||||
let url = Url::parse("about:not-found").unwrap();
|
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);
|
about_loader::factory(load_data_404, senders, classifier, cancel_listener);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if cancel_listener.is_cancelled() {
|
if cancel_listener.is_cancelled() {
|
||||||
if let Ok(progress_chan) = get_progress_chan(load_data, file_path,
|
if let Ok(progress_chan) = get_progress_chan(load_data, file_path,
|
||||||
senders, classifier, &[]) {
|
senders, classifier, &[]) {
|
||||||
|
@ -96,6 +114,7 @@ pub fn factory(load_data: LoadData,
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match read_block(reader) {
|
match read_block(reader) {
|
||||||
Ok(ReadStatus::Partial(buf)) => {
|
Ok(ReadStatus::Partial(buf)) => {
|
||||||
let progress_chan = get_progress_chan(load_data, file_path,
|
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 hsts::{HstsEntry, HstsList, secure_url};
|
||||||
use hyper::Error as HttpError;
|
use hyper::Error as HttpError;
|
||||||
use hyper::client::{Pool, Request, Response};
|
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::{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::header::{Location, SetCookie, StrictTransportSecurity, UserAgent, qitem};
|
||||||
use hyper::http::RawStatus;
|
use hyper::http::RawStatus;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use hyper::mime::{Mime, SubLevel, TopLevel};
|
use hyper::mime::{Mime, SubLevel, TopLevel};
|
||||||
use hyper::net::Fresh;
|
use hyper::net::Fresh;
|
||||||
use hyper::status::{StatusClass, StatusCode};
|
use hyper::status::{StatusClass, StatusCode};
|
||||||
|
use ipc_channel::ipc;
|
||||||
use log;
|
use log;
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
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::hosts::replace_hosts;
|
||||||
use net_traits::response::HttpsState;
|
use net_traits::response::HttpsState;
|
||||||
use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadContext, LoadData};
|
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 openssl::ssl::error::{SslError, OpensslError};
|
||||||
use profile_traits::time::{ProfilerCategory, profile, ProfilerChan, TimerMetadata};
|
use profile_traits::time::{ProfilerCategory, profile, ProfilerChan, TimerMetadata};
|
||||||
use profile_traits::time::{TimerMetadataReflowType, TimerMetadataFrameType};
|
use profile_traits::time::{TimerMetadataReflowType, TimerMetadataFrameType};
|
||||||
|
@ -39,7 +40,7 @@ use std::boxed::FnBox;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Cursor, Read, Write};
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use time;
|
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 {
|
pub trait HttpResponse: Read {
|
||||||
fn headers(&self) -> &Headers;
|
fn headers(&self) -> &Headers;
|
||||||
fn status(&self) -> StatusCode;
|
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 {
|
impl HttpResponse for WrappedHttpResponse {
|
||||||
fn headers(&self) -> &Headers {
|
fn headers(&self) -> &Headers {
|
||||||
&self.response.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 {
|
pub trait HttpRequestFactory {
|
||||||
type R: HttpRequest;
|
type R: HttpRequest;
|
||||||
|
|
||||||
|
@ -466,13 +492,13 @@ fn update_sts_list_from_response(url: &Url, response: &HttpResponse, hsts_list:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StreamedResponse<R: HttpResponse> {
|
pub struct StreamedResponse {
|
||||||
decoder: Decoder<R>,
|
decoder: Decoder,
|
||||||
pub metadata: Metadata
|
pub metadata: Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<R: HttpResponse> Read for StreamedResponse<R> {
|
impl Read for StreamedResponse {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
match self.decoder {
|
match self.decoder {
|
||||||
|
@ -484,12 +510,12 @@ impl<R: HttpResponse> Read for StreamedResponse<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: HttpResponse> StreamedResponse<R> {
|
impl StreamedResponse {
|
||||||
fn new(m: Metadata, d: Decoder<R>) -> StreamedResponse<R> {
|
fn new(m: Metadata, d: Decoder) -> StreamedResponse {
|
||||||
StreamedResponse { metadata: m, decoder: d }
|
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() {
|
let decoder = match response.content_encoding() {
|
||||||
Some(Encoding::Gzip) => {
|
Some(Encoding::Gzip) => {
|
||||||
let result = GzDecoder::new(response);
|
let result = GzDecoder::new(response);
|
||||||
|
@ -515,11 +541,11 @@ impl<R: HttpResponse> StreamedResponse<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Decoder<R: Read> {
|
enum Decoder {
|
||||||
Gzip(GzDecoder<R>),
|
Gzip(GzDecoder<Box<HttpResponse>>),
|
||||||
Deflate(DeflateDecoder<R>),
|
Deflate(DeflateDecoder<Box<HttpResponse>>),
|
||||||
Brotli(Decompressor<R>),
|
Brotli(Decompressor<Box<HttpResponse>>),
|
||||||
Plain(R)
|
Plain(Box<HttpResponse>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_request_to_devtools(devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
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>,
|
request_factory: &HttpRequestFactory<R=A>,
|
||||||
user_agent: String,
|
user_agent: String,
|
||||||
cancel_listener: &CancellationListener)
|
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 max_redirects = prefs::get_pref("network.http.redirection-limit").as_i64().unwrap() as u32;
|
||||||
let mut iters = 0;
|
let mut iters = 0;
|
||||||
// URL of the document being loaded, as seen by all the higher-level code.
|
// 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));
|
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
|
// 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.
|
// 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
|
// 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(),
|
metadata.headers.clone(), metadata.status.clone(),
|
||||||
pipeline_id);
|
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 immeta::load_from_buf;
|
||||||
use ipc_channel::ipc::{self, IpcSender, IpcReceiver};
|
use ipc_channel::ipc::{self, IpcSender, IpcReceiver};
|
||||||
use ipc_channel::router::ROUTER;
|
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::base::{Image, ImageMetadata, load_from_memory, PixelFormat};
|
||||||
use net_traits::image_cache_thread::ImageResponder;
|
use net_traits::image_cache_thread::ImageResponder;
|
||||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState};
|
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState};
|
||||||
use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
|
use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
|
||||||
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadData, CoreResourceThread};
|
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadData, CoreResourceThread, LoadOrigin};
|
||||||
use net_traits::{ResponseAction, LoadContext, NetworkError};
|
use net_traits::{ResponseAction, LoadContext, NetworkError, RequestSource};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
|
@ -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 {
|
impl ImageCache {
|
||||||
fn run(core_resource_thread: CoreResourceThread,
|
fn run(core_resource_thread: CoreResourceThread,
|
||||||
webrender_api: Option<webrender_traits::RenderApi>,
|
webrender_api: Option<webrender_traits::RenderApi>,
|
||||||
|
@ -520,7 +538,9 @@ impl ImageCache {
|
||||||
CacheResult::Miss => {
|
CacheResult::Miss => {
|
||||||
// A new load request! Request the load from
|
// A new load request! Request the load from
|
||||||
// the resource thread.
|
// the resource thread.
|
||||||
let load_data = LoadData::new(LoadContext::Image, (*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 (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
let response_target = AsyncResponseTarget {
|
let response_target = AsyncResponseTarget {
|
||||||
sender: action_sender,
|
sender: action_sender,
|
||||||
|
|
|
@ -76,6 +76,30 @@ pub enum LoadContext {
|
||||||
CacheManifest,
|
CacheManifest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, HeapSizeOf)]
|
||||||
|
pub struct CustomResponse {
|
||||||
|
#[ignore_heap_size_of = "Defined in hyper"]
|
||||||
|
pub headers: Headers,
|
||||||
|
#[ignore_heap_size_of = "Defined in hyper"]
|
||||||
|
pub raw_status: RawStatus,
|
||||||
|
pub body: Vec<u8>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomResponse {
|
||||||
|
pub fn new(headers: Headers, raw_status: RawStatus, body: Vec<u8>) -> CustomResponse {
|
||||||
|
CustomResponse { headers: headers, raw_status: raw_status, body: body }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type CustomResponseSender = IpcSender<Option<CustomResponse>>;
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
|
||||||
|
pub enum RequestSource {
|
||||||
|
Window(#[ignore_heap_size_of = "Defined in ipc-channel"] IpcSender<CustomResponseSender>),
|
||||||
|
Worker(#[ignore_heap_size_of = "Defined in ipc-channel"] IpcSender<CustomResponseSender>),
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
|
#[derive(Clone, Deserialize, Serialize, HeapSizeOf)]
|
||||||
pub struct LoadData {
|
pub struct LoadData {
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
|
@ -96,15 +120,14 @@ pub struct LoadData {
|
||||||
/// The policy and referring URL for the originator of this request
|
/// The policy and referring URL for the originator of this request
|
||||||
pub referrer_policy: Option<ReferrerPolicy>,
|
pub referrer_policy: Option<ReferrerPolicy>,
|
||||||
pub referrer_url: Option<Url>,
|
pub referrer_url: Option<Url>,
|
||||||
|
pub source: RequestSource,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoadData {
|
impl LoadData {
|
||||||
pub fn new(context: LoadContext,
|
pub fn new(context: LoadContext,
|
||||||
url: Url,
|
url: Url,
|
||||||
id: Option<PipelineId>,
|
load_origin: &LoadOrigin) -> LoadData {
|
||||||
referrer_policy: Option<ReferrerPolicy>,
|
|
||||||
referrer_url: Option<Url>) -> LoadData {
|
|
||||||
LoadData {
|
LoadData {
|
||||||
url: url,
|
url: url,
|
||||||
method: Method::Get,
|
method: Method::Get,
|
||||||
|
@ -112,15 +135,23 @@ impl LoadData {
|
||||||
preserved_headers: Headers::new(),
|
preserved_headers: Headers::new(),
|
||||||
data: None,
|
data: None,
|
||||||
cors: None,
|
cors: None,
|
||||||
pipeline_id: id,
|
pipeline_id: load_origin.pipeline_id(),
|
||||||
credentials_flag: true,
|
credentials_flag: true,
|
||||||
context: context,
|
context: context,
|
||||||
referrer_policy: referrer_policy,
|
referrer_policy: load_origin.referrer_policy(),
|
||||||
referrer_url: referrer_url
|
referrer_url: load_origin.referrer_url(),
|
||||||
|
source: load_origin.request_source()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait LoadOrigin {
|
||||||
|
fn referrer_url(&self) -> Option<Url>;
|
||||||
|
fn referrer_policy(&self) -> Option<ReferrerPolicy>;
|
||||||
|
fn request_source(&self) -> RequestSource;
|
||||||
|
fn pipeline_id(&self) -> Option<PipelineId>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Interface for observing the final response for an asynchronous fetch operation.
|
/// Interface for observing the final response for an asynchronous fetch operation.
|
||||||
pub trait AsyncFetchListener {
|
pub trait AsyncFetchListener {
|
||||||
fn response_available(&self, response: response::Response);
|
fn response_available(&self, response: response::Response);
|
||||||
|
@ -304,6 +335,7 @@ pub struct PendingAsyncLoad {
|
||||||
context: LoadContext,
|
context: LoadContext,
|
||||||
referrer_policy: Option<ReferrerPolicy>,
|
referrer_policy: Option<ReferrerPolicy>,
|
||||||
referrer_url: Option<Url>,
|
referrer_url: Option<Url>,
|
||||||
|
source: RequestSource
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PendingLoadGuard {
|
struct PendingLoadGuard {
|
||||||
|
@ -324,13 +356,29 @@ impl Drop for PendingLoadGuard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LoadOrigin for PendingAsyncLoad {
|
||||||
|
fn referrer_url(&self) -> Option<Url> {
|
||||||
|
self.referrer_url.clone()
|
||||||
|
}
|
||||||
|
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||||
|
self.referrer_policy.clone()
|
||||||
|
}
|
||||||
|
fn request_source(&self) -> RequestSource {
|
||||||
|
self.source.clone()
|
||||||
|
}
|
||||||
|
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||||
|
self.pipeline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PendingAsyncLoad {
|
impl PendingAsyncLoad {
|
||||||
pub fn new(context: LoadContext,
|
pub fn new(context: LoadContext,
|
||||||
core_resource_thread: CoreResourceThread,
|
core_resource_thread: CoreResourceThread,
|
||||||
url: Url,
|
url: Url,
|
||||||
pipeline: Option<PipelineId>,
|
pipeline: Option<PipelineId>,
|
||||||
referrer_policy: Option<ReferrerPolicy>,
|
referrer_policy: Option<ReferrerPolicy>,
|
||||||
referrer_url: Option<Url>)
|
referrer_url: Option<Url>,
|
||||||
|
source: RequestSource)
|
||||||
-> PendingAsyncLoad {
|
-> PendingAsyncLoad {
|
||||||
PendingAsyncLoad {
|
PendingAsyncLoad {
|
||||||
core_resource_thread: core_resource_thread,
|
core_resource_thread: core_resource_thread,
|
||||||
|
@ -339,14 +387,18 @@ impl PendingAsyncLoad {
|
||||||
guard: PendingLoadGuard { loaded: false, },
|
guard: PendingLoadGuard { loaded: false, },
|
||||||
context: context,
|
context: context,
|
||||||
referrer_policy: referrer_policy,
|
referrer_policy: referrer_policy,
|
||||||
referrer_url: referrer_url
|
referrer_url: referrer_url,
|
||||||
|
source: source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initiate the network request associated with this pending load, using the provided target.
|
/// Initiate the network request associated with this pending load, using the provided target.
|
||||||
pub fn load_async(mut self, listener: AsyncResponseTarget) {
|
pub fn load_async(mut self, listener: AsyncResponseTarget) {
|
||||||
self.guard.neuter();
|
self.guard.neuter();
|
||||||
let load_data = LoadData::new(self.context, self.url, self.pipeline, self.referrer_policy, self.referrer_url);
|
|
||||||
|
let load_data = LoadData::new(self.context.clone(),
|
||||||
|
self.url.clone(),
|
||||||
|
&self);
|
||||||
let consumer = LoadConsumer::Listener(listener);
|
let consumer = LoadConsumer::Listener(listener);
|
||||||
self.core_resource_thread.send(CoreResourceMsg::Load(load_data, consumer, None)).unwrap();
|
self.core_resource_thread.send(CoreResourceMsg::Load(load_data, consumer, None)).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -460,11 +512,11 @@ pub enum ProgressMsg {
|
||||||
pub fn load_whole_resource(context: LoadContext,
|
pub fn load_whole_resource(context: LoadContext,
|
||||||
core_resource_thread: &CoreResourceThread,
|
core_resource_thread: &CoreResourceThread,
|
||||||
url: Url,
|
url: Url,
|
||||||
pipeline_id: Option<PipelineId>)
|
load_origin: &LoadOrigin)
|
||||||
-> Result<(Metadata, Vec<u8>), NetworkError> {
|
-> Result<(Metadata, Vec<u8>), NetworkError> {
|
||||||
let (start_chan, start_port) = ipc::channel().unwrap();
|
let (start_chan, start_port) = ipc::channel().unwrap();
|
||||||
core_resource_thread.send(CoreResourceMsg::Load(LoadData::new(context, url, pipeline_id, None, None),
|
let load_data = LoadData::new(context, url, load_origin);
|
||||||
LoadConsumer::Channel(start_chan), None)).unwrap();
|
core_resource_thread.send(CoreResourceMsg::Load(load_data, LoadConsumer::Channel(start_chan), None)).unwrap();
|
||||||
let response = start_port.recv().unwrap();
|
let response = start_port.recv().unwrap();
|
||||||
|
|
||||||
let mut buf = vec!();
|
let mut buf = vec!();
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
use dom::bindings::js::JS;
|
use dom::bindings::js::JS;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::AsyncResponseTarget;
|
|
||||||
use net_traits::{PendingAsyncLoad, CoreResourceThread, LoadContext};
|
use net_traits::{PendingAsyncLoad, CoreResourceThread, LoadContext};
|
||||||
|
use net_traits::{RequestSource, AsyncResponseTarget};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -130,20 +130,27 @@ impl DocumentLoader {
|
||||||
|
|
||||||
/// Create a new pending network request, which can be initiated at some point in
|
/// Create a new pending network request, which can be initiated at some point in
|
||||||
/// the future.
|
/// the future.
|
||||||
pub fn prepare_async_load(&mut self, load: LoadType, referrer: &Document) -> PendingAsyncLoad {
|
pub fn prepare_async_load(&mut self,
|
||||||
|
load: LoadType,
|
||||||
|
referrer: &Document) -> PendingAsyncLoad {
|
||||||
let context = load.to_load_context();
|
let context = load.to_load_context();
|
||||||
let url = load.url().clone();
|
let url = load.url().clone();
|
||||||
self.add_blocking_load(load);
|
self.add_blocking_load(load);
|
||||||
|
let client_chan = referrer.window().custom_message_chan();
|
||||||
PendingAsyncLoad::new(context,
|
PendingAsyncLoad::new(context,
|
||||||
(*self.resource_thread).clone(),
|
(*self.resource_thread).clone(),
|
||||||
url,
|
url,
|
||||||
self.pipeline,
|
self.pipeline,
|
||||||
referrer.get_referrer_policy(),
|
referrer.get_referrer_policy(),
|
||||||
Some(referrer.url().clone()))
|
Some(referrer.url().clone()),
|
||||||
|
RequestSource::Window(client_chan))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create and initiate a new network request.
|
/// Create and initiate a new network request.
|
||||||
pub fn load_async(&mut self, load: LoadType, listener: AsyncResponseTarget, referrer: &Document) {
|
pub fn load_async(&mut self,
|
||||||
|
load: LoadType,
|
||||||
|
listener: AsyncResponseTarget,
|
||||||
|
referrer: &Document) {
|
||||||
let pending = self.prepare_async_load(load, referrer);
|
let pending = self.prepare_async_load(load, referrer);
|
||||||
pending.load_async(listener)
|
pending.load_async(listener)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ use ipc_channel::ipc::IpcSender;
|
||||||
use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
|
use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
|
||||||
use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
|
use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
|
||||||
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
|
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
|
||||||
use msg::constellation_msg::{PanicMsg, PipelineId};
|
use msg::constellation_msg::{PipelineId, PanicMsg};
|
||||||
use net_traits::CoreResourceThread;
|
use net_traits::{CoreResourceThread, RequestSource};
|
||||||
use profile_traits::{mem, time};
|
use profile_traits::{mem, time};
|
||||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||||
use script_thread::{MainThreadScriptChan, ScriptThread};
|
use script_thread::{MainThreadScriptChan, ScriptThread};
|
||||||
|
@ -65,6 +65,14 @@ impl<'a> GlobalRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// gets the custom message channel associated with global object
|
||||||
|
pub fn request_source(&self) -> RequestSource {
|
||||||
|
match *self {
|
||||||
|
GlobalRef::Window(ref window) => RequestSource::Window(window.custom_message_chan()),
|
||||||
|
GlobalRef::Worker(ref worker) => RequestSource::Worker(worker.custom_message_chan()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the `PipelineId` for this global scope.
|
/// Get the `PipelineId` for this global scope.
|
||||||
pub fn pipeline(&self) -> PipelineId {
|
pub fn pipeline(&self) -> PipelineId {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
|
@ -16,7 +16,8 @@ use dom::bindings::refcounted::LiveDOMReferences;
|
||||||
use dom::bindings::reflector::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::bindings::structuredclone::StructuredCloneData;
|
use dom::bindings::structuredclone::StructuredCloneData;
|
||||||
use dom::messageevent::MessageEvent;
|
use dom::messageevent::MessageEvent;
|
||||||
use dom::worker::{SimpleWorkerErrorHandler, SharedRt, TrustedWorkerAddress, WorkerMessageHandler};
|
use dom::worker::{SimpleWorkerErrorHandler, SharedRt, TrustedWorkerAddress};
|
||||||
|
use dom::worker::{WorkerScriptLoadOrigin, WorkerMessageHandler};
|
||||||
use dom::workerglobalscope::WorkerGlobalScope;
|
use dom::workerglobalscope::WorkerGlobalScope;
|
||||||
use dom::workerglobalscope::WorkerGlobalScopeInit;
|
use dom::workerglobalscope::WorkerGlobalScopeInit;
|
||||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
|
@ -26,7 +27,7 @@ use js::jsapi::{JSAutoCompartment, JSContext, RootedValue};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use net_traits::{LoadContext, load_whole_resource};
|
use net_traits::{LoadContext, load_whole_resource, CustomResponse};
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
|
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
|
||||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
|
||||||
|
@ -133,6 +134,7 @@ enum MixedMessage {
|
||||||
FromWorker((TrustedWorkerAddress, WorkerScriptMsg)),
|
FromWorker((TrustedWorkerAddress, WorkerScriptMsg)),
|
||||||
FromScheduler((TrustedWorkerAddress, TimerEvent)),
|
FromScheduler((TrustedWorkerAddress, TimerEvent)),
|
||||||
FromDevtools(DevtoolScriptControlMsg),
|
FromDevtools(DevtoolScriptControlMsg),
|
||||||
|
FromNetwork(IpcSender<Option<CustomResponse>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dedicatedworkerglobalscope
|
// https://html.spec.whatwg.org/multipage/#dedicatedworkerglobalscope
|
||||||
|
@ -215,18 +217,18 @@ impl DedicatedWorkerGlobalScope {
|
||||||
worker: TrustedWorkerAddress,
|
worker: TrustedWorkerAddress,
|
||||||
parent_sender: Box<ScriptChan + Send>,
|
parent_sender: Box<ScriptChan + Send>,
|
||||||
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
||||||
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>) {
|
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
||||||
|
worker_load_origin: WorkerScriptLoadOrigin) {
|
||||||
let serialized_worker_url = worker_url.to_string();
|
let serialized_worker_url = worker_url.to_string();
|
||||||
let name = format!("WebWorker for {}", serialized_worker_url);
|
let name = format!("WebWorker for {}", serialized_worker_url);
|
||||||
let panic_chan = init.panic_chan.clone();
|
let panic_chan = init.panic_chan.clone();
|
||||||
spawn_named_with_send_on_panic(name, SCRIPT | IN_WORKER, move || {
|
spawn_named_with_send_on_panic(name, SCRIPT | IN_WORKER, move || {
|
||||||
let roots = RootCollection::new();
|
let roots = RootCollection::new();
|
||||||
let _stack_roots_tls = StackRootTLS::new(&roots);
|
let _stack_roots_tls = StackRootTLS::new(&roots);
|
||||||
|
|
||||||
let (url, source) = match load_whole_resource(LoadContext::Script,
|
let (url, source) = match load_whole_resource(LoadContext::Script,
|
||||||
&init.core_resource_thread,
|
&init.core_resource_thread,
|
||||||
worker_url,
|
worker_url,
|
||||||
None) {
|
&worker_load_origin) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("error loading script {}", serialized_worker_url);
|
println!("error loading script {}", serialized_worker_url);
|
||||||
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
|
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
|
||||||
|
@ -316,17 +318,20 @@ impl DedicatedWorkerGlobalScope {
|
||||||
let worker_port = &self.receiver;
|
let worker_port = &self.receiver;
|
||||||
let timer_event_port = &self.timer_event_port;
|
let timer_event_port = &self.timer_event_port;
|
||||||
let devtools_port = scope.from_devtools_receiver();
|
let devtools_port = scope.from_devtools_receiver();
|
||||||
|
let msg_port = scope.custom_message_port();
|
||||||
|
|
||||||
let sel = Select::new();
|
let sel = Select::new();
|
||||||
let mut worker_handle = sel.handle(worker_port);
|
let mut worker_handle = sel.handle(worker_port);
|
||||||
let mut timer_event_handle = sel.handle(timer_event_port);
|
let mut timer_event_handle = sel.handle(timer_event_port);
|
||||||
let mut devtools_handle = sel.handle(devtools_port);
|
let mut devtools_handle = sel.handle(devtools_port);
|
||||||
|
let mut msg_port_handle = sel.handle(msg_port);
|
||||||
unsafe {
|
unsafe {
|
||||||
worker_handle.add();
|
worker_handle.add();
|
||||||
timer_event_handle.add();
|
timer_event_handle.add();
|
||||||
if scope.from_devtools_sender().is_some() {
|
if scope.from_devtools_sender().is_some() {
|
||||||
devtools_handle.add();
|
devtools_handle.add();
|
||||||
}
|
}
|
||||||
|
msg_port_handle.add();
|
||||||
}
|
}
|
||||||
let ret = sel.wait();
|
let ret = sel.wait();
|
||||||
if ret == worker_handle.id() {
|
if ret == worker_handle.id() {
|
||||||
|
@ -335,6 +340,8 @@ impl DedicatedWorkerGlobalScope {
|
||||||
Ok(MixedMessage::FromScheduler(try!(timer_event_port.recv())))
|
Ok(MixedMessage::FromScheduler(try!(timer_event_port.recv())))
|
||||||
} else if ret == devtools_handle.id() {
|
} else if ret == devtools_handle.id() {
|
||||||
Ok(MixedMessage::FromDevtools(try!(devtools_port.recv())))
|
Ok(MixedMessage::FromDevtools(try!(devtools_port.recv())))
|
||||||
|
} else if ret == msg_port_handle.id() {
|
||||||
|
Ok(MixedMessage::FromNetwork(try!(msg_port.recv())))
|
||||||
} else {
|
} else {
|
||||||
panic!("unexpected select result!")
|
panic!("unexpected select result!")
|
||||||
}
|
}
|
||||||
|
@ -397,6 +404,10 @@ impl DedicatedWorkerGlobalScope {
|
||||||
let _ar = AutoWorkerReset::new(self, linked_worker);
|
let _ar = AutoWorkerReset::new(self, linked_worker);
|
||||||
self.handle_script_event(msg);
|
self.handle_script_event(msg);
|
||||||
},
|
},
|
||||||
|
MixedMessage::FromNetwork(network_sender) => {
|
||||||
|
// We send None as of now
|
||||||
|
let _ = network_sender.send(None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1354,7 +1354,7 @@ impl Document {
|
||||||
|
|
||||||
pub fn load_async(&self, load: LoadType, listener: AsyncResponseTarget) {
|
pub fn load_async(&self, load: LoadType, listener: AsyncResponseTarget) {
|
||||||
let mut loader = self.loader.borrow_mut();
|
let mut loader = self.loader.borrow_mut();
|
||||||
loader.load_async(load, listener, self)
|
loader.load_async(load, listener, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish_load(&self, load: LoadType) {
|
pub fn finish_load(&self, load: LoadType) {
|
||||||
|
|
|
@ -47,10 +47,10 @@ use libc;
|
||||||
use msg::constellation_msg::{LoadData, PanicMsg, PipelineId, SubpageId};
|
use msg::constellation_msg::{LoadData, PanicMsg, PipelineId, SubpageId};
|
||||||
use msg::constellation_msg::{WindowSizeData, WindowSizeType};
|
use msg::constellation_msg::{WindowSizeData, WindowSizeType};
|
||||||
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
||||||
use net_traits::ResourceThreads;
|
|
||||||
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
||||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
|
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
|
||||||
use net_traits::storage_thread::StorageType;
|
use net_traits::storage_thread::StorageType;
|
||||||
|
use net_traits::{ResourceThreads, CustomResponseSender};
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use profile_traits::mem;
|
use profile_traits::mem;
|
||||||
use profile_traits::time::{ProfilerCategory, TimerMetadata, TimerMetadataFrameType};
|
use profile_traits::time::{ProfilerCategory, TimerMetadata, TimerMetadataFrameType};
|
||||||
|
@ -150,6 +150,8 @@ pub struct Window {
|
||||||
image_cache_thread: ImageCacheThread,
|
image_cache_thread: ImageCacheThread,
|
||||||
#[ignore_heap_size_of = "channels are hard"]
|
#[ignore_heap_size_of = "channels are hard"]
|
||||||
image_cache_chan: ImageCacheChan,
|
image_cache_chan: ImageCacheChan,
|
||||||
|
#[ignore_heap_size_of = "channels are hard"]
|
||||||
|
custom_message_chan: IpcSender<CustomResponseSender>,
|
||||||
#[ignore_heap_size_of = "TODO(#6911) newtypes containing unmeasurable types are hard"]
|
#[ignore_heap_size_of = "TODO(#6911) newtypes containing unmeasurable types are hard"]
|
||||||
compositor: IpcSender<ScriptToCompositorMsg>,
|
compositor: IpcSender<ScriptToCompositorMsg>,
|
||||||
browsing_context: MutNullableHeap<JS<BrowsingContext>>,
|
browsing_context: MutNullableHeap<JS<BrowsingContext>>,
|
||||||
|
@ -305,6 +307,10 @@ impl Window {
|
||||||
self.image_cache_chan.clone()
|
self.image_cache_chan.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn custom_message_chan(&self) -> IpcSender<CustomResponseSender> {
|
||||||
|
self.custom_message_chan.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_next_worker_id(&self) -> WorkerId {
|
pub fn get_next_worker_id(&self) -> WorkerId {
|
||||||
let worker_id = self.next_worker_id.get();
|
let worker_id = self.next_worker_id.get();
|
||||||
let WorkerId(id_num) = worker_id;
|
let WorkerId(id_num) = worker_id;
|
||||||
|
@ -1442,6 +1448,7 @@ impl Window {
|
||||||
history_task_source: HistoryTraversalTaskSource,
|
history_task_source: HistoryTraversalTaskSource,
|
||||||
file_task_source: FileReadingTaskSource,
|
file_task_source: FileReadingTaskSource,
|
||||||
image_cache_chan: ImageCacheChan,
|
image_cache_chan: ImageCacheChan,
|
||||||
|
custom_message_chan: IpcSender<CustomResponseSender>,
|
||||||
compositor: IpcSender<ScriptToCompositorMsg>,
|
compositor: IpcSender<ScriptToCompositorMsg>,
|
||||||
image_cache_thread: ImageCacheThread,
|
image_cache_thread: ImageCacheThread,
|
||||||
resource_threads: ResourceThreads,
|
resource_threads: ResourceThreads,
|
||||||
|
@ -1479,6 +1486,7 @@ impl Window {
|
||||||
history_traversal_task_source: history_task_source,
|
history_traversal_task_source: history_task_source,
|
||||||
file_reading_task_source: file_task_source,
|
file_reading_task_source: file_task_source,
|
||||||
image_cache_chan: image_cache_chan,
|
image_cache_chan: image_cache_chan,
|
||||||
|
custom_message_chan: custom_message_chan,
|
||||||
console: Default::default(),
|
console: Default::default(),
|
||||||
crypto: Default::default(),
|
crypto: Default::default(),
|
||||||
compositor: compositor,
|
compositor: compositor,
|
||||||
|
|
|
@ -24,10 +24,13 @@ use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
|
||||||
use js::jsapi::{JSAutoCompartment, JS_RequestInterruptCallback};
|
use js::jsapi::{JSAutoCompartment, JS_RequestInterruptCallback};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
|
use net_traits::{RequestSource, LoadOrigin};
|
||||||
use script_thread::Runnable;
|
use script_thread::Runnable;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::mpsc::{Sender, channel};
|
use std::sync::mpsc::{Sender, channel};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use url::Url;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
pub type TrustedWorkerAddress = Trusted<Worker>;
|
pub type TrustedWorkerAddress = Trusted<Worker>;
|
||||||
|
@ -45,6 +48,29 @@ pub struct Worker {
|
||||||
runtime: Arc<Mutex<Option<SharedRt>>>
|
runtime: Arc<Mutex<Option<SharedRt>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct WorkerScriptLoadOrigin {
|
||||||
|
referrer_url: Option<Url>,
|
||||||
|
referrer_policy: Option<ReferrerPolicy>,
|
||||||
|
request_source: RequestSource,
|
||||||
|
pipeline_id: Option<PipelineId>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LoadOrigin for WorkerScriptLoadOrigin {
|
||||||
|
fn referrer_url(&self) -> Option<Url> {
|
||||||
|
self.referrer_url.clone()
|
||||||
|
}
|
||||||
|
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||||
|
self.referrer_policy.clone()
|
||||||
|
}
|
||||||
|
fn request_source(&self) -> RequestSource {
|
||||||
|
self.request_source.clone()
|
||||||
|
}
|
||||||
|
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||||
|
self.pipeline_id.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Worker {
|
impl Worker {
|
||||||
fn new_inherited(sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
fn new_inherited(sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
|
||||||
closing: Arc<AtomicBool>) -> Worker {
|
closing: Arc<AtomicBool>) -> Worker {
|
||||||
|
@ -82,6 +108,13 @@ impl Worker {
|
||||||
let worker_ref = Trusted::new(worker.r());
|
let worker_ref = Trusted::new(worker.r());
|
||||||
let worker_id = global.get_next_worker_id();
|
let worker_id = global.get_next_worker_id();
|
||||||
|
|
||||||
|
let worker_load_origin = WorkerScriptLoadOrigin {
|
||||||
|
referrer_url: None,
|
||||||
|
referrer_policy: None,
|
||||||
|
request_source: global.request_source(),
|
||||||
|
pipeline_id: Some(global.pipeline())
|
||||||
|
};
|
||||||
|
|
||||||
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
|
||||||
let optional_sender = match global.devtools_chan() {
|
let optional_sender = match global.devtools_chan() {
|
||||||
Some(ref chan) => {
|
Some(ref chan) => {
|
||||||
|
@ -114,7 +147,7 @@ impl Worker {
|
||||||
|
|
||||||
DedicatedWorkerGlobalScope::run_worker_scope(
|
DedicatedWorkerGlobalScope::run_worker_scope(
|
||||||
init, worker_url, global.pipeline(), devtools_receiver, worker.runtime.clone(), worker_ref,
|
init, worker_url, global.pipeline(), devtools_receiver, worker.runtime.clone(), worker_ref,
|
||||||
global.script_chan(), sender, receiver);
|
global.script_chan(), sender, receiver, worker_load_origin);
|
||||||
|
|
||||||
Ok(worker)
|
Ok(worker)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,13 @@ use dom::eventtarget::EventTarget;
|
||||||
use dom::window::{base64_atob, base64_btoa};
|
use dom::window::{base64_atob, base64_btoa};
|
||||||
use dom::workerlocation::WorkerLocation;
|
use dom::workerlocation::WorkerLocation;
|
||||||
use dom::workernavigator::WorkerNavigator;
|
use dom::workernavigator::WorkerNavigator;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
|
use ipc_channel::router::ROUTER;
|
||||||
use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
|
use js::jsapi::{HandleValue, JSContext, JSRuntime, RootedValue};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
use msg::constellation_msg::{PanicMsg, PipelineId};
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy, PanicMsg};
|
||||||
use net_traits::{LoadContext, CoreResourceThread, load_whole_resource};
|
use net_traits::{LoadContext, CoreResourceThread, load_whole_resource, RequestSource, LoadOrigin, CustomResponseSender};
|
||||||
use profile_traits::{mem, time};
|
use profile_traits::{mem, time};
|
||||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
|
||||||
use script_traits::ScriptMsg as ConstellationMsg;
|
use script_traits::ScriptMsg as ConstellationMsg;
|
||||||
|
@ -101,6 +102,12 @@ pub struct WorkerGlobalScope {
|
||||||
|
|
||||||
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
||||||
panic_chan: IpcSender<PanicMsg>,
|
panic_chan: IpcSender<PanicMsg>,
|
||||||
|
|
||||||
|
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
||||||
|
custom_msg_chan: IpcSender<CustomResponseSender>,
|
||||||
|
|
||||||
|
#[ignore_heap_size_of = "Defined in std"]
|
||||||
|
custom_msg_port: Receiver<CustomResponseSender>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkerGlobalScope {
|
impl WorkerGlobalScope {
|
||||||
|
@ -110,7 +117,8 @@ impl WorkerGlobalScope {
|
||||||
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
|
||||||
timer_event_chan: IpcSender<TimerEvent>)
|
timer_event_chan: IpcSender<TimerEvent>)
|
||||||
-> WorkerGlobalScope {
|
-> WorkerGlobalScope {
|
||||||
|
let (msg_chan, msg_port) = ipc::channel().unwrap();
|
||||||
|
let custom_msg_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(msg_port);
|
||||||
WorkerGlobalScope {
|
WorkerGlobalScope {
|
||||||
eventtarget: EventTarget::new_inherited(),
|
eventtarget: EventTarget::new_inherited(),
|
||||||
next_worker_id: Cell::new(WorkerId(0)),
|
next_worker_id: Cell::new(WorkerId(0)),
|
||||||
|
@ -133,6 +141,8 @@ impl WorkerGlobalScope {
|
||||||
constellation_chan: init.constellation_chan,
|
constellation_chan: init.constellation_chan,
|
||||||
scheduler_chan: init.scheduler_chan,
|
scheduler_chan: init.scheduler_chan,
|
||||||
panic_chan: init.panic_chan,
|
panic_chan: init.panic_chan,
|
||||||
|
custom_msg_chan: msg_chan,
|
||||||
|
custom_msg_port: custom_msg_port
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +192,14 @@ impl WorkerGlobalScope {
|
||||||
self.runtime.cx()
|
self.runtime.cx()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn custom_message_chan(&self) -> IpcSender<CustomResponseSender> {
|
||||||
|
self.custom_msg_chan.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn custom_message_port(&self) -> &Receiver<CustomResponseSender> {
|
||||||
|
&self.custom_msg_port
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_closing(&self) -> bool {
|
pub fn is_closing(&self) -> bool {
|
||||||
self.closing.load(Ordering::SeqCst)
|
self.closing.load(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
|
@ -210,6 +228,21 @@ impl WorkerGlobalScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LoadOrigin for WorkerGlobalScope {
|
||||||
|
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> {
|
||||||
|
Some(self.pipeline())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
|
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
|
||||||
fn Self_(&self) -> Root<WorkerGlobalScope> {
|
fn Self_(&self) -> Root<WorkerGlobalScope> {
|
||||||
|
@ -236,7 +269,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
||||||
|
|
||||||
let mut rval = RootedValue::new(self.runtime.cx(), UndefinedValue());
|
let mut rval = RootedValue::new(self.runtime.cx(), UndefinedValue());
|
||||||
for url in urls {
|
for url in urls {
|
||||||
let (url, source) = match load_whole_resource(LoadContext::Script, &self.core_resource_thread, url, None) {
|
let (url, source) = match load_whole_resource(LoadContext::Script, &self.core_resource_thread, url, self) {
|
||||||
Err(_) => return Err(Error::Network),
|
Err(_) => return Err(Error::Network),
|
||||||
Ok((metadata, bytes)) => {
|
Ok((metadata, bytes)) => {
|
||||||
(metadata.final_url, String::from_utf8(bytes).unwrap())
|
(metadata.final_url, String::from_utf8(bytes).unwrap())
|
||||||
|
|
|
@ -44,9 +44,10 @@ use ipc_channel::router::ROUTER;
|
||||||
use js::jsapi::JS_ClearPendingException;
|
use js::jsapi::JS_ClearPendingException;
|
||||||
use js::jsapi::{JSContext, JS_ParseJSON, RootedValue};
|
use js::jsapi::{JSContext, JS_ParseJSON, RootedValue};
|
||||||
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||||
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
use net_traits::CoreResourceMsg::Load;
|
use net_traits::CoreResourceMsg::Load;
|
||||||
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError};
|
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError, RequestSource};
|
||||||
use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, CoreResourceThread};
|
use net_traits::{LoadConsumer, LoadContext, LoadData, ResourceCORSData, CoreResourceThread, LoadOrigin};
|
||||||
use network_listener::{NetworkListener, PreInvoke};
|
use network_listener::{NetworkListener, PreInvoke};
|
||||||
use parse::html::{ParseContext, parse_html};
|
use parse::html::{ParseContext, parse_html};
|
||||||
use parse::xml::{self, parse_xml};
|
use parse::xml::{self, parse_xml};
|
||||||
|
@ -295,6 +296,26 @@ impl XMLHttpRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LoadOrigin for XMLHttpRequest {
|
||||||
|
fn referrer_url(&self) -> Option<Url> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
fn request_source(&self) -> RequestSource {
|
||||||
|
if self.sync.get() {
|
||||||
|
RequestSource::None
|
||||||
|
} else {
|
||||||
|
self.global().r().request_source()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||||
|
let global = self.global();
|
||||||
|
Some(global.r().pipeline())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl XMLHttpRequestMethods for XMLHttpRequest {
|
impl XMLHttpRequestMethods for XMLHttpRequest {
|
||||||
// https://xhr.spec.whatwg.org/#handler-xhr-onreadystatechange
|
// https://xhr.spec.whatwg.org/#handler-xhr-onreadystatechange
|
||||||
event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange);
|
event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange);
|
||||||
|
@ -572,14 +593,11 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
||||||
|
|
||||||
// Step 5
|
// Step 5
|
||||||
let global = self.global();
|
let global = self.global();
|
||||||
let pipeline_id = global.r().pipeline();
|
|
||||||
//TODO - set referrer_policy/referrer_url in load_data
|
//TODO - set referrer_policy/referrer_url in load_data
|
||||||
let mut load_data =
|
let mut load_data =
|
||||||
LoadData::new(LoadContext::Browsing,
|
LoadData::new(LoadContext::Browsing,
|
||||||
self.request_url.borrow().clone().unwrap(),
|
self.request_url.borrow().clone().unwrap(),
|
||||||
Some(pipeline_id),
|
self);
|
||||||
None,
|
|
||||||
None);
|
|
||||||
if load_data.url.origin().ne(&global.r().get_url().origin()) {
|
if load_data.url.origin().ne(&global.r().get_url().origin()) {
|
||||||
load_data.credentials_flag = self.WithCredentials();
|
load_data.credentials_flag = self.WithCredentials();
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,8 +65,8 @@ use msg::webdriver_msg::WebDriverScriptCommand;
|
||||||
use net_traits::LoadData as NetLoadData;
|
use net_traits::LoadData as NetLoadData;
|
||||||
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
||||||
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
|
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread};
|
||||||
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata};
|
use net_traits::{AsyncResponseTarget, CoreResourceMsg, LoadConsumer, LoadContext, Metadata, ResourceThreads};
|
||||||
use net_traits::{ResourceThreads, IpcSend};
|
use net_traits::{RequestSource, CustomResponse, CustomResponseSender, IpcSend};
|
||||||
use network_listener::NetworkListener;
|
use network_listener::NetworkListener;
|
||||||
use parse::ParserRoot;
|
use parse::ParserRoot;
|
||||||
use parse::html::{ParseContext, parse_html};
|
use parse::html::{ParseContext, parse_html};
|
||||||
|
@ -205,6 +205,7 @@ enum MixedMessage {
|
||||||
FromDevtools(DevtoolScriptControlMsg),
|
FromDevtools(DevtoolScriptControlMsg),
|
||||||
FromImageCache(ImageCacheResult),
|
FromImageCache(ImageCacheResult),
|
||||||
FromScheduler(TimerEvent),
|
FromScheduler(TimerEvent),
|
||||||
|
FromNetwork(IpcSender<Option<CustomResponse>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Messages used to control the script event loop
|
/// Messages used to control the script event loop
|
||||||
|
@ -321,6 +322,12 @@ pub struct ScriptThread {
|
||||||
/// events in the event queue.
|
/// events in the event queue.
|
||||||
chan: MainThreadScriptChan,
|
chan: MainThreadScriptChan,
|
||||||
|
|
||||||
|
/// A handle to network event messages
|
||||||
|
custom_message_chan: IpcSender<CustomResponseSender>,
|
||||||
|
|
||||||
|
/// The port which receives a sender from the network
|
||||||
|
custom_message_port: Receiver<CustomResponseSender>,
|
||||||
|
|
||||||
dom_manipulation_task_source: DOMManipulationTaskSource,
|
dom_manipulation_task_source: DOMManipulationTaskSource,
|
||||||
|
|
||||||
user_interaction_task_source: UserInteractionTaskSource,
|
user_interaction_task_source: UserInteractionTaskSource,
|
||||||
|
@ -536,6 +543,9 @@ impl ScriptThread {
|
||||||
let (ipc_devtools_sender, ipc_devtools_receiver) = ipc::channel().unwrap();
|
let (ipc_devtools_sender, ipc_devtools_receiver) = ipc::channel().unwrap();
|
||||||
let devtools_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_devtools_receiver);
|
let devtools_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_devtools_receiver);
|
||||||
|
|
||||||
|
let (ipc_custom_resp_chan, ipc_custom_resp_port) = ipc::channel().unwrap();
|
||||||
|
let custom_msg_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_custom_resp_port);
|
||||||
|
|
||||||
// Ask the router to proxy IPC messages from the image cache thread to us.
|
// Ask the router to proxy IPC messages from the image cache thread to us.
|
||||||
let (ipc_image_cache_channel, ipc_image_cache_port) = ipc::channel().unwrap();
|
let (ipc_image_cache_channel, ipc_image_cache_port) = ipc::channel().unwrap();
|
||||||
let image_cache_port =
|
let image_cache_port =
|
||||||
|
@ -558,6 +568,9 @@ impl ScriptThread {
|
||||||
bluetooth_thread: state.bluetooth_thread,
|
bluetooth_thread: state.bluetooth_thread,
|
||||||
|
|
||||||
port: port,
|
port: port,
|
||||||
|
custom_message_chan: ipc_custom_resp_chan,
|
||||||
|
custom_message_port: custom_msg_port,
|
||||||
|
|
||||||
chan: MainThreadScriptChan(chan.clone()),
|
chan: MainThreadScriptChan(chan.clone()),
|
||||||
dom_manipulation_task_source: DOMManipulationTaskSource(chan.clone()),
|
dom_manipulation_task_source: DOMManipulationTaskSource(chan.clone()),
|
||||||
user_interaction_task_source: UserInteractionTaskSource(chan.clone()),
|
user_interaction_task_source: UserInteractionTaskSource(chan.clone()),
|
||||||
|
@ -619,7 +632,8 @@ impl ScriptThread {
|
||||||
|
|
||||||
/// Handle incoming control messages.
|
/// Handle incoming control messages.
|
||||||
fn handle_msgs(&self) -> bool {
|
fn handle_msgs(&self) -> bool {
|
||||||
use self::MixedMessage::{FromScript, FromConstellation, FromScheduler, FromDevtools, FromImageCache};
|
use self::MixedMessage::{FromConstellation, FromDevtools, FromImageCache};
|
||||||
|
use self::MixedMessage::{FromScheduler, FromScript, FromNetwork};
|
||||||
|
|
||||||
// Handle pending resize events.
|
// Handle pending resize events.
|
||||||
// Gather them first to avoid a double mut borrow on self.
|
// Gather them first to avoid a double mut borrow on self.
|
||||||
|
@ -653,6 +667,7 @@ impl ScriptThread {
|
||||||
let mut timer_event_port = sel.handle(&self.timer_event_port);
|
let mut timer_event_port = sel.handle(&self.timer_event_port);
|
||||||
let mut devtools_port = sel.handle(&self.devtools_port);
|
let mut devtools_port = sel.handle(&self.devtools_port);
|
||||||
let mut image_cache_port = sel.handle(&self.image_cache_port);
|
let mut image_cache_port = sel.handle(&self.image_cache_port);
|
||||||
|
let mut custom_message_port = sel.handle(&self.custom_message_port);
|
||||||
unsafe {
|
unsafe {
|
||||||
script_port.add();
|
script_port.add();
|
||||||
control_port.add();
|
control_port.add();
|
||||||
|
@ -661,6 +676,7 @@ impl ScriptThread {
|
||||||
devtools_port.add();
|
devtools_port.add();
|
||||||
}
|
}
|
||||||
image_cache_port.add();
|
image_cache_port.add();
|
||||||
|
custom_message_port.add();
|
||||||
}
|
}
|
||||||
let ret = sel.wait();
|
let ret = sel.wait();
|
||||||
if ret == script_port.id() {
|
if ret == script_port.id() {
|
||||||
|
@ -673,6 +689,8 @@ impl ScriptThread {
|
||||||
FromDevtools(self.devtools_port.recv().unwrap())
|
FromDevtools(self.devtools_port.recv().unwrap())
|
||||||
} else if ret == image_cache_port.id() {
|
} else if ret == image_cache_port.id() {
|
||||||
FromImageCache(self.image_cache_port.recv().unwrap())
|
FromImageCache(self.image_cache_port.recv().unwrap())
|
||||||
|
} else if ret == custom_message_port.id() {
|
||||||
|
FromNetwork(self.custom_message_port.recv().unwrap())
|
||||||
} else {
|
} else {
|
||||||
panic!("unexpected select result")
|
panic!("unexpected select result")
|
||||||
}
|
}
|
||||||
|
@ -735,7 +753,10 @@ impl ScriptThread {
|
||||||
Err(_) => match self.timer_event_port.try_recv() {
|
Err(_) => match self.timer_event_port.try_recv() {
|
||||||
Err(_) => match self.devtools_port.try_recv() {
|
Err(_) => match self.devtools_port.try_recv() {
|
||||||
Err(_) => match self.image_cache_port.try_recv() {
|
Err(_) => match self.image_cache_port.try_recv() {
|
||||||
Err(_) => break,
|
Err(_) => match self.custom_message_port.try_recv() {
|
||||||
|
Err(_) => break,
|
||||||
|
Ok(ev) => event = FromNetwork(ev)
|
||||||
|
},
|
||||||
Ok(ev) => event = FromImageCache(ev),
|
Ok(ev) => event = FromImageCache(ev),
|
||||||
},
|
},
|
||||||
Ok(ev) => event = FromDevtools(ev),
|
Ok(ev) => event = FromDevtools(ev),
|
||||||
|
@ -761,6 +782,7 @@ impl ScriptThread {
|
||||||
},
|
},
|
||||||
FromConstellation(inner_msg) => self.handle_msg_from_constellation(inner_msg),
|
FromConstellation(inner_msg) => self.handle_msg_from_constellation(inner_msg),
|
||||||
FromScript(inner_msg) => self.handle_msg_from_script(inner_msg),
|
FromScript(inner_msg) => self.handle_msg_from_script(inner_msg),
|
||||||
|
FromNetwork(inner_msg) => self.handle_msg_from_network(inner_msg),
|
||||||
FromScheduler(inner_msg) => self.handle_timer_event(inner_msg),
|
FromScheduler(inner_msg) => self.handle_timer_event(inner_msg),
|
||||||
FromDevtools(inner_msg) => self.handle_msg_from_devtools(inner_msg),
|
FromDevtools(inner_msg) => self.handle_msg_from_devtools(inner_msg),
|
||||||
FromImageCache(inner_msg) => self.handle_msg_from_image_cache(inner_msg),
|
FromImageCache(inner_msg) => self.handle_msg_from_image_cache(inner_msg),
|
||||||
|
@ -820,6 +842,7 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MixedMessage::FromScheduler(_) => ScriptThreadEventCategory::TimerEvent,
|
MixedMessage::FromScheduler(_) => ScriptThreadEventCategory::TimerEvent,
|
||||||
|
MixedMessage::FromNetwork(_) => ScriptThreadEventCategory::NetworkEvent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,6 +1012,12 @@ impl ScriptThread {
|
||||||
msg.responder.unwrap().respond(msg.image_response);
|
msg.responder.unwrap().respond(msg.image_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_msg_from_network(&self, msg: IpcSender<Option<CustomResponse>>) {
|
||||||
|
// We may detect controlling service workers here
|
||||||
|
// We send None as default
|
||||||
|
let _ = msg.send(None);
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) {
|
fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) {
|
||||||
let context = self.root_browsing_context();
|
let context = self.root_browsing_context();
|
||||||
match msg {
|
match msg {
|
||||||
|
@ -1437,6 +1466,7 @@ impl ScriptThread {
|
||||||
HistoryTraversalTaskSource(history_sender.clone()),
|
HistoryTraversalTaskSource(history_sender.clone()),
|
||||||
FileReadingTaskSource(file_sender.clone()),
|
FileReadingTaskSource(file_sender.clone()),
|
||||||
self.image_cache_channel.clone(),
|
self.image_cache_channel.clone(),
|
||||||
|
self.custom_message_chan.clone(),
|
||||||
self.compositor.borrow_mut().clone(),
|
self.compositor.borrow_mut().clone(),
|
||||||
self.image_cache_thread.clone(),
|
self.image_cache_thread.clone(),
|
||||||
self.resource_threads.clone(),
|
self.resource_threads.clone(),
|
||||||
|
@ -1905,6 +1935,7 @@ impl ScriptThread {
|
||||||
credentials_flag: true,
|
credentials_flag: true,
|
||||||
referrer_policy: load_data.referrer_policy,
|
referrer_policy: load_data.referrer_policy,
|
||||||
referrer_url: load_data.referrer_url,
|
referrer_url: load_data.referrer_url,
|
||||||
|
source: RequestSource::Window(self.custom_message_chan.clone())
|
||||||
}, LoadConsumer::Listener(response_target), None)).unwrap();
|
}, LoadConsumer::Listener(response_target), None)).unwrap();
|
||||||
|
|
||||||
self.incomplete_loads.borrow_mut().push(incomplete);
|
self.incomplete_loads.borrow_mut().push(incomplete);
|
||||||
|
|
|
@ -5,11 +5,30 @@
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
use net_traits::LoadConsumer::Channel;
|
use net_traits::LoadConsumer::Channel;
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use net_traits::{LoadData, LoadContext, NetworkError};
|
use net_traits::{LoadData, LoadContext, NetworkError, LoadOrigin, RequestSource};
|
||||||
use self::hyper::header::ContentType;
|
use self::hyper::header::ContentType;
|
||||||
use self::hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};
|
use self::hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
struct DataLoadTest;
|
||||||
|
|
||||||
|
impl LoadOrigin for DataLoadTest {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn assert_parse(url: &'static str,
|
fn assert_parse(url: &'static str,
|
||||||
|
@ -20,11 +39,10 @@ fn assert_parse(url: &'static str,
|
||||||
use net::mime_classifier::MIMEClassifier;
|
use net::mime_classifier::MIMEClassifier;
|
||||||
use net::resource_thread::CancellationListener;
|
use net::resource_thread::CancellationListener;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
let (start_chan, start_port) = ipc::channel().unwrap();
|
let (start_chan, start_port) = ipc::channel().unwrap();
|
||||||
let classifier = Arc::new(MIMEClassifier::new());
|
let classifier = Arc::new(MIMEClassifier::new());
|
||||||
load(LoadData::new(LoadContext::Browsing, Url::parse(url).unwrap(), None, None, None),
|
load(LoadData::new(LoadContext::Browsing, Url::parse(url).unwrap(), &DataLoadTest),
|
||||||
Channel(start_chan),
|
Channel(start_chan),
|
||||||
classifier, CancellationListener::new(None));
|
classifier, CancellationListener::new(None));
|
||||||
|
|
||||||
|
|
|
@ -20,19 +20,58 @@ use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
use net::cookie::Cookie;
|
use net::cookie::Cookie;
|
||||||
use net::cookie_storage::CookieStorage;
|
use net::cookie_storage::CookieStorage;
|
||||||
use net::hsts::HstsEntry;
|
use net::hsts::HstsEntry;
|
||||||
use net::http_loader::LoadErrorType;
|
use net::http_loader::{LoadErrorType, HttpResponse};
|
||||||
use net::http_loader::{load, LoadError, HttpRequestFactory, HttpRequest, HttpResponse, UIProvider, HttpState};
|
use net::http_loader::{load, LoadError, HttpRequestFactory, HttpRequest, UIProvider, HttpState};
|
||||||
use net::resource_thread::{AuthCacheEntry, CancellationListener};
|
use net::resource_thread::{AuthCacheEntry, CancellationListener};
|
||||||
|
use net_traits::{CustomResponse, RequestSource, Metadata, LoadOrigin};
|
||||||
use net_traits::{LoadData, CookieSource, LoadContext, IncludeSubdomains};
|
use net_traits::{LoadData, CookieSource, LoadContext, IncludeSubdomains};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::io::{self, Write, Read, Cursor};
|
use std::io::{self, Write, Read, Cursor};
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use std::sync::{Arc, mpsc, RwLock};
|
use std::sync::{Arc, mpsc, RwLock};
|
||||||
|
use std::thread;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::prefs;
|
use util::prefs;
|
||||||
|
|
||||||
const DEFAULT_USER_AGENT: &'static str = "Test-agent";
|
const DEFAULT_USER_AGENT: &'static str = "Test-agent";
|
||||||
|
|
||||||
|
struct HttpTest;
|
||||||
|
|
||||||
|
impl LoadOrigin for HttpTest {
|
||||||
|
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> {
|
||||||
|
Some(PipelineId::fake_root_pipeline_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LoadOriginInfo<'a> {
|
||||||
|
referrer_url: &'a str,
|
||||||
|
referrer_policy: Option<ReferrerPolicy>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LoadOrigin for LoadOriginInfo<'a> {
|
||||||
|
fn referrer_url(&self) -> Option<Url> {
|
||||||
|
Some(Url::parse(self.referrer_url).unwrap())
|
||||||
|
}
|
||||||
|
fn referrer_policy(&self) -> Option<ReferrerPolicy> {
|
||||||
|
self.referrer_policy.clone()
|
||||||
|
}
|
||||||
|
fn request_source(&self) -> RequestSource {
|
||||||
|
RequestSource::None
|
||||||
|
}
|
||||||
|
fn pipeline_id(&self) -> Option<PipelineId> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn respond_with(body: Vec<u8>) -> MockResponse {
|
fn respond_with(body: Vec<u8>) -> MockResponse {
|
||||||
let headers = Headers::new();
|
let headers = Headers::new();
|
||||||
respond_with_headers(body, headers)
|
respond_with_headers(body, headers)
|
||||||
|
@ -135,12 +174,27 @@ fn redirect_with_headers(host: String, mut headers: Headers) -> MockResponse {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Source {
|
||||||
|
Window,
|
||||||
|
Worker
|
||||||
|
}
|
||||||
|
|
||||||
|
fn respond_404() -> MockResponse {
|
||||||
|
MockResponse::new(
|
||||||
|
Headers::new(),
|
||||||
|
StatusCode::NotFound,
|
||||||
|
RawStatus(404, Cow::Borrowed("Not Found")),
|
||||||
|
b"".to_vec()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
enum ResponseType {
|
enum ResponseType {
|
||||||
Redirect(String),
|
Redirect(String),
|
||||||
RedirectWithHeaders(String, Headers),
|
RedirectWithHeaders(String, Headers),
|
||||||
Text(Vec<u8>),
|
Text(Vec<u8>),
|
||||||
WithHeaders(Vec<u8>, Headers),
|
WithHeaders(Vec<u8>, Headers),
|
||||||
NeedsAuth(Headers),
|
NeedsAuth(Headers),
|
||||||
|
Dummy404
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MockRequest {
|
struct MockRequest {
|
||||||
|
@ -169,6 +223,9 @@ fn response_for_request_type(t: ResponseType) -> Result<MockResponse, LoadError>
|
||||||
},
|
},
|
||||||
ResponseType::NeedsAuth(h) => {
|
ResponseType::NeedsAuth(h) => {
|
||||||
Ok(basic_auth(h))
|
Ok(basic_auth(h))
|
||||||
|
},
|
||||||
|
ResponseType::Dummy404 => {
|
||||||
|
Ok(respond_404())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,7 +387,7 @@ fn test_check_default_headers_loaded_in_every_request() {
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
load_data.data = None;
|
load_data.data = None;
|
||||||
load_data.method = Method::Get;
|
load_data.method = Method::Get;
|
||||||
|
|
||||||
|
@ -374,7 +431,7 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
load_data.data = None;
|
load_data.data = None;
|
||||||
load_data.method = Method::Post;
|
load_data.method = Method::Post;
|
||||||
|
|
||||||
|
@ -412,7 +469,7 @@ fn test_request_and_response_data_with_network_messages() {
|
||||||
let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
|
let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
|
||||||
// This will probably have to be changed as it uses fake_root_pipeline_id which is marked for removal.
|
// This will probably have to be changed as it uses fake_root_pipeline_id which is marked for removal.
|
||||||
let pipeline_id = PipelineId::fake_root_pipeline_id();
|
let pipeline_id = PipelineId::fake_root_pipeline_id();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), Some(pipeline_id), None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
let mut request_headers = Headers::new();
|
let mut request_headers = Headers::new();
|
||||||
request_headers.set(Host { hostname: "bar.foo".to_owned(), port: None });
|
request_headers.set(Host { hostname: "bar.foo".to_owned(), port: None });
|
||||||
load_data.headers = request_headers.clone();
|
load_data.headers = request_headers.clone();
|
||||||
|
@ -464,6 +521,22 @@ fn test_request_and_response_data_with_network_messages() {
|
||||||
assert_eq!(devhttpresponse, httpresponse);
|
assert_eq!(devhttpresponse, httpresponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct HttpTestNoPipeline;
|
||||||
|
impl LoadOrigin for HttpTestNoPipeline {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_request_and_response_message_from_devtool_without_pipeline_id() {
|
fn test_request_and_response_message_from_devtool_without_pipeline_id() {
|
||||||
struct Factory;
|
struct Factory;
|
||||||
|
@ -485,7 +558,7 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() {
|
||||||
|
|
||||||
let url = Url::parse("https://mozilla.com").unwrap();
|
let url = Url::parse("https://mozilla.com").unwrap();
|
||||||
let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
|
let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTestNoPipeline);
|
||||||
let _ = load(&load_data, &ui_provider, &http_state, Some(devtools_chan), &Factory,
|
let _ = load(&load_data, &ui_provider, &http_state, Some(devtools_chan), &Factory,
|
||||||
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
|
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
|
||||||
|
|
||||||
|
@ -514,7 +587,7 @@ fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
load_data.method = Method::Post;
|
load_data.method = Method::Post;
|
||||||
|
|
||||||
|
@ -544,7 +617,7 @@ fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_co
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -578,7 +651,7 @@ fn test_load_should_decode_the_response_as_gzip_when_response_headers_have_conte
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -621,7 +694,7 @@ fn test_load_doesnt_send_request_body_on_any_redirect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
load_data.data = Some(<[_]>::to_vec("Body on POST!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Body on POST!".as_bytes()));
|
||||||
|
|
||||||
|
@ -653,7 +726,7 @@ fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_ar
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -685,7 +758,7 @@ fn test_load_adds_host_to_sts_list_when_url_is_https_and_sts_headers_are_present
|
||||||
|
|
||||||
let url = Url::parse("https://mozilla.com").unwrap();
|
let url = Url::parse("https://mozilla.com").unwrap();
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -722,7 +795,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_
|
||||||
|
|
||||||
assert_cookie_for_domain(http_state.cookie_jar.clone(), "http://mozilla.com", "");
|
assert_cookie_for_domain(http_state.cookie_jar.clone(), "http://mozilla.com", "");
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let _ = load(&load_data,
|
let _ = load(&load_data,
|
||||||
&ui_provider, &http_state,
|
&ui_provider, &http_state,
|
||||||
|
@ -738,7 +811,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_
|
||||||
fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_resource_manager() {
|
fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_resource_manager() {
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
|
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
|
@ -794,7 +867,7 @@ fn test_load_sends_secure_cookie_if_http_changed_to_https_due_to_entry_in_hsts_s
|
||||||
cookie_jar.push(cookie, CookieSource::HTTP);
|
cookie_jar.push(cookie, CookieSource::HTTP);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url, &HttpTest);
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
|
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
|
@ -826,7 +899,7 @@ fn test_load_sends_cookie_if_nonhttp() {
|
||||||
cookie_jar.push(cookie, CookieSource::HTTP);
|
cookie_jar.push(cookie, CookieSource::HTTP);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url, &HttpTest);
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
|
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
|
@ -860,7 +933,7 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl(
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
let _ = load(&load_data,
|
let _ = load(&load_data,
|
||||||
&ui_provider, &http_state,
|
&ui_provider, &http_state,
|
||||||
None,
|
None,
|
||||||
|
@ -890,7 +963,7 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() {
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, Url::parse("http://mozilla.com").unwrap(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, Url::parse("http://mozilla.com").unwrap(), &HttpTest);
|
||||||
let _ = load(&load_data,
|
let _ = load(&load_data,
|
||||||
&ui_provider, &http_state,
|
&ui_provider, &http_state,
|
||||||
None,
|
None,
|
||||||
|
@ -921,7 +994,7 @@ fn test_when_cookie_set_marked_httpsonly_secure_isnt_sent_on_http_request() {
|
||||||
cookie_jar.push(cookie, CookieSource::HTTP);
|
cookie_jar.push(cookie, CookieSource::HTTP);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url, &HttpTest);
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
|
|
||||||
assert_cookie_for_domain(http_state.cookie_jar.clone(), "https://mozilla.com", "mozillaIs=theBest");
|
assert_cookie_for_domain(http_state.cookie_jar.clone(), "https://mozilla.com", "mozillaIs=theBest");
|
||||||
|
@ -939,7 +1012,7 @@ fn test_load_sets_content_length_to_length_of_request_body() {
|
||||||
let content = "This is a request body";
|
let content = "This is a request body";
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
load_data.data = Some(<[_]>::to_vec(content.as_bytes()));
|
load_data.data = Some(<[_]>::to_vec(content.as_bytes()));
|
||||||
|
|
||||||
|
@ -965,7 +1038,7 @@ fn test_load_uses_explicit_accept_from_headers_in_load_data() {
|
||||||
accept_headers.set(Accept(vec![text_html.clone()]));
|
accept_headers.set(Accept(vec![text_html.clone()]));
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
load_data.headers.set(Accept(vec![text_html.clone()]));
|
load_data.headers.set(Accept(vec![text_html.clone()]));
|
||||||
|
@ -994,7 +1067,7 @@ fn test_load_sets_default_accept_to_html_xhtml_xml_and_then_anything_else() {
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
|
|
||||||
|
@ -1017,7 +1090,7 @@ fn test_load_uses_explicit_accept_encoding_from_load_data_headers() {
|
||||||
accept_encoding_headers.set(AcceptEncoding(vec![qitem(Encoding::Chunked)]));
|
accept_encoding_headers.set(AcceptEncoding(vec![qitem(Encoding::Chunked)]));
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
load_data.headers.set(AcceptEncoding(vec![qitem(Encoding::Chunked)]));
|
load_data.headers.set(AcceptEncoding(vec![qitem(Encoding::Chunked)]));
|
||||||
|
|
||||||
|
@ -1042,7 +1115,7 @@ fn test_load_sets_default_accept_encoding_to_gzip_and_deflate() {
|
||||||
qitem(Encoding::EncodingExt("br".to_owned()))]));
|
qitem(Encoding::EncodingExt("br".to_owned()))]));
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
|
@ -1077,7 +1150,7 @@ fn test_load_errors_when_there_a_redirect_loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -1106,7 +1179,7 @@ fn test_load_errors_when_there_is_too_many_redirects() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -1153,7 +1226,7 @@ fn test_load_follows_a_redirect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = Url::parse("http://mozilla.com").unwrap();
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
|
@ -1180,7 +1253,7 @@ impl HttpRequestFactory for DontConnectFactory {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_load_errors_when_scheme_is_not_http_or_https() {
|
fn test_load_errors_when_scheme_is_not_http_or_https() {
|
||||||
let url = Url::parse("ftp://not-supported").unwrap();
|
let url = Url::parse("ftp://not-supported").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -1199,7 +1272,7 @@ fn test_load_errors_when_scheme_is_not_http_or_https() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_load_errors_when_viewing_source_and_inner_url_scheme_is_not_http_or_https() {
|
fn test_load_errors_when_viewing_source_and_inner_url_scheme_is_not_http_or_https() {
|
||||||
let url = Url::parse("view-source:ftp://not-supported").unwrap();
|
let url = Url::parse("view-source:ftp://not-supported").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -1242,7 +1315,7 @@ fn test_load_errors_when_cancelled() {
|
||||||
cancel_sender.send(()).unwrap();
|
cancel_sender.send(()).unwrap();
|
||||||
|
|
||||||
let url = Url::parse("https://mozilla.com").unwrap();
|
let url = Url::parse("https://mozilla.com").unwrap();
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
|
@ -1291,7 +1364,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url_x.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url_x.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -1357,7 +1430,7 @@ fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
@ -1390,7 +1463,7 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() {
|
||||||
|
|
||||||
http_state.auth_cache.write().unwrap().entries.insert(url.clone(), auth_entry);
|
http_state.auth_cache.write().unwrap().entries.insert(url.clone(), auth_entry);
|
||||||
|
|
||||||
let mut load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
let mut load_data = LoadData::new(LoadContext::Browsing, url, &HttpTest);
|
||||||
load_data.credentials_flag = true;
|
load_data.credentials_flag = true;
|
||||||
|
|
||||||
let mut auth_header = Headers::new();
|
let mut auth_header = Headers::new();
|
||||||
|
@ -1429,7 +1502,7 @@ fn test_auth_ui_sets_header_on_401() {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url, &HttpTest);
|
||||||
|
|
||||||
match load(
|
match load(
|
||||||
&load_data, &ui_provider, &http_state,
|
&load_data, &ui_provider, &http_state,
|
||||||
|
@ -1465,7 +1538,7 @@ fn test_auth_ui_needs_www_auth() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
let load_data = LoadData::new(LoadContext::Browsing, url, &HttpTest);
|
||||||
|
|
||||||
let response = load(&load_data, &AuthProvider, &http_state,
|
let response = load(&load_data, &AuthProvider, &http_state,
|
||||||
None, &Factory, DEFAULT_USER_AGENT.to_owned(),
|
None, &Factory, DEFAULT_USER_AGENT.to_owned(),
|
||||||
|
@ -1478,19 +1551,15 @@ fn test_auth_ui_needs_www_auth() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_referer_header_matches(request_url: &str,
|
fn assert_referer_header_matches(origin_info: &LoadOrigin,
|
||||||
referrer_url: &str,
|
request_url: &str,
|
||||||
referrer_policy: Option<ReferrerPolicy>,
|
|
||||||
expected_referrer: &str) {
|
expected_referrer: &str) {
|
||||||
let ref_url = Url::parse(referrer_url).unwrap();
|
|
||||||
let url = Url::parse(request_url).unwrap();
|
let url = Url::parse(request_url).unwrap();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing,
|
let load_data = LoadData::new(LoadContext::Browsing,
|
||||||
url.clone(),
|
url.clone(),
|
||||||
None,
|
origin_info);
|
||||||
referrer_policy,
|
|
||||||
Some(ref_url));
|
|
||||||
|
|
||||||
let mut referer_headers = Headers::new();
|
let mut referer_headers = Headers::new();
|
||||||
referer_headers.set(Referer(expected_referrer.to_owned()));
|
referer_headers.set(Referer(expected_referrer.to_owned()));
|
||||||
|
@ -1505,16 +1574,13 @@ fn assert_referer_header_matches(request_url: &str,
|
||||||
&CancellationListener::new(None));
|
&CancellationListener::new(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_referer_header_not_included(request_url: &str, referrer_url: &str, referrer_policy: Option<ReferrerPolicy>) {
|
fn assert_referer_header_not_included(origin_info: &LoadOrigin, request_url: &str) {
|
||||||
let ref_url = Url::parse(referrer_url).unwrap();
|
|
||||||
let url = Url::parse(request_url).unwrap();
|
let url = Url::parse(request_url).unwrap();
|
||||||
let ui_provider = TestProvider::new();
|
let ui_provider = TestProvider::new();
|
||||||
|
|
||||||
let load_data = LoadData::new(LoadContext::Browsing,
|
let load_data = LoadData::new(LoadContext::Browsing,
|
||||||
url.clone(),
|
url.clone(),
|
||||||
None,
|
origin_info);
|
||||||
referrer_policy,
|
|
||||||
Some(ref_url));
|
|
||||||
|
|
||||||
let http_state = HttpState::new();
|
let http_state = HttpState::new();
|
||||||
|
|
||||||
|
@ -1533,17 +1599,27 @@ fn test_referer_set_to_origin_with_originonly_policy() {
|
||||||
let referrer_policy = Some(ReferrerPolicy::OriginOnly);
|
let referrer_policy = Some(ReferrerPolicy::OriginOnly);
|
||||||
let expected_referrer = "http://someurl.com/";
|
let expected_referrer = "http://someurl.com/";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_referer_set_to_stripped_url_with_unsafeurl_policy() {
|
fn test_referer_set_to_stripped_url_with_unsafeurl_policy() {
|
||||||
|
|
||||||
let request_url = "http://mozilla.com";
|
let request_url = "http://mozilla.com";
|
||||||
let referrer_url = "http://username:password@someurl.com/some/path#fragment";
|
let referrer_url = "http://username:password@someurl.com/some/path#fragment";
|
||||||
let referrer_policy = Some(ReferrerPolicy::UnsafeUrl);
|
let referrer_policy = Some(ReferrerPolicy::UnsafeUrl);
|
||||||
let expected_referrer = "http://someurl.com/some/path";
|
let expected_referrer = "http://someurl.com/some/path";
|
||||||
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1553,7 +1629,12 @@ fn test_referer_with_originwhencrossorigin_policy_cross_orig() {
|
||||||
let referrer_policy = Some(ReferrerPolicy::OriginWhenCrossOrigin);
|
let referrer_policy = Some(ReferrerPolicy::OriginWhenCrossOrigin);
|
||||||
let expected_referrer = "http://someurl.com/";
|
let expected_referrer = "http://someurl.com/";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1563,7 +1644,12 @@ fn test_referer_with_originwhencrossorigin_policy_same_orig() {
|
||||||
let referrer_policy = Some(ReferrerPolicy::OriginWhenCrossOrigin);
|
let referrer_policy = Some(ReferrerPolicy::OriginWhenCrossOrigin);
|
||||||
let expected_referrer = "http://mozilla.com/some/path";
|
let expected_referrer = "http://mozilla.com/some/path";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1573,7 +1659,12 @@ fn test_http_to_https_considered_cross_origin_for_referer_header_logic() {
|
||||||
let referrer_policy = Some(ReferrerPolicy::OriginWhenCrossOrigin);
|
let referrer_policy = Some(ReferrerPolicy::OriginWhenCrossOrigin);
|
||||||
let expected_referrer = "http://mozilla.com/";
|
let expected_referrer = "http://mozilla.com/";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1583,7 +1674,12 @@ fn test_referer_set_to_ref_url_with_noreferrerwhendowngrade_policy_https_to_http
|
||||||
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
||||||
let expected_referrer = "https://mozilla.com/some/path";
|
let expected_referrer = "https://mozilla.com/some/path";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1592,7 +1688,12 @@ fn test_no_referer_set_with_noreferrerwhendowngrade_policy_https_to_http() {
|
||||||
let referrer_url = "https://username:password@mozilla.com/some/path#fragment";
|
let referrer_url = "https://username:password@mozilla.com/some/path#fragment";
|
||||||
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
||||||
|
|
||||||
assert_referer_header_not_included(request_url, referrer_url, referrer_policy)
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_not_included(&origin_info, request_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1602,7 +1703,12 @@ fn test_referer_set_to_ref_url_with_noreferrerwhendowngrade_policy_http_to_https
|
||||||
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
||||||
let expected_referrer = "http://mozilla.com/some/path";
|
let expected_referrer = "http://mozilla.com/some/path";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1612,7 +1718,12 @@ fn test_referer_set_to_ref_url_with_noreferrerwhendowngrade_policy_http_to_http(
|
||||||
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
let referrer_policy = Some(ReferrerPolicy::NoRefWhenDowngrade);
|
||||||
let expected_referrer = "http://mozilla.com/some/path";
|
let expected_referrer = "http://mozilla.com/some/path";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1622,7 +1733,12 @@ fn test_no_referrer_policy_follows_noreferrerwhendowngrade_https_to_https() {
|
||||||
let referrer_policy = None;
|
let referrer_policy = None;
|
||||||
let expected_referrer = "https://mozilla.com/some/path";
|
let expected_referrer = "https://mozilla.com/some/path";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1631,7 +1747,12 @@ fn test_no_referrer_policy_follows_noreferrerwhendowngrade_https_to_http() {
|
||||||
let referrer_url = "https://username:password@mozilla.com/some/path#fragment";
|
let referrer_url = "https://username:password@mozilla.com/some/path#fragment";
|
||||||
let referrer_policy = None;
|
let referrer_policy = None;
|
||||||
|
|
||||||
assert_referer_header_not_included(request_url, referrer_url, referrer_policy);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_not_included(&origin_info, request_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1641,7 +1762,12 @@ fn test_no_referrer_policy_follows_noreferrerwhendowngrade_http_to_https() {
|
||||||
let referrer_policy = None;
|
let referrer_policy = None;
|
||||||
let expected_referrer = "http://mozilla.com/some/path";
|
let expected_referrer = "http://mozilla.com/some/path";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1651,14 +1777,87 @@ fn test_no_referrer_policy_follows_noreferrerwhendowngrade_http_to_http() {
|
||||||
let referrer_policy = None;
|
let referrer_policy = None;
|
||||||
let expected_referrer = "http://mozilla.com/some/path";
|
let expected_referrer = "http://mozilla.com/some/path";
|
||||||
|
|
||||||
assert_referer_header_matches(request_url, referrer_url, referrer_policy, expected_referrer);
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_matches(&origin_info, request_url, expected_referrer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_no_referer_set_with_noreferrer_policy() {
|
fn test_no_referer_set_with_noreferrer_policy() {
|
||||||
|
|
||||||
let request_url = "http://mozilla.com";
|
let request_url = "http://mozilla.com";
|
||||||
let referrer_url = "http://someurl.com";
|
let referrer_url = "http://someurl.com";
|
||||||
let referrer_policy = Some(ReferrerPolicy::NoReferrer);
|
let referrer_policy = Some(ReferrerPolicy::NoReferrer);
|
||||||
|
|
||||||
assert_referer_header_not_included(request_url, referrer_url, referrer_policy)
|
let origin_info = LoadOriginInfo {
|
||||||
|
referrer_url: referrer_url,
|
||||||
|
referrer_policy: referrer_policy,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_referer_header_not_included(&origin_info, request_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_request_with_source(source: Source, expected_body: Vec<u8>) -> (Metadata, String) {
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
|
|
||||||
|
struct Factory;
|
||||||
|
impl HttpRequestFactory for Factory {
|
||||||
|
type R = MockRequest;
|
||||||
|
fn create(&self, _: Url, _: Method, _: Headers) -> Result<MockRequest, LoadError> {
|
||||||
|
Ok(MockRequest::new(ResponseType::Dummy404))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mock_response = CustomResponse::new(
|
||||||
|
Headers::new(),
|
||||||
|
RawStatus(200, Cow::Borrowed("OK")),
|
||||||
|
expected_body
|
||||||
|
);
|
||||||
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
|
let http_state = HttpState::new();
|
||||||
|
let ui_provider = TestProvider::new();
|
||||||
|
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
|
||||||
|
|
||||||
|
match source {
|
||||||
|
Source::Window => load_data.source = RequestSource::Window(sender.clone()),
|
||||||
|
Source::Worker => load_data.source = RequestSource::Worker(sender.clone()),
|
||||||
|
}
|
||||||
|
|
||||||
|
let join_handle = thread::spawn(move || {
|
||||||
|
let response = load(&load_data.clone(), &ui_provider, &http_state,
|
||||||
|
None, &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
|
||||||
|
match response {
|
||||||
|
Ok(mut response) => {
|
||||||
|
let metadata = response.metadata.clone();
|
||||||
|
let body = read_response(&mut response);
|
||||||
|
(metadata, body)
|
||||||
|
}
|
||||||
|
Err(e) => panic!("Error Getting Response: {:?}", e)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let network_sender = receiver.recv().unwrap();
|
||||||
|
network_sender.send(Some(mock_response)).unwrap();
|
||||||
|
let (metadata, body) = join_handle.join().unwrap();
|
||||||
|
(metadata, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_custom_response_from_window() {
|
||||||
|
let expected_body = b"Yay! From Window".to_vec();
|
||||||
|
let (metadata, body) = load_request_with_source(Source::Window, expected_body.clone());
|
||||||
|
assert_eq!(metadata.status, Some(RawStatus(200, Cow::Borrowed("OK"))));
|
||||||
|
assert_eq!(body, String::from_utf8(expected_body).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_custom_response_from_worker() {
|
||||||
|
let expected_body = b"Yay! From Worker".to_vec();
|
||||||
|
let (metadata, body) = load_request_with_source(Source::Worker, expected_body.clone());
|
||||||
|
assert_eq!(metadata.status, Some(RawStatus(200, Cow::Borrowed("OK"))));
|
||||||
|
assert_eq!(body, String::from_utf8(expected_body).unwrap());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
* 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 ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
|
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
|
||||||
use net::resource_thread::new_core_resource_thread;
|
use net::resource_thread::new_core_resource_thread;
|
||||||
use net_traits::hosts::{parse_hostsfile, host_replacement};
|
use net_traits::hosts::{parse_hostsfile, host_replacement};
|
||||||
use net_traits::{CoreResourceMsg, LoadData, LoadConsumer, LoadContext, NetworkError, ProgressMsg};
|
use net_traits::{CoreResourceMsg, LoadData, LoadConsumer, LoadContext};
|
||||||
|
use net_traits::{NetworkError, ProgressMsg, LoadOrigin, RequestSource};
|
||||||
use profile_traits::time::ProfilerChan;
|
use profile_traits::time::ProfilerChan;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -17,6 +19,23 @@ fn ip(s: &str) -> IpAddr {
|
||||||
s.parse().unwrap()
|
s.parse().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ResourceTest;
|
||||||
|
|
||||||
|
impl LoadOrigin for ResourceTest {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_exit() {
|
fn test_exit() {
|
||||||
let (tx, _rx) = ipc::channel().unwrap();
|
let (tx, _rx) = ipc::channel().unwrap();
|
||||||
|
@ -30,7 +49,7 @@ fn test_bad_scheme() {
|
||||||
let resource_thread = new_core_resource_thread("".to_owned(), None, ProfilerChan(tx));
|
let resource_thread = new_core_resource_thread("".to_owned(), None, ProfilerChan(tx));
|
||||||
let (start_chan, start) = ipc::channel().unwrap();
|
let (start_chan, start) = ipc::channel().unwrap();
|
||||||
let url = Url::parse("bogus://whatever").unwrap();
|
let url = Url::parse("bogus://whatever").unwrap();
|
||||||
resource_thread.send(CoreResourceMsg::Load(LoadData::new(LoadContext::Browsing, url, None, None, None),
|
resource_thread.send(CoreResourceMsg::Load(LoadData::new(LoadContext::Browsing, url, &ResourceTest),
|
||||||
|
|
||||||
LoadConsumer::Channel(start_chan), None)).unwrap();
|
LoadConsumer::Channel(start_chan), None)).unwrap();
|
||||||
let response = start.recv().unwrap();
|
let response = start.recv().unwrap();
|
||||||
|
@ -210,7 +229,7 @@ fn test_cancelled_listener() {
|
||||||
let (sync_sender, sync_receiver) = ipc::channel().unwrap();
|
let (sync_sender, sync_receiver) = ipc::channel().unwrap();
|
||||||
let url = Url::parse(&format!("http://127.0.0.1:{}", port)).unwrap();
|
let url = Url::parse(&format!("http://127.0.0.1:{}", port)).unwrap();
|
||||||
|
|
||||||
resource_thread.send(CoreResourceMsg::Load(LoadData::new(LoadContext::Browsing, url, None, None, None),
|
resource_thread.send(CoreResourceMsg::Load(LoadData::new(LoadContext::Browsing, url, &ResourceTest),
|
||||||
LoadConsumer::Channel(sender),
|
LoadConsumer::Channel(sender),
|
||||||
Some(id_sender))).unwrap();
|
Some(id_sender))).unwrap();
|
||||||
// get the `ResourceId` and send a cancel message, which should stop the loading loop
|
// get the `ResourceId` and send a cancel message, which should stop the loading loop
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue