Skip to main content

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_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        if let Some(request_id) = self.request_id.take() {
55            // stop trying to make fetch happen
56            // it's not going to happen
57
58            if let Some(ref core_resource_thread) = self.core_resource_thread {
59                // No error handling here. Cancellation is a courtesy call,
60                // we don't actually care if the other side heard.
61                cancel_async_fetch(vec![request_id], core_resource_thread);
62            }
63        }
64    }
65
66    /// Use this if you don't want it to send a cancellation request
67    /// on drop (e.g. if the fetch completes)
68    pub fn ignore(&mut self) {
69        let _ = self.request_id.take();
70    }
71
72    /// <https://fetch.spec.whatwg.org/#fetch-controller-abort>
73    pub fn abort(&mut self) {
74        // Step 1. Set controller’s state to "aborted".
75        self.state = FetchControllerState::Aborted;
76
77        self.cancel();
78    }
79
80    /// <https://fetch.spec.whatwg.org/#fetch-controller-terminate>
81    pub fn terminate(&mut self) {
82        // > To terminate a fetch controller controller,
83        // > set controller’s state to "terminated".
84        self.state = FetchControllerState::Terminated;
85
86        self.cancel();
87    }
88}