net_traits/fetch/fetch_controller.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use malloc_size_of_derive::MallocSizeOf;
6
7use crate::request::RequestId;
8use crate::{CoreResourceThread, cancel_and_forget_async_fetch, cancel_async_fetch};
9
10/// <https://fetch.spec.whatwg.org/#fetch-controller-state>
11#[derive(Default, MallocSizeOf, PartialEq)]
12pub enum FetchControllerState {
13 #[default]
14 Ongoing,
15 Terminated,
16 Aborted,
17}
18
19/// Fetch controller object. By default initialized to having a
20/// request associated with it, which can be aborted or terminated.
21/// Calling `ignore` will sever the relationship with the request,
22/// meaning it cannot be cancelled through this controller from that point on.
23/// <https://fetch.spec.whatwg.org/#fetch-controller>
24#[derive(Default, MallocSizeOf)]
25pub struct FetchController {
26 request_id: Option<RequestId>,
27 core_resource_thread: Option<CoreResourceThread>,
28 keep_alive: bool,
29 /// <https://fetch.spec.whatwg.org/#fetch-controller-state>
30 pub state: FetchControllerState,
31}
32
33impl FetchController {
34 /// Create a FetchController associated with a request,
35 /// and a particular(public vs private) resource thread.
36 pub fn new(
37 request_id: RequestId,
38 keep_alive: bool,
39 core_resource_thread: CoreResourceThread,
40 ) -> Self {
41 Self {
42 request_id: Some(request_id),
43 core_resource_thread: Some(core_resource_thread),
44 keep_alive,
45 state: Default::default(),
46 }
47 }
48
49 pub fn keep_alive(&self) -> bool {
50 self.keep_alive
51 }
52
53 fn cancel(&mut self) {
54 // stop trying to make fetch happen
55 // it's not going to happen
56 let Some(request_id) = self.request_id.take() else {
57 return;
58 };
59 let Some(core_resource_thread) = &self.core_resource_thread else {
60 return;
61 };
62
63 if self.state == FetchControllerState::Terminated {
64 cancel_and_forget_async_fetch(vec![request_id], core_resource_thread);
65 } else {
66 cancel_async_fetch(vec![request_id], core_resource_thread);
67 }
68 }
69
70 /// Use this if you don't want it to send a cancellation request
71 /// on drop (e.g. if the fetch completes)
72 pub fn ignore(&mut self) {
73 let _ = self.request_id.take();
74 }
75
76 /// <https://fetch.spec.whatwg.org/#fetch-controller-abort>
77 pub fn abort(&mut self) {
78 // Step 1. Set controller’s state to "aborted".
79 self.state = FetchControllerState::Aborted;
80
81 self.cancel();
82 }
83
84 /// <https://fetch.spec.whatwg.org/#fetch-controller-terminate>
85 pub fn terminate(&mut self) {
86 // > To terminate a fetch controller controller,
87 // > set controller’s state to "terminated".
88 self.state = FetchControllerState::Terminated;
89
90 self.cancel();
91 }
92}