mirror of
https://github.com/lexmount/moli.git
synced 2026-10-31 00:06:19 +00:00
fix(fetch): classify 101 as final in response timing
Reuse the existing interim status predicate in buffered, HTML and raw collectors so Switching Protocols starts the final response timeline. Cover 101 alone and after 103 across all collectors, plus HTML header completion.
This commit is contained in:
@@ -1078,7 +1078,7 @@ impl Handler for ResponseCollector {
|
||||
self.status_text = Some(parsed.status_text);
|
||||
self.body.clear();
|
||||
if let Some(progress) = &self.response_progress {
|
||||
if parsed.status < 200 {
|
||||
if is_interim_response_status(parsed.status) {
|
||||
progress.mark_interim_response_started();
|
||||
} else {
|
||||
progress.mark_response_started();
|
||||
@@ -1155,7 +1155,7 @@ impl Handler for StreamingResponseCollector {
|
||||
self.declared_identity_body_length = None;
|
||||
self.response_too_large = false;
|
||||
self.cookie_set_reports.clear();
|
||||
if self.status < 200 {
|
||||
if is_interim_response_status(self.status) {
|
||||
self.response_progress.mark_interim_response_started();
|
||||
} else {
|
||||
self.response_progress.mark_response_started();
|
||||
@@ -1233,10 +1233,10 @@ impl Handler for RawStreamingResponseCollector {
|
||||
self.response_bytes_received = 0;
|
||||
self.response_too_large = false;
|
||||
self.cookie_set_reports.clear();
|
||||
if self.status >= 200 {
|
||||
self.response_progress.mark_response_started();
|
||||
} else {
|
||||
if is_interim_response_status(self.status) {
|
||||
self.response_progress.mark_interim_response_started();
|
||||
} else {
|
||||
self.response_progress.mark_response_started();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -177,6 +177,7 @@ async fn html_response_timing_records_terminal_failures() -> Result<()> {
|
||||
#[tokio::test]
|
||||
async fn html_response_timing_finishes_bodyless_responses_at_headers() -> Result<()> {
|
||||
for (method, headers) in [
|
||||
("GET", "HTTP/1.1 101 Switching Protocols\r\n"),
|
||||
("GET", "HTTP/1.1 204 No Content\r\n"),
|
||||
("GET", "HTTP/1.1 205 Reset Content\r\n"),
|
||||
("GET", "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n"),
|
||||
@@ -328,3 +329,56 @@ async fn html_declared_body_completion_precedes_delivery_of_the_last_chunk() ->
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn switching_protocols_timing_is_final_in_every_collector() {
|
||||
for interim in [false, true] {
|
||||
for mode in ["buffered", "html", "raw"] {
|
||||
let cancel = FetchCancelHandle::new();
|
||||
let mut handler = match mode {
|
||||
"buffered" => {
|
||||
FetchTransferHandler::new_buffered(ResponseCollector::new(Some(cancel.clone())))
|
||||
}
|
||||
"html" => {
|
||||
let (start_tx, _start_rx) = oneshot::channel();
|
||||
let (body_tx, _body_rx) = mpsc::unbounded_channel();
|
||||
FetchTransferHandler::new_streaming(StreamingResponseCollector::new(
|
||||
new_shared_browser_cookie_store(),
|
||||
start_tx,
|
||||
body_tx,
|
||||
cancel.clone(),
|
||||
))
|
||||
}
|
||||
"raw" => {
|
||||
let (start_tx, _start_rx) = oneshot::channel();
|
||||
let (body_tx, _body_rx) = mpsc::unbounded_channel();
|
||||
FetchTransferHandler::new_raw_streaming(RawStreamingResponseCollector::new(
|
||||
new_shared_browser_cookie_store(),
|
||||
start_tx,
|
||||
body_tx,
|
||||
cancel.clone(),
|
||||
))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if interim {
|
||||
assert!(handler.header(b"HTTP/1.1 103 Early Hints\r\n"));
|
||||
assert!(cancel.response_timing().response_started_at().is_none());
|
||||
}
|
||||
assert!(handler.header(b"HTTP/1.1 101 Switching Protocols\r\n"));
|
||||
let timing = cancel.response_timing();
|
||||
assert!(
|
||||
timing.response_started_at().is_some(),
|
||||
"{mode}: 101 must be final"
|
||||
);
|
||||
assert_eq!(
|
||||
timing.first_interim_response_started_at().is_some(),
|
||||
interim,
|
||||
"{mode}"
|
||||
);
|
||||
if let Some(first_interim) = timing.first_interim_response_started_at() {
|
||||
assert!(first_interim <= timing.response_started_at().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user