mirror of
https://github.com/lexmount/moli.git
synced 2026-11-01 00:07:03 +00:00
fix(performance): distinguish cached and validated resource transfers
Carry Fetch response cache state through buffered and streaming responses, navigation, child-document snapshots, and paused response continuations. Fresh disk and memory hits are local; an actual 304 merge is validated. A later memory-cache read resets validated state to local. Resource Timing now reports zero transferred bytes for local hits, 300 for validation, and body size plus the fixed 300-byte overhead for network responses. Real response-header lengths no longer affect transferSize. Exercise real HTTP cache hits, conditional requests, response bodies and header padding in top and child documents. Preserve the existing network provenance of in-flight script waiters. Validation: cargo fmt --all; full workspace/all-targets/all-features Clippy with -D warnings; cargo nextest run --no-fail-fast (19872 passed, 13 skipped). All Cargo runs used 32 build jobs and 32 test threads. The production binary matches Chromium across 22 cache-timing observations; preload controls stay at 23/24 with the existing pending-preload duplicate-download failure.
This commit is contained in:
Generated
+1
@@ -2669,6 +2669,7 @@ dependencies = [
|
||||
"moli-web-mime",
|
||||
"parking_lot",
|
||||
"rcgen",
|
||||
"serde",
|
||||
"strum",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
|
||||
@@ -90,6 +90,7 @@ async fn external_raw_bridge_drop_after_body_eof_cancels_pending_fetch_completio
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_rx,
|
||||
|
||||
@@ -10,7 +10,8 @@ use std::time::Instant;
|
||||
use support::FixtureServer;
|
||||
use tokio::time::Duration;
|
||||
|
||||
|
||||
#[path = "fetch_behaviors/cache_timing.rs"]
|
||||
mod cache_timing;
|
||||
#[path = "fetch_behaviors/preload_as.rs"]
|
||||
mod preload_as;
|
||||
#[path = "fetch_behaviors/preload_crossorigin.rs"]
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
use super::*;
|
||||
use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
struct CacheDirectory(PathBuf);
|
||||
|
||||
impl Drop for CacheDirectory {
|
||||
fn drop(&mut self) {
|
||||
let _ = std::fs::remove_dir_all(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn resource_timing_distinguishes_network_local_and_revalidated_responses() -> Result<()> {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
||||
let addr = listener.local_addr()?;
|
||||
let cache_dir = CacheDirectory(std::env::temp_dir().join(format!(
|
||||
"moli-resource-timing-{}-{}",
|
||||
std::process::id(),
|
||||
addr.port()
|
||||
)));
|
||||
let requests = Arc::new(parking_lot::Mutex::new(HashMap::<
|
||||
String,
|
||||
Vec<Option<String>>,
|
||||
>::new()));
|
||||
let (shutdown, mut shutting_down) = tokio::sync::oneshot::channel::<()>();
|
||||
let server = tokio::spawn(async move {
|
||||
let mut connections = tokio::task::JoinSet::new();
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = &mut shutting_down => break,
|
||||
accepted = listener.accept() => {
|
||||
let (mut socket, _) = accepted?;
|
||||
let requests = Arc::clone(&requests);
|
||||
connections.spawn(async move {
|
||||
let mut bytes = Vec::new();
|
||||
loop {
|
||||
let mut buffer = [0; 4096];
|
||||
let size = socket.read(&mut buffer).await?;
|
||||
if size == 0 { return Ok::<_, anyhow::Error>(()); }
|
||||
bytes.extend_from_slice(&buffer[..size]);
|
||||
if bytes.windows(4).any(|part| part == b"\r\n\r\n") { break; }
|
||||
}
|
||||
let request = String::from_utf8(bytes)?;
|
||||
let path = request.split_whitespace().nth(1).context("request path")?;
|
||||
let url = url::Url::parse(&format!("http://fixture{path}"))?;
|
||||
let params: HashMap<_, _> = url.query_pairs().collect();
|
||||
let mode = params.get("mode").map(|value| value.as_ref()).unwrap_or("");
|
||||
let context = params.get("context").map(|value| value.as_ref()).unwrap_or("");
|
||||
let key = format!("{mode}:{context}");
|
||||
let conditional = request.lines().find_map(|line| {
|
||||
let (name, value) = line.split_once(':')?;
|
||||
name.eq_ignore_ascii_case("if-none-match").then(|| value.trim().to_owned())
|
||||
});
|
||||
let mut headers = String::new();
|
||||
let (status, mime, body) = match url.path() {
|
||||
"/probe-cache" => {
|
||||
requests.lock().entry(key).or_default().push(conditional.clone());
|
||||
let validated = mode == "revalidate" && conditional.as_deref() == Some("\"v1\"");
|
||||
let cache = if mode == "fresh" || validated { "max-age=600" }
|
||||
else if mode == "revalidate" { "no-cache" }
|
||||
else { "no-store" };
|
||||
headers = format!("ETag: \"v1\"\r\nCache-Control: {cache}\r\n");
|
||||
if mode == "padding" {
|
||||
let padding: usize = params.get("padding").context("padding")?.parse()?;
|
||||
headers.push_str(&format!("X-Padding: {}\r\n", "x".repeat(padding)));
|
||||
}
|
||||
if validated { ("304 Not Modified", "text/plain", String::new()) }
|
||||
else { ("200 OK", "text/plain", "cached".to_owned()) }
|
||||
}
|
||||
"/probe-cache-stats" => {
|
||||
headers.push_str("Cache-Control: no-store\r\n");
|
||||
let records = requests.lock().get(&key).cloned().unwrap_or_default();
|
||||
let records: Vec<_> = records.into_iter().map(|conditional| serde_json::json!({"conditional":conditional})).collect();
|
||||
("200 OK", "application/json", serde_json::to_string(&records)?)
|
||||
}
|
||||
_ => ("200 OK", "text/html", "<!doctype html><body>cache timing".to_owned()),
|
||||
};
|
||||
socket.write_all(format!(
|
||||
"HTTP/1.1 {status}\r\nContent-Type: {mime}\r\nContent-Length: {}\r\n{headers}Connection: close\r\n\r\n{body}", body.len()
|
||||
).as_bytes()).await?;
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
Some(result) = connections.join_next(), if !connections.is_empty() => { result??; }
|
||||
}
|
||||
}
|
||||
connections.shutdown().await;
|
||||
Ok::<_, anyhow::Error>(())
|
||||
});
|
||||
let mut config = AppConfig::default();
|
||||
config
|
||||
.fetch_mut()
|
||||
.set_http_cache_dir(Some(cache_dir.0.display().to_string()));
|
||||
let browser = Browser::new(config)?;
|
||||
let mut page = browser.fetch(&format!("http://{addr}/")).await?;
|
||||
let fixture = include_str!("../fixtures/cache-resource-timing.js");
|
||||
for context in ["top", "child"] {
|
||||
let script = if context == "top" {
|
||||
fixture.to_owned()
|
||||
} else {
|
||||
format!(
|
||||
r#"(async () => {{
|
||||
const frame = document.createElement('iframe');
|
||||
frame.srcdoc = '<!doctype html><body>child';
|
||||
await new Promise(resolve => {{ frame.onload=resolve; document.body.append(frame); }});
|
||||
frame.contentWindow.cacheTimingContext = 'child';
|
||||
const result = await frame.contentWindow.eval({});
|
||||
frame.remove();
|
||||
return result;
|
||||
}})()"#,
|
||||
serde_json::to_string(fixture)?
|
||||
)
|
||||
};
|
||||
let result = tokio::time::timeout(
|
||||
Duration::from_secs(15),
|
||||
page.evaluate_runtime_expression_with_await_async(
|
||||
&format!("({script}).then(JSON.stringify)"),
|
||||
true,
|
||||
),
|
||||
)
|
||||
.await??;
|
||||
let observed: serde_json::Value =
|
||||
serde_json::from_str(result["value"].as_str().context("timing observations")?)?;
|
||||
let expected = [
|
||||
("fresh", [306, 0, 0]),
|
||||
("revalidate", [306, 300, 0]),
|
||||
("no-store", [306, 306, 306]),
|
||||
];
|
||||
let mut expected_rows = Vec::new();
|
||||
for (mode, transfers) in expected {
|
||||
let observations: Vec<_> = transfers
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, transfer)| {
|
||||
serde_json::json!({
|
||||
"body":"cached", "count":index + 1, "transfer":transfer, "encoded":6, "decoded":6, "status":200
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let stats = match mode {
|
||||
"fresh" => serde_json::json!([{"conditional":null}]),
|
||||
"revalidate" => serde_json::json!([{"conditional":null},{"conditional":"\"v1\""}]),
|
||||
_ => {
|
||||
serde_json::json!([{"conditional":null},{"conditional":null},{"conditional":null}])
|
||||
}
|
||||
};
|
||||
expected_rows
|
||||
.push(serde_json::json!({"mode":mode,"observations":observations,"stats":stats}));
|
||||
}
|
||||
assert_eq!(
|
||||
observed,
|
||||
serde_json::json!({"result":expected_rows,"headers":[
|
||||
{"padding":0,"transfer":306,"encoded":6},
|
||||
{"padding":4096,"transfer":306,"encoded":6}
|
||||
]}),
|
||||
"{context}"
|
||||
);
|
||||
}
|
||||
let _ = shutdown.send(());
|
||||
server.await??;
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
(async () => {
|
||||
const xhr = url => new Promise((resolve, reject) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url);
|
||||
request.onload = () => resolve(request.responseText);
|
||||
request.onerror = () => reject(new Error('xhr ' + url));
|
||||
request.send();
|
||||
});
|
||||
const context = globalThis.cacheTimingContext || 'top';
|
||||
const resourceUrl = (path, parameters) => {
|
||||
const url = new URL(path, document.baseURI);
|
||||
url.search = new URLSearchParams({...parameters, context});
|
||||
return url.href;
|
||||
};
|
||||
const result = [];
|
||||
for (const mode of ['fresh', 'revalidate', 'no-store']) {
|
||||
const url = resourceUrl('/probe-cache', {mode});
|
||||
const observations = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const body = await xhr(url);
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
const entries = performance.getEntriesByName(url);
|
||||
const entry = entries[entries.length - 1];
|
||||
observations.push({
|
||||
body,
|
||||
count: entries.length,
|
||||
transfer: entry.transferSize,
|
||||
encoded: entry.encodedBodySize,
|
||||
decoded: entry.decodedBodySize,
|
||||
status: entry.responseStatus
|
||||
});
|
||||
}
|
||||
const stats = await (await fetch(resourceUrl('/probe-cache-stats', {mode}))).json();
|
||||
result.push({mode, observations, stats});
|
||||
}
|
||||
const headers = [];
|
||||
for (const padding of [0, 4096]) {
|
||||
const url = resourceUrl('/probe-cache', {mode: 'padding', padding});
|
||||
await xhr(url);
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
const entry = performance.getEntriesByName(url)[0];
|
||||
headers.push({padding, transfer: entry.transferSize, encoded: entry.encodedBodySize});
|
||||
}
|
||||
return {result, headers};
|
||||
})()
|
||||
@@ -27,6 +27,7 @@ moli-url-policy = { path = "../moli-url-policy" }
|
||||
moli-web-bot-auth = { path = "../moli-web-bot-auth" }
|
||||
moli-web-mime = { path = "../moli-web-mime" }
|
||||
parking_lot = "0.12"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
strum = { version = "0.28.0", features = ["derive"] }
|
||||
tokio = { version = "1.51.0", features = ["rt", "sync"] }
|
||||
tracing = "0.1.41"
|
||||
|
||||
@@ -90,6 +90,7 @@ pub(crate) struct CachedStreamingResponseLookup {
|
||||
pub(crate) body: std::io::BufReader<std::fs::File>,
|
||||
pub(crate) expires_at_unix_ms: Option<u64>,
|
||||
pub(crate) force_validate: bool,
|
||||
pub(crate) cache_state: crate::ResponseCacheState,
|
||||
}
|
||||
|
||||
pub(crate) fn cached_streaming_response_is_stale(record: &CachedStreamingResponseLookup) -> bool {
|
||||
|
||||
+1
@@ -165,6 +165,7 @@ fn cached_streaming_record_from_entry(
|
||||
body: entry.body,
|
||||
expires_at_unix_ms: entry.metadata.expires_at_unix_ms,
|
||||
force_validate,
|
||||
cache_state: crate::ResponseCacheState::Local,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ pub(crate) fn merge_cached_not_modified_streaming_response_lookup(
|
||||
) -> Result<CachedStreamingResponseLookup> {
|
||||
let headers = merge_not_modified_headers(&cached.headers, not_modified_headers);
|
||||
cached.headers = headers.clone();
|
||||
cached.cache_state = crate::ResponseCacheState::Validated;
|
||||
cached.metadata.headers = headers.clone();
|
||||
|
||||
let final_url = Url::parse(&cached.final_url).with_context(|| {
|
||||
|
||||
@@ -537,6 +537,7 @@ impl StreamingResponseCollector {
|
||||
redirected: !self.redirect_chain.is_empty(),
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
network_request_extra_info: self.network_request_extra_info.clone(),
|
||||
}));
|
||||
@@ -940,6 +941,7 @@ impl RawStreamingResponseCollector {
|
||||
redirected: !self.redirect_chain.is_empty(),
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
network_request_extra_info: self.network_request_extra_info.clone(),
|
||||
}));
|
||||
|
||||
@@ -73,6 +73,7 @@ pub struct StreamingHtmlResponseStart {
|
||||
pub redirected: bool,
|
||||
pub redirect_chain: Vec<RedirectInfo>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: crate::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<NegotiatedHttpVersion>,
|
||||
pub network_request_extra_info: Option<NetworkRequestExtraInfo>,
|
||||
}
|
||||
@@ -89,6 +90,7 @@ impl StreamingHtmlResponseStart {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain,
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ pub use request::{
|
||||
pub use request_policy::{is_bad_port, should_request_be_blocked_due_to_bad_port};
|
||||
pub use response::{
|
||||
NegotiatedHttpVersion, NetworkRequestExtraInfo, NetworkResponseExtraInfo, RawResponse,
|
||||
RedirectInfo, RedirectSource, Response, ResponseBody, ResponseHead,
|
||||
RedirectInfo, RedirectSource, Response, ResponseBody, ResponseCacheState, ResponseHead,
|
||||
};
|
||||
pub use runtime::PendingStreamingRawResponse;
|
||||
pub use runtime::{
|
||||
|
||||
@@ -4,6 +4,18 @@ use url::Url;
|
||||
|
||||
use crate::{StreamingHtmlResponse, StreamingRawResponse};
|
||||
|
||||
/// Fetch's response cache state, retained separately from the legacy
|
||||
/// `from_cache` flag so Resource Timing can distinguish a 304 validation from
|
||||
/// a response served without a network request.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum ResponseCacheState {
|
||||
#[default]
|
||||
None,
|
||||
Local,
|
||||
Validated,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum NegotiatedHttpVersion {
|
||||
Http09,
|
||||
@@ -51,6 +63,7 @@ pub struct ResponseHead {
|
||||
pub redirected: bool,
|
||||
pub redirect_chain: Vec<RedirectInfo>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: crate::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<NegotiatedHttpVersion>,
|
||||
}
|
||||
|
||||
@@ -327,6 +340,7 @@ pub struct Response {
|
||||
pub redirected: bool,
|
||||
pub redirect_chain: Vec<RedirectInfo>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: crate::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<NegotiatedHttpVersion>,
|
||||
network_request_extra_info: Option<NetworkRequestExtraInfo>,
|
||||
}
|
||||
@@ -347,6 +361,7 @@ impl Clone for Response {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
network_request_extra_info: self.network_request_extra_info.clone(),
|
||||
}
|
||||
@@ -401,6 +416,7 @@ impl Response {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
}
|
||||
}
|
||||
@@ -439,6 +455,7 @@ impl Response {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain,
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_extra_info: None,
|
||||
})
|
||||
@@ -457,6 +474,7 @@ impl Response {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain,
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_extra_info: None,
|
||||
})
|
||||
@@ -473,6 +491,7 @@ impl Response {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain,
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
};
|
||||
let (body, body_bytes) = self
|
||||
@@ -510,6 +529,7 @@ impl Response {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain,
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
};
|
||||
(head, self.body)
|
||||
@@ -536,6 +556,7 @@ pub struct RawResponse {
|
||||
pub redirected: bool,
|
||||
pub redirect_chain: Vec<RedirectInfo>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: crate::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<NegotiatedHttpVersion>,
|
||||
network_request_extra_info: Option<NetworkRequestExtraInfo>,
|
||||
}
|
||||
@@ -556,6 +577,7 @@ impl Clone for RawResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
network_request_extra_info: self.network_request_extra_info.clone(),
|
||||
}
|
||||
@@ -604,6 +626,7 @@ impl RawResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
}
|
||||
}
|
||||
@@ -628,6 +651,7 @@ impl RawResponse {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain,
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_extra_info: None,
|
||||
})
|
||||
@@ -646,6 +670,7 @@ impl RawResponse {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain,
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_extra_info: None,
|
||||
})
|
||||
@@ -662,6 +687,7 @@ impl RawResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain,
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
};
|
||||
(head, self.body)
|
||||
|
||||
@@ -2344,6 +2344,7 @@ impl RuntimeOwner {
|
||||
redirected: !job.request.redirect_chain.is_empty(),
|
||||
redirect_chain: job.request.redirect_chain,
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version,
|
||||
network_request_extra_info: request_extra_info,
|
||||
}));
|
||||
@@ -2920,6 +2921,7 @@ fn complete_streaming_html_job(job: StreamingRuntimeJob, response: Response) {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain,
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_extra_info,
|
||||
}));
|
||||
@@ -2941,6 +2943,7 @@ fn complete_cached_streaming_html_job(
|
||||
let redirect_chain = job.request.redirect_chain.clone();
|
||||
let CachedStreamingResponseLookup {
|
||||
metadata,
|
||||
cache_state,
|
||||
final_url,
|
||||
status,
|
||||
headers,
|
||||
@@ -2973,6 +2976,7 @@ fn complete_cached_streaming_html_job(
|
||||
redirected,
|
||||
redirect_chain,
|
||||
from_cache: true,
|
||||
cache_state,
|
||||
negotiated_http_version: None,
|
||||
network_request_extra_info: None,
|
||||
}));
|
||||
@@ -3063,6 +3067,7 @@ fn complete_cached_streaming_raw_job(
|
||||
let redirect_chain = job.request.redirect_chain.clone();
|
||||
let CachedStreamingResponseLookup {
|
||||
metadata,
|
||||
cache_state,
|
||||
final_url,
|
||||
status,
|
||||
headers,
|
||||
@@ -3095,6 +3100,7 @@ fn complete_cached_streaming_raw_job(
|
||||
redirected,
|
||||
redirect_chain,
|
||||
from_cache: true,
|
||||
cache_state,
|
||||
negotiated_http_version: None,
|
||||
network_request_extra_info: None,
|
||||
}));
|
||||
@@ -3537,6 +3543,7 @@ fn proxy_connect_response_start(
|
||||
redirected: !redirect_chain.is_empty(),
|
||||
redirect_chain: redirect_chain.to_vec(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
network_request_extra_info: None,
|
||||
}
|
||||
@@ -3640,6 +3647,7 @@ fn collect_buffered_response(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version,
|
||||
},
|
||||
body,
|
||||
@@ -4300,6 +4308,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"<!doctype html><html><body>cached</body></html>".to_owned(),
|
||||
|
||||
@@ -31,6 +31,7 @@ pub struct StreamingHtmlResponse {
|
||||
pub redirected: bool,
|
||||
pub redirect_chain: Vec<RedirectInfo>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: crate::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<NegotiatedHttpVersion>,
|
||||
network_request_extra_info: Option<NetworkRequestExtraInfo>,
|
||||
body_chunks: mpsc::UnboundedReceiver<String>,
|
||||
@@ -58,6 +59,7 @@ impl StreamingHtmlResponse {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_chunks,
|
||||
@@ -82,6 +84,7 @@ impl StreamingHtmlResponse {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain,
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_extra_info: None,
|
||||
body_chunks,
|
||||
@@ -101,6 +104,7 @@ impl StreamingHtmlResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
}
|
||||
}
|
||||
@@ -174,6 +178,7 @@ pub struct StreamingRawResponse {
|
||||
pub redirected: bool,
|
||||
pub redirect_chain: Vec<RedirectInfo>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: crate::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<NegotiatedHttpVersion>,
|
||||
network_request_extra_info: Option<NetworkRequestExtraInfo>,
|
||||
body_chunks: mpsc::UnboundedReceiver<Vec<u8>>,
|
||||
@@ -205,6 +210,7 @@ impl StreamingRawResponse {
|
||||
redirected,
|
||||
redirect_chain,
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
network_request_extra_info: None,
|
||||
body_chunks,
|
||||
@@ -230,6 +236,7 @@ impl StreamingRawResponse {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain,
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_extra_info: None,
|
||||
body_chunks,
|
||||
@@ -321,6 +328,7 @@ impl StreamingRawResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
}
|
||||
}
|
||||
@@ -387,6 +395,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ fn sample_response_head() -> ResponseHead {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
}
|
||||
}
|
||||
@@ -4405,11 +4406,19 @@ fn network_metadata_keeps_raw_304_separate_from_merged_cached_response() {
|
||||
fetch_raw_with_network_metadata_for_test(&client, Request::get(&server.url()).unwrap())
|
||||
.unwrap();
|
||||
assert_eq!(first.response().status, 200);
|
||||
assert_eq!(
|
||||
first.response().cache_state,
|
||||
crate::ResponseCacheState::None
|
||||
);
|
||||
let second =
|
||||
fetch_raw_with_network_metadata_for_test(&client, Request::get(&server.url()).unwrap())
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(second.response().status, 200);
|
||||
assert_eq!(
|
||||
second.response().cache_state,
|
||||
crate::ResponseCacheState::Validated
|
||||
);
|
||||
assert_eq!(second.response().body_bytes(), b"cached");
|
||||
let exchange = second
|
||||
.observation_journal()
|
||||
@@ -4812,6 +4821,9 @@ fn fetch_client_cache_updates_freshness_after_not_modified() {
|
||||
assert_eq!(first.body_text(), "hit-1");
|
||||
assert_eq!(second.body_text(), "hit-1");
|
||||
assert_eq!(third.body_text(), "hit-1");
|
||||
assert_eq!(first.cache_state, crate::ResponseCacheState::None);
|
||||
assert_eq!(second.cache_state, crate::ResponseCacheState::Validated);
|
||||
assert_eq!(third.cache_state, crate::ResponseCacheState::Local);
|
||||
for response in [&first, &second, &third] {
|
||||
assert_eq!(response.status, 200);
|
||||
assert_eq!(
|
||||
|
||||
@@ -326,6 +326,7 @@ pub struct NavigationResponse {
|
||||
pub redirected: bool,
|
||||
pub redirect_chain: Vec<NavigationRedirect>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: moli_fetch::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<NegotiatedHttpVersion>,
|
||||
network_request_headers: Option<Vec<(String, String)>>,
|
||||
}
|
||||
@@ -346,6 +347,7 @@ impl Clone for NavigationResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.clone(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
network_request_headers: self.network_request_headers.clone(),
|
||||
}
|
||||
@@ -407,6 +409,7 @@ impl NavigationResponse {
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
}
|
||||
}
|
||||
@@ -448,6 +451,7 @@ impl NavigationResponse {
|
||||
redirected: head.redirected,
|
||||
redirect_chain: head.redirect_chain.into_iter().map(Into::into).collect(),
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_headers: None,
|
||||
}
|
||||
@@ -474,6 +478,7 @@ impl NavigationResponse {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body,
|
||||
@@ -506,6 +511,7 @@ impl NavigationResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.into_iter().map(Into::into).collect(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
};
|
||||
let (body, body_bytes) = self
|
||||
@@ -543,6 +549,7 @@ impl NavigationResponse {
|
||||
redirected: self.redirected,
|
||||
redirect_chain: self.redirect_chain.into_iter().map(Into::into).collect(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
};
|
||||
(head, self.body)
|
||||
@@ -2431,6 +2438,7 @@ pub struct PendingSubresourceResponseInfo {
|
||||
/// a response-stage Fetch pause is held.
|
||||
pub response_body: SubresourceResponseBody,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: moli_fetch::ResponseCacheState,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -2450,6 +2458,7 @@ pub struct PendingSubresourceAuthInfo {
|
||||
pub response_headers: Vec<(String, Vec<u8>)>,
|
||||
pub response_body: SubresourceResponseBody,
|
||||
pub response_from_cache: bool,
|
||||
pub response_cache_state: moli_fetch::ResponseCacheState,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -3310,6 +3319,8 @@ pub struct ChildFrameDocumentNetworkSnapshot {
|
||||
pub response_body: Option<SubresourceResponseBody>,
|
||||
#[serde(default)]
|
||||
pub from_cache: bool,
|
||||
#[serde(default)]
|
||||
pub cache_state: moli_fetch::ResponseCacheState,
|
||||
}
|
||||
|
||||
/// A completed child main-resource request whose Network facts remain
|
||||
@@ -4033,6 +4044,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"hello".to_owned(),
|
||||
@@ -4060,6 +4072,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"é".to_owned(),
|
||||
@@ -4098,6 +4111,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
String::new(),
|
||||
|
||||
@@ -273,6 +273,7 @@ impl PendingFetchAuthNavigation {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
b"auth required".to_vec(),
|
||||
|
||||
@@ -408,6 +408,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body.to_vec(),
|
||||
|
||||
@@ -159,6 +159,7 @@ async fn prepare_browser_owned_error_page_navigation_with_engine_async(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
prepare_captured_document_response_with_engine_async(
|
||||
@@ -1215,6 +1216,7 @@ fn decoded_data_url_navigation_response(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
decoded.body,
|
||||
@@ -1311,6 +1313,7 @@ async fn load_inline_html_navigation_with_engine_async(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
prepare_navigation_from_captured_raw_response_with_engine_async(
|
||||
@@ -3003,6 +3006,7 @@ impl CdpConnection {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
self.build_navigation_from_captured_raw_response_with_load_inputs_async(
|
||||
|
||||
@@ -629,6 +629,7 @@ fn pause_data_url_response_stage_navigation_into_buffer(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body,
|
||||
|
||||
@@ -592,6 +592,7 @@ mod tests {
|
||||
response_headers: vec![("content-type".to_owned(), b"text/plain".to_vec())],
|
||||
response_body: SubresourceResponseBody::from_bytes(b"prepared".to_vec()),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
});
|
||||
let action = crate::domains::activity::PreparedSubresourceContinueAction::capture_for_test(
|
||||
&mut conn,
|
||||
@@ -669,6 +670,7 @@ mod tests {
|
||||
response_headers: Vec::new(),
|
||||
response_body: SubresourceResponseBody::from_bytes(b"old".to_vec()),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
});
|
||||
let old_action =
|
||||
crate::domains::activity::PreparedSubresourceContinueAction::capture_for_test(
|
||||
|
||||
@@ -689,6 +689,7 @@ async fn clear_browser_cache_keeps_pending_response_navigation_transfer() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
b"body".to_vec(),
|
||||
|
||||
@@ -1643,6 +1643,7 @@ async fn child_frame_activity_emits_document_network_events_from_prepared_load()
|
||||
encoded_data_length: 3,
|
||||
response_body: Some(SubresourceResponseBody::from_bytes(vec![0x00, 0xff, b'a'])),
|
||||
from_cache: true,
|
||||
cache_state: moli_fetch::ResponseCacheState::Local,
|
||||
}),
|
||||
}],
|
||||
"https://example.test".to_owned(),
|
||||
@@ -1774,6 +1775,7 @@ async fn stale_child_document_response_emits_network_without_navigation_or_lifec
|
||||
b"historical child body".to_vec(),
|
||||
)),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
},
|
||||
}],
|
||||
Vec::new(),
|
||||
@@ -1875,6 +1877,7 @@ async fn child_document_network_without_body_records_known_no_data() {
|
||||
encoded_data_length: 0,
|
||||
response_body: None,
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
};
|
||||
let mut background_events = Vec::new();
|
||||
|
||||
|
||||
@@ -298,6 +298,7 @@ impl ResourcePerformanceEntry {
|
||||
response.status,
|
||||
&response.headers,
|
||||
body_size as f64,
|
||||
response.cache_state,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -315,6 +316,7 @@ impl ResourcePerformanceEntry {
|
||||
response.status,
|
||||
&response.headers,
|
||||
body_size as f64,
|
||||
response.cache_state,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -331,6 +333,7 @@ impl ResourcePerformanceEntry {
|
||||
response.status,
|
||||
&response.headers,
|
||||
response.body_bytes().len() as f64,
|
||||
response.cache_state,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -341,11 +344,15 @@ impl ResourcePerformanceEntry {
|
||||
response_status: u16,
|
||||
response_headers: &[(String, Vec<u8>)],
|
||||
body_size: f64,
|
||||
cache_state: moli_fetch::ResponseCacheState,
|
||||
) -> Self {
|
||||
let header_size = response_headers
|
||||
.iter()
|
||||
.map(|(name, value)| name.len() + value.len() + 4)
|
||||
.sum::<usize>() as f64;
|
||||
// Resource Timing deliberately uses a fixed overhead rather than
|
||||
// exposing response-header sizes, which could reveal cookies.
|
||||
let transfer_size = match cache_state {
|
||||
moli_fetch::ResponseCacheState::None => body_size + 300.0,
|
||||
moli_fetch::ResponseCacheState::Local => 0.0,
|
||||
moli_fetch::ResponseCacheState::Validated => 300.0,
|
||||
};
|
||||
let content_type = moli_web_mime::response_content_type(response_headers)
|
||||
.and_then(|value| moli_web_mime::mime_essence(&value))
|
||||
.unwrap_or_default();
|
||||
@@ -353,7 +360,7 @@ impl ResourcePerformanceEntry {
|
||||
name: name.into(),
|
||||
initiator_type: initiator_type.to_owned(),
|
||||
start_unix_millis,
|
||||
transfer_size: (body_size + header_size).max(1.0),
|
||||
transfer_size,
|
||||
encoded_body_size: body_size,
|
||||
decoded_body_size: body_size,
|
||||
// The fetch lifecycle does not yet retain render-blocking metadata.
|
||||
@@ -370,26 +377,15 @@ impl ResourcePerformanceEntry {
|
||||
start_unix_millis: Option<f64>,
|
||||
network: &crate::protocol_types::ChildFrameDocumentNetworkSnapshot,
|
||||
) -> Self {
|
||||
let body_size = network.encoded_data_length as f64;
|
||||
let header_size = network
|
||||
.response_headers
|
||||
.iter()
|
||||
.map(|(name, value)| name.len() + value.len() + 4)
|
||||
.sum::<usize>() as f64;
|
||||
let content_type = moli_web_mime::response_content_type(&network.response_headers)
|
||||
.and_then(|value| moli_web_mime::mime_essence(&value))
|
||||
.unwrap_or_default();
|
||||
Self {
|
||||
name: name.into(),
|
||||
initiator_type: initiator_type.to_owned(),
|
||||
Self::from_response_parts(
|
||||
name,
|
||||
initiator_type,
|
||||
start_unix_millis,
|
||||
transfer_size: (body_size + header_size).max(1.0),
|
||||
encoded_body_size: body_size,
|
||||
decoded_body_size: body_size,
|
||||
render_blocking_status: "non-blocking".to_owned(),
|
||||
response_status: f64::from(network.status),
|
||||
content_type,
|
||||
}
|
||||
network.status,
|
||||
&network.response_headers,
|
||||
network.encoded_data_length as f64,
|
||||
network.cache_state,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn from_network_failure(
|
||||
|
||||
@@ -1108,6 +1108,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: true,
|
||||
cache_state: moli_fetch::ResponseCacheState::Local,
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"export default 1;".to_owned(),
|
||||
|
||||
@@ -888,6 +888,7 @@ fn child_document_load_outcome_from_response(
|
||||
encoded_data_length,
|
||||
response_body: Some(response_body),
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
}),
|
||||
},
|
||||
)))
|
||||
@@ -956,6 +957,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
moli_fetch::ResponseBody::materialized_bytes(body_bytes.clone()),
|
||||
|
||||
@@ -3085,6 +3085,7 @@ impl JsContextHost {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: info.from_cache,
|
||||
cache_state: info.cache_state,
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
)
|
||||
@@ -3130,6 +3131,7 @@ impl JsContextHost {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: info.response_from_cache,
|
||||
cache_state: info.response_cache_state,
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -306,6 +306,7 @@ impl JsContextHost {
|
||||
response_headers: response_headers.into_iter().collect(),
|
||||
response_body: SubresourceResponseBody::from_bytes(Vec::new()),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
}),
|
||||
);
|
||||
true
|
||||
|
||||
@@ -836,6 +836,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body.to_owned(),
|
||||
@@ -854,6 +855,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body.to_vec(),
|
||||
@@ -1058,6 +1060,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"x".repeat(64),
|
||||
|
||||
@@ -68,6 +68,7 @@ impl RendererPreparedNetworkResourceLoad {
|
||||
cookie_set_reports: head.cookie_set_reports,
|
||||
redirect_chain: head.redirect_chain.into_iter().map(Into::into).collect(),
|
||||
from_cache: head.from_cache,
|
||||
cache_state: head.cache_state,
|
||||
negotiated_http_version: head.negotiated_http_version,
|
||||
network_request_headers,
|
||||
},
|
||||
@@ -90,6 +91,7 @@ pub struct RendererNetworkResourceLoadResponse {
|
||||
pub cookie_set_reports: Vec<StoredCookieSetReport>,
|
||||
pub redirect_chain: Vec<NavigationRedirect>,
|
||||
pub from_cache: bool,
|
||||
pub cache_state: moli_fetch::ResponseCacheState,
|
||||
pub negotiated_http_version: Option<moli_fetch::NegotiatedHttpVersion>,
|
||||
pub network_request_headers: Option<Vec<(String, String)>>,
|
||||
}
|
||||
@@ -111,6 +113,7 @@ impl RendererNetworkResourceLoadResponse {
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
from_cache: self.from_cache,
|
||||
cache_state: self.cache_state,
|
||||
negotiated_http_version: self.negotiated_http_version,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,6 +1208,7 @@ fn streaming_raw_response_from_cached_subresource(
|
||||
) -> Result<StreamingRawResponse> {
|
||||
let mut head = response.head();
|
||||
head.from_cache = true;
|
||||
head.cache_state = moli_fetch::ResponseCacheState::Local;
|
||||
for redirect in &mut head.redirect_chain {
|
||||
redirect.from_cache = true;
|
||||
redirect.network_extra_info_available = false;
|
||||
@@ -1231,6 +1232,7 @@ fn streaming_raw_response_from_local_response(response: Response) -> Result<Stre
|
||||
|
||||
fn response_with_memory_cache_hit(mut response: Response) -> Response {
|
||||
response.from_cache = true;
|
||||
response.cache_state = moli_fetch::ResponseCacheState::Local;
|
||||
for redirect in &mut response.redirect_chain {
|
||||
redirect.from_cache = true;
|
||||
redirect.network_extra_info_available = false;
|
||||
|
||||
@@ -288,6 +288,7 @@ async fn memory_cache_tee_drop_after_body_eof_cancels_pending_completion_and_rel
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_rx,
|
||||
@@ -1228,6 +1229,8 @@ async fn concurrent_script_text_waiter_preserves_owner_cache_state() -> Result<(
|
||||
!second.from_cache,
|
||||
"in-flight coalescing should preserve the owner's network provenance"
|
||||
);
|
||||
assert_eq!(first.cache_state, moli_fetch::ResponseCacheState::None);
|
||||
assert_eq!(second.cache_state, moli_fetch::ResponseCacheState::None);
|
||||
|
||||
let third = loader
|
||||
.fetch_cacheable_script_text_stream(request()?)
|
||||
@@ -1240,6 +1243,7 @@ async fn concurrent_script_text_waiter_preserves_owner_cache_state() -> Result<(
|
||||
third.from_cache,
|
||||
"completed script text cache hits should still report memory-cache provenance"
|
||||
);
|
||||
assert_eq!(third.cache_state, moli_fetch::ResponseCacheState::Local);
|
||||
|
||||
server.await?;
|
||||
Ok(())
|
||||
@@ -1605,6 +1609,7 @@ async fn cached_raw_subresource_marks_redirect_hops_from_cache() -> Result<()> {
|
||||
negotiated_http_version: None,
|
||||
}],
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
b"cached-final-body".to_vec(),
|
||||
|
||||
@@ -1089,6 +1089,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
true,
|
||||
|
||||
@@ -187,6 +187,7 @@ fn cors_redirect_referrer_never_recovers_stripped_information() -> Result<()> {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
assert_eq!(
|
||||
@@ -239,6 +240,7 @@ fn cors_redirect_modes_precede_location_parsing() -> Result<()> {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
let result = redirects.advance(head, false, None);
|
||||
|
||||
@@ -129,6 +129,7 @@ pub(super) fn blob_response(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_bytes.to_vec(),
|
||||
@@ -152,6 +153,7 @@ pub(crate) fn data_url_response(url: &url::Url) -> Option<Response> {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_bytes,
|
||||
|
||||
@@ -626,6 +626,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
}
|
||||
}
|
||||
@@ -657,6 +658,7 @@ mod tests {
|
||||
negotiated_http_version: None,
|
||||
}],
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
let document_url = url("https://document.test/page.html");
|
||||
|
||||
@@ -95,6 +95,7 @@ fn xhr_complete_callback(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
pending_body_value,
|
||||
|
||||
@@ -312,6 +312,7 @@ impl DetachedParserScriptFetchContinuation {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
ResponseBody::materialized_text(text, response_body),
|
||||
|
||||
@@ -732,6 +732,7 @@ fn dedicated_worker_navigation_response_eq(
|
||||
&& left.redirected == right.redirected
|
||||
&& left.redirect_chain == right.redirect_chain
|
||||
&& left.from_cache == right.from_cache
|
||||
&& left.cache_state == right.cache_state
|
||||
&& left.negotiated_http_version == right.negotiated_http_version
|
||||
&& left.network_request_headers() == right.network_request_headers()
|
||||
}
|
||||
|
||||
@@ -491,6 +491,7 @@ fn about_blank_navigation_response(url: &Url) -> Option<moli_fetch::Response> {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
Vec::new(),
|
||||
|
||||
@@ -245,6 +245,7 @@ fetch({:?})
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
},
|
||||
@@ -460,6 +461,7 @@ async fn streaming_finish_requires_matching_request_and_body_source_identity() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -738,6 +738,7 @@ pub(super) fn stale_loaded_completion(
|
||||
encoded_data_length: 0,
|
||||
response_body: None,
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
}),
|
||||
},
|
||||
))),
|
||||
|
||||
@@ -633,6 +633,7 @@ fn module_graph_network_result_records_staged_response_started_with_cache_state(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: true,
|
||||
cache_state: moli_fetch::ResponseCacheState::Local,
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"export default 1;".to_owned(),
|
||||
|
||||
@@ -859,6 +859,7 @@ impl ScriptVm {
|
||||
response_headers: response.headers.clone(),
|
||||
response_body: SubresourceResponseBody::from_navigation_response(&response),
|
||||
from_cache: response.from_cache,
|
||||
cache_state: response.cache_state,
|
||||
};
|
||||
self._context_host
|
||||
.borrow_mut()
|
||||
@@ -1115,6 +1116,7 @@ impl ScriptVm {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
let pending = match continuation {
|
||||
@@ -1861,6 +1863,7 @@ impl ScriptVm {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: pending.response.from_cache,
|
||||
cache_state: pending.response.cache_state,
|
||||
negotiated_http_version: pending.response.negotiated_http_version,
|
||||
});
|
||||
let result = if pending.pending.request_mode == moli_fetch::RequestMode::NoCors {
|
||||
@@ -1925,6 +1928,7 @@ impl ScriptVm {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: pending.response.from_cache,
|
||||
cache_state: pending.response.cache_state,
|
||||
negotiated_http_version: pending.response.negotiated_http_version,
|
||||
});
|
||||
let result = if pending.pending.request_mode == moli_fetch::RequestMode::NoCors {
|
||||
@@ -1998,6 +2002,7 @@ impl ScriptVm {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: pending.response.from_cache,
|
||||
cache_state: pending.response.cache_state,
|
||||
negotiated_http_version: pending.response.negotiated_http_version,
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -138,6 +138,7 @@ impl ScriptVm {
|
||||
response_headers: response.headers.clone(),
|
||||
response_body: SubresourceResponseBody::from_navigation_response(&response),
|
||||
response_from_cache: response.from_cache,
|
||||
response_cache_state: response.cache_state,
|
||||
};
|
||||
trace_async_subresource_stage(
|
||||
"async_subresource_complete_running_auth_required",
|
||||
@@ -191,6 +192,7 @@ impl ScriptVm {
|
||||
response_headers: response.headers.clone(),
|
||||
response_body: SubresourceResponseBody::from_navigation_response(&response),
|
||||
from_cache: response.from_cache,
|
||||
cache_state: response.cache_state,
|
||||
};
|
||||
self._context_host
|
||||
.borrow_mut()
|
||||
|
||||
@@ -588,6 +588,7 @@ fn parser_script_network_results_populate_buffered_resource_timing_snapshots() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"void 0;".to_owned(),
|
||||
|
||||
@@ -179,6 +179,7 @@ fn xhr_null_body_statuses_discard_buffered_and_streamed_bytes() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
if streaming {
|
||||
@@ -344,6 +345,7 @@ fn xhr_null_body_late_completion_preserves_a_replacement_requests_progress() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
|
||||
@@ -64,6 +64,7 @@ fn window_service_worker_response_filter_survives_streaming_clone_and_cache() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
let response_filter = Some(if cors {
|
||||
@@ -233,6 +234,7 @@ fn window_filtered_fetch_preserves_internal_head_through_clone_and_cache() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
if streaming {
|
||||
|
||||
@@ -57,6 +57,7 @@ fn redirect_filter_completion_keeps_status_text_and_explicit_filters() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"body".to_owned(),
|
||||
|
||||
@@ -35,6 +35,7 @@ fn xhr_response_headers_are_filtered_combined_and_sorted_before_events() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
if streaming {
|
||||
|
||||
@@ -1200,6 +1200,7 @@ fn xml_http_request_blob_response_uses_final_mime_type() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
moli_fetch::ResponseBody::materialized_bytes(b"body".to_vec()),
|
||||
@@ -1300,6 +1301,7 @@ fn xml_http_request_default_response_type_parses_response_xml_for_document_mime(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
moli_fetch::ResponseBody::materialized_bytes(
|
||||
@@ -1327,6 +1329,7 @@ fn xml_http_request_default_response_type_parses_response_xml_for_document_mime(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
moli_fetch::ResponseBody::materialized_bytes(b"plain text".to_vec()),
|
||||
@@ -1405,6 +1408,7 @@ fn xml_http_request_response_document_uses_response_url_and_requester_origin() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
moli_fetch::ResponseBody::materialized_bytes(br#"<html xmlns="http://www.w3.org/1999/xhtml"><head><base href="../assets/" /></head><body><a id="link" href="child">link</a></body></html>"#.to_vec()),
|
||||
@@ -1502,6 +1506,7 @@ fn xml_http_request_document_response_requires_an_eligible_mime_and_well_formed_
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
if streaming {
|
||||
@@ -1656,6 +1661,7 @@ fn xhr_streamed_response_documents_keep_distinct_source_modification_times() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
@@ -1773,6 +1779,7 @@ fn xhr_response_decoding_uses_headers_received_overrides_for_buffered_and_stream
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
if streaming {
|
||||
@@ -2958,6 +2965,7 @@ __streamingXhr.send();
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
|
||||
@@ -3144,6 +3152,7 @@ async fn streaming_subresource_finish_preserves_response_head_cache_state() {
|
||||
negotiated_http_version: None,
|
||||
}],
|
||||
from_cache: true,
|
||||
cache_state: moli_fetch::ResponseCacheState::Local,
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
@@ -3424,6 +3433,7 @@ async fn streaming_fetch_body_error_records_response_started_then_body_failed()
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
@@ -3525,6 +3535,7 @@ fn install_streaming_fetch_response_fixture(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_source_id,
|
||||
@@ -3587,6 +3598,7 @@ fn install_streaming_fetch_response_fixture(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
@@ -3699,6 +3711,7 @@ async fn streaming_fetch_body_cancel_aborts_streaming_subresource() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
@@ -4336,6 +4349,7 @@ async fn streaming_xhr_materialization_failure_errors_body_source_before_close()
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
|
||||
@@ -655,6 +655,7 @@ async fn child_navigation_keeps_accepted_beacon_network_only_and_rejects_stale_s
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -325,6 +325,7 @@ async fn child_csp_report_keeps_exact_violation_document_without_v8_after_naviga
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1967,6 +1967,7 @@ fn isolated_realm_destruction_aborts_fetch_and_detaches_keepalive() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -31,6 +31,7 @@ fn fetch_request_initializers_use_request_header_guards() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
vm.complete_async_subresource_fetch(crate::types::AsyncSubresourceFetchCompletion {
|
||||
|
||||
@@ -374,6 +374,7 @@ fn register_pending_window_fetch_for_test(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
network_request_headers: None,
|
||||
|
||||
@@ -357,6 +357,7 @@ fn external_script_redirect_final_url_obeys_script_src_csp() {
|
||||
redirected: true,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"globalThis.__redirectScriptRan = true;".to_owned(),
|
||||
|
||||
@@ -725,6 +725,7 @@ fn response_clone_tees_pending_network_body_after_parent_consumption() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_source_id,
|
||||
@@ -831,6 +832,7 @@ fn pending_fetch_body_pipe_through_text_decoder_stream_pulls_future_chunks() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
body_source_id,
|
||||
@@ -954,6 +956,7 @@ fn materialize_response_object_preserves_redirected_slot() {
|
||||
redirected: true,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
"redirected-body".to_owned(),
|
||||
@@ -1336,6 +1339,7 @@ redirect_mode: moli_fetch::RequestRedirectMode::Follow,
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
let id = crate::network_host::new_network_body_source_id();
|
||||
@@ -1439,6 +1443,7 @@ fn opaque_window_fetch_keeps_blocked_bytes_out_of_internal_clone_consumers() {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
},
|
||||
@@ -1551,6 +1556,7 @@ redirect_mode: moli_fetch::RequestRedirectMode::Follow, method: "GET", mode: mol
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
moli_fetch::ResponseBody::materialized_bytes(Vec::new()),
|
||||
|
||||
@@ -554,6 +554,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
|
||||
@@ -950,6 +951,7 @@ mod tests {
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
let mut resource =
|
||||
|
||||
@@ -115,6 +115,7 @@ fn service_worker_fetch_stream_response_head(
|
||||
redirected: response_head.redirected || !job.request.redirect_chain().is_empty(),
|
||||
redirect_chain: job.request.redirect_chain().to_vec(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
}
|
||||
}
|
||||
@@ -638,6 +639,7 @@ impl ServiceWorkerRuntimeService {
|
||||
redirected: response.redirected || !job.request.redirect_chain().is_empty(),
|
||||
redirect_chain: job.request.redirect_chain().to_vec(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
},
|
||||
String::from_utf8_lossy(&response.body).into_owned(),
|
||||
|
||||
@@ -2677,6 +2677,7 @@ pub(in crate::worker) fn worker_response_from_body(
|
||||
redirected: false,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
})
|
||||
}
|
||||
@@ -3088,6 +3089,7 @@ pub(in crate::worker) fn drain_worker_fetch_completion_result(
|
||||
response_headers: response_head.headers.clone(),
|
||||
response_body,
|
||||
response_from_cache: response_head.from_cache,
|
||||
response_cache_state: response_head.cache_state,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@@ -3122,6 +3124,7 @@ pub(in crate::worker) fn drain_worker_fetch_completion_result(
|
||||
response_headers: response_head.headers.clone(),
|
||||
response_body: response_body.clone(),
|
||||
from_cache: response_head.from_cache,
|
||||
cache_state: response_head.cache_state,
|
||||
};
|
||||
pending.paused_response = Some(PausedWorkerSubresourceResponse {
|
||||
response_filter: completion.response_filter.clone(),
|
||||
|
||||
@@ -1069,6 +1069,7 @@ pub(in crate::worker) fn drain_worker_xhr_completion(
|
||||
response_headers: response_head.headers.clone(),
|
||||
response_body,
|
||||
response_from_cache: response_head.from_cache,
|
||||
response_cache_state: response_head.cache_state,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@@ -1104,6 +1105,7 @@ pub(in crate::worker) fn drain_worker_xhr_completion(
|
||||
response_headers: response_head.headers.clone(),
|
||||
response_body: response_body.clone(),
|
||||
from_cache: response_head.from_cache,
|
||||
cache_state: response_head.cache_state,
|
||||
};
|
||||
pending.paused_response = Some(PausedWorkerSubresourceResponse {
|
||||
response_filter: None,
|
||||
|
||||
@@ -3446,6 +3446,7 @@ fn start_service_worker_navigation_preload_response_in_context(
|
||||
redirected: started.response_head.redirected,
|
||||
redirect_chain: Vec::new(),
|
||||
from_cache: false,
|
||||
cache_state: Default::default(),
|
||||
negotiated_http_version: None,
|
||||
};
|
||||
let response_object = build_navigation_preload_response_object_from_stream_for_request_mode(
|
||||
|
||||
Reference in New Issue
Block a user