mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
script: Move navigation fetching to the ScriptThread
(#34919)
This allows reusing the asynchrnous fetch mechanism that we use for page resources and is likely a step toward removing the `FetchThread`. Benefits: - Reduces IPC traffic during navigation. Now instead of bouncing between the constellation and the `ScriptThread` responses are sent directly to the `ScriptThread`. - Allows cancelling loads after redirects, which was not possible before. There is the question of what to do when a redirect is cross-origin (#23037). This currently isn't handled properly as the `Constellation` sends data to the same `Pipeline` that initiated the load. This change doesn't fix this issue, but does make it more possible for the `ScriptThread` to shut down the pipeline and ask the `Constellation` to replace it with a new one. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
73c0701c83
commit
fbd77b4524
16 changed files with 420 additions and 460 deletions
|
@ -14,7 +14,7 @@ use base::id::HistoryStateId;
|
|||
use cookie::Cookie;
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use headers::{ContentType, HeaderMapExt, ReferrerPolicy as ReferrerPolicyHeader};
|
||||
use http::{Error as HttpError, HeaderMap, StatusCode};
|
||||
use http::{header, Error as HttpError, HeaderMap, HeaderValue, StatusCode};
|
||||
use hyper_serde::Serde;
|
||||
use hyper_util::client::legacy::Error as HyperError;
|
||||
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||
|
@ -46,6 +46,10 @@ pub mod request;
|
|||
pub mod response;
|
||||
pub mod storage_thread;
|
||||
|
||||
/// <https://fetch.spec.whatwg.org/#document-accept-header-value>
|
||||
pub const DOCUMENT_ACCEPT_HEADER_VALUE: HeaderValue =
|
||||
HeaderValue::from_static("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
|
||||
/// An implementation of the [Fetch specification](https://fetch.spec.whatwg.org/)
|
||||
pub mod fetch {
|
||||
pub mod headers;
|
||||
|
@ -197,7 +201,7 @@ pub enum FetchResponseMsg {
|
|||
}
|
||||
|
||||
impl FetchResponseMsg {
|
||||
fn request_id(&self) -> RequestId {
|
||||
pub fn request_id(&self) -> RequestId {
|
||||
match self {
|
||||
FetchResponseMsg::ProcessRequestBody(id) |
|
||||
FetchResponseMsg::ProcessRequestEOF(id) |
|
||||
|
@ -252,6 +256,15 @@ pub enum FetchMetadata {
|
|||
},
|
||||
}
|
||||
|
||||
impl FetchMetadata {
|
||||
pub fn metadata(&self) -> &Metadata {
|
||||
match self {
|
||||
Self::Unfiltered(metadata) => metadata,
|
||||
Self::Filtered { unsafe_, .. } => unsafe_,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FetchResponseListener {
|
||||
fn process_request_body(&mut self, request_id: RequestId);
|
||||
fn process_request_eof(&mut self, request_id: RequestId);
|
||||
|
@ -511,6 +524,7 @@ pub enum CoreResourceMsg {
|
|||
enum ToFetchThreadMessage {
|
||||
StartFetch(
|
||||
/* request_builder */ RequestBuilder,
|
||||
/* response_init */ Option<ResponseInit>,
|
||||
/* cancel_chan */ Option<IpcReceiver<()>>,
|
||||
/* callback */ BoxedFetchCallback,
|
||||
),
|
||||
|
@ -570,14 +584,29 @@ impl FetchThread {
|
|||
fn run(&mut self) {
|
||||
loop {
|
||||
match self.receiver.recv().unwrap() {
|
||||
ToFetchThreadMessage::StartFetch(request_builder, canceller, callback) => {
|
||||
ToFetchThreadMessage::StartFetch(
|
||||
request_builder,
|
||||
response_init,
|
||||
canceller,
|
||||
callback,
|
||||
) => {
|
||||
self.active_fetches.insert(request_builder.id, callback);
|
||||
self.core_resource_thread
|
||||
.send(CoreResourceMsg::Fetch(
|
||||
|
||||
// Only redirects have a `response_init` field.
|
||||
let message = match response_init {
|
||||
Some(response_init) => CoreResourceMsg::FetchRedirect(
|
||||
request_builder,
|
||||
response_init,
|
||||
self.to_fetch_sender.clone(),
|
||||
canceller,
|
||||
),
|
||||
None => CoreResourceMsg::Fetch(
|
||||
request_builder,
|
||||
FetchChannels::ResponseMsg(self.to_fetch_sender.clone(), canceller),
|
||||
))
|
||||
.unwrap();
|
||||
),
|
||||
};
|
||||
|
||||
self.core_resource_thread.send(message).unwrap();
|
||||
},
|
||||
ToFetchThreadMessage::FetchResponse(fetch_response_msg) => {
|
||||
let request_id = fetch_response_msg.request_id();
|
||||
|
@ -599,18 +628,23 @@ impl FetchThread {
|
|||
}
|
||||
}
|
||||
|
||||
/// Instruct the resource thread to make a new request.
|
||||
static FETCH_THREAD: OnceLock<Sender<ToFetchThreadMessage>> = OnceLock::new();
|
||||
|
||||
/// Instruct the resource thread to make a new fetch request.
|
||||
pub fn fetch_async(
|
||||
core_resource_thread: &CoreResourceThread,
|
||||
request: RequestBuilder,
|
||||
response_init: Option<ResponseInit>,
|
||||
canceller: Option<IpcReceiver<()>>,
|
||||
callback: BoxedFetchCallback,
|
||||
) {
|
||||
static FETCH_THREAD: OnceLock<Sender<ToFetchThreadMessage>> = OnceLock::new();
|
||||
let _ = FETCH_THREAD
|
||||
.get_or_init(|| FetchThread::spawn(core_resource_thread))
|
||||
.send(ToFetchThreadMessage::StartFetch(
|
||||
request, canceller, callback,
|
||||
request,
|
||||
response_init,
|
||||
canceller,
|
||||
callback,
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -945,5 +979,17 @@ pub fn http_percent_encode(bytes: &[u8]) -> String {
|
|||
percent_encoding::percent_encode(bytes, HTTP_VALUE).to_string()
|
||||
}
|
||||
|
||||
pub fn set_default_accept_language(headers: &mut HeaderMap) {
|
||||
if headers.contains_key(header::ACCEPT_LANGUAGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(eijebong): Change this once typed headers are done
|
||||
headers.insert(
|
||||
header::ACCEPT_LANGUAGE,
|
||||
HeaderValue::from_static("en-US,en;q=0.5"),
|
||||
);
|
||||
}
|
||||
|
||||
pub static PRIVILEGED_SECRET: LazyLock<u32> =
|
||||
LazyLock::new(|| servo_rand::ServoRng::default().next_u32());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue