Repository: servo/servo
File: components/net/fetch/methods.rs (Rust)

Code before:
    pub cancellation_listener: Arc<CancellationListener>,
    pub timing: ServoArc<Mutex<ResourceFetchTiming>>,
    pub protocols: Arc<ProtocolRegistry>,
    pub websocket_chan: Option<Arc<Mutex<WebSocketChannel>>>,
    pub ca_certificates: CACertificates,
    pub ignore_certificate_errors: bool,
}

#[derive(Default)]
pub struct CancellationListener {
    cancelled: AtomicBool,
}

impl CancellationListener {
    pub(crate) fn cancelled(&self) -> bool {
        self.cancelled.load(Ordering::Relaxed)
    }

    pub(crate) fn cancel(&self) {
        self.cancelled.store(true, Ordering::Relaxed)
    }
}
pub type DoneChannel = Option<(TokioSender<Data>, TokioReceiver<Data>)>;

pub struct FetchResponseCollector {
    pub sender: Option<tokio::sync::oneshot::Sender<Response>>,
}

impl FetchTaskTarget for FetchResponseCollector {
    fn process_request_body(&mut self, _: &Request) {}
    fn process_request_eof(&mut self, _: &Request) {}
    fn process_response(&mut self, _: &Request, _: &Response) {}
    fn process_response_chunk(&mut self, _: &Request, _: Vec<u8>) {}
    /// Fired when the response is fully fetched
    fn process_response_eof(&mut self, _: &Request, response: &Response) {
        let Some(sender) = self.sender.take() else {
            return;
        };
        let _ = sender.send(response.clone());
    }
    fn process_csp_violations(&mut self, _: &Request, _: Vec<csp::Violation>) {}
}

/// [Fetch](https://fetch.spec.whatwg.org#concept-fetch)
pub async fn fetch(request: Request, target: Target<'_>, context: &FetchContext) -> Response {
    // Steps 7,4 of https://w3c.github.io/resource-timing/#processing-model
    // rev order okay since spec says they're equal - https://w3c.github.io/resource-timing/#dfn-starttime
    {
        let mut timing_guard = context.timing.lock();
        timing_guard.set_attribute(ResourceAttribute::FetchStart);
        timing_guard.set_attribute(ResourceAttribute::StartTime(ResourceTimeValue::FetchStart));

Review comment (suggestion):
```suggestion
pub(crate) struct FetchResponseCollector {
    pub(crate) sender: Option<tokio::sync::oneshot::Sender<Response>>,
```

Code after:
    pub cancellation_listener: Arc<CancellationListener>,
    pub timing: ServoArc<Mutex<ResourceFetchTiming>>,
    pub protocols: Arc<ProtocolRegistry>,
    pub websocket_chan: Option<Arc<Mutex<WebSocketChannel>>>,
    pub ca_certificates: CACertificates,
    pub ignore_certificate_errors: bool,
}

#[derive(Default)]
pub struct CancellationListener {
    cancelled: AtomicBool,
}

impl CancellationListener {
    pub(crate) fn cancelled(&self) -> bool {
        self.cancelled.load(Ordering::Relaxed)
    }

    pub(crate) fn cancel(&self) {
        self.cancelled.store(true, Ordering::Relaxed)
    }
}
pub type DoneChannel = Option<(TokioSender<Data>, TokioReceiver<Data>)>;

/// [Fetch](https://fetch.spec.whatwg.org#concept-fetch)
pub async fn fetch(request: Request, target: Target<'_>, context: &FetchContext) -> Response {
    // Steps 7,4 of https://w3c.github.io/resource-timing/#processing-model
    // rev order okay since spec says they're equal - https://w3c.github.io/resource-timing/#dfn-starttime
    {
        let mut timing_guard = context.timing.lock();
        timing_guard.set_attribute(ResourceAttribute::FetchStart);
        timing_guard.set_attribute(ResourceAttribute::StartTime(ResourceTimeValue::FetchStart));
    }
    fetch_with_cors_cache(request, &mut CorsCache::default(), target, context).await
}

/// Continuation of fetch from step 8.
///
/// <https://fetch.spec.whatwg.org#concept-fetch>
pub async fn fetch_with_cors_cache(
    request: Request,
    cache: &mut CorsCache,
    target: Target<'_>,
    context: &FetchContext,
) -> Response {
    // Step 8. Let fetchParams be a new fetch params whose request is request
    let mut fetch_params = FetchParams::new(request);
    let request = &mut fetch_params.request;

    // Step 4. Populate request from client given request.
    request.populate_request_from_client();