fix(constellation): pass resolved URL to embedder (#34004)

Constellation notifies the embedder about history changes.
When we hit a URL that responds with a HTTP 301 response code,
we want to replace the original URL with the final location.

The change boils down to reading the URL from
`Pipeline.url`, which is kept up to date, instead of from
`Pipeline.load_data.url`, which stores the original request.

Fixes #33876

Signed-off-by: rwakulszowa <rwakulszowa1@gmail.com>
This commit is contained in:
rwa 2024-10-29 18:13:30 +01:00 committed by GitHub
parent f8e17b68a6
commit d17321f53d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -4695,9 +4695,9 @@ where
)] )]
fn notify_history_changed(&self, top_level_browsing_context_id: TopLevelBrowsingContextId) { fn notify_history_changed(&self, top_level_browsing_context_id: TopLevelBrowsingContextId) {
// Send a flat projection of the history to embedder. // Send a flat projection of the history to embedder.
// The final vector is a concatenation of the LoadData of the past // The final vector is a concatenation of the URLs of the past
// entries, the current entry and the future entries. // entries, the current entry and the future entries.
// LoadData of inner frames are ignored and replaced with the LoadData // URLs of inner frames are ignored and replaced with the URL
// of the parent. // of the parent.
let session_history = match self.webviews.get(top_level_browsing_context_id) { let session_history = match self.webviews.get(top_level_browsing_context_id) {
@ -4720,91 +4720,88 @@ where
}, },
}; };
let current_load_data = match self.pipelines.get(&browsing_context.pipeline_id) { let current_url = match self.pipelines.get(&browsing_context.pipeline_id) {
Some(pipeline) => pipeline.load_data.clone(), Some(pipeline) => pipeline.url.clone(),
None => { None => {
return warn!("{}: Refresh after closure", browsing_context.pipeline_id); return warn!("{}: Refresh after closure", browsing_context.pipeline_id);
}, },
}; };
// If LoadData was ignored, use the LoadData of the previous SessionHistoryEntry, which // If URL was ignored, use the URL of the previous SessionHistoryEntry, which
// is the LoadData of the parent browsing context. // is the URL of the parent browsing context.
let resolve_load_data_future = let resolve_url_future =
|previous_load_data: &mut LoadData, diff: &SessionHistoryDiff| match *diff { |previous_url: &mut ServoUrl, diff: &SessionHistoryDiff| match *diff {
SessionHistoryDiff::BrowsingContext { SessionHistoryDiff::BrowsingContext {
browsing_context_id, browsing_context_id,
ref new_reloader, ref new_reloader,
.. ..
} => { } => {
if browsing_context_id == top_level_browsing_context_id { if browsing_context_id == top_level_browsing_context_id {
let load_data = match *new_reloader { let url = match *new_reloader {
NeedsToReload::No(pipeline_id) => { NeedsToReload::No(pipeline_id) => {
match self.pipelines.get(&pipeline_id) { match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.load_data.clone(), Some(pipeline) => pipeline.url.clone(),
None => previous_load_data.clone(), None => previous_url.clone(),
} }
}, },
NeedsToReload::Yes(_, ref load_data) => load_data.clone(), NeedsToReload::Yes(_, ref load_data) => load_data.url.clone(),
}; };
*previous_load_data = load_data.clone(); *previous_url = url.clone();
Some(load_data) Some(url)
} else { } else {
Some(previous_load_data.clone()) Some(previous_url.clone())
} }
}, },
_ => Some(previous_load_data.clone()), _ => Some(previous_url.clone()),
}; };
let resolve_load_data_past = let resolve_url_past = |previous_url: &mut ServoUrl, diff: &SessionHistoryDiff| match *diff
|previous_load_data: &mut LoadData, diff: &SessionHistoryDiff| match *diff { {
SessionHistoryDiff::BrowsingContext { SessionHistoryDiff::BrowsingContext {
browsing_context_id, browsing_context_id,
ref old_reloader, ref old_reloader,
.. ..
} => { } => {
if browsing_context_id == top_level_browsing_context_id { if browsing_context_id == top_level_browsing_context_id {
let load_data = match *old_reloader { let url = match *old_reloader {
NeedsToReload::No(pipeline_id) => { NeedsToReload::No(pipeline_id) => match self.pipelines.get(&pipeline_id) {
match self.pipelines.get(&pipeline_id) { Some(pipeline) => pipeline.url.clone(),
Some(pipeline) => pipeline.load_data.clone(), None => previous_url.clone(),
None => previous_load_data.clone(), },
} NeedsToReload::Yes(_, ref load_data) => load_data.url.clone(),
}, };
NeedsToReload::Yes(_, ref load_data) => load_data.clone(), *previous_url = url.clone();
}; Some(url)
*previous_load_data = load_data.clone(); } else {
Some(load_data) Some(previous_url.clone())
} else { }
Some(previous_load_data.clone()) },
} _ => Some(previous_url.clone()),
}, };
_ => Some(previous_load_data.clone()),
};
let mut entries: Vec<LoadData> = session_history let mut entries: Vec<ServoUrl> = session_history
.past .past
.iter() .iter()
.rev() .rev()
.scan(current_load_data.clone(), &resolve_load_data_past) .scan(current_url.clone(), &resolve_url_past)
.collect(); .collect();
entries.reverse(); entries.reverse();
let current_index = entries.len(); let current_index = entries.len();
entries.push(current_load_data.clone()); entries.push(current_url.clone());
entries.extend( entries.extend(
session_history session_history
.future .future
.iter() .iter()
.rev() .rev()
.scan(current_load_data, &resolve_load_data_future), .scan(current_url, &resolve_url_future),
); );
let urls = entries.iter().map(|entry| entry.url.clone()).collect();
let msg = ( let msg = (
Some(top_level_browsing_context_id), Some(top_level_browsing_context_id),
EmbedderMsg::HistoryChanged(urls, current_index), EmbedderMsg::HistoryChanged(entries, current_index),
); );
self.embedder_proxy.send(msg); self.embedder_proxy.send(msg);
} }