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}