chromium/chrome/browser/preloading/prefetch/search_prefetch/streaming_search_prefetch_url_loader.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_PRELOADING_PREFETCH_SEARCH_PREFETCH_STREAMING_SEARCH_PREFETCH_URL_LOADER_H_
#define CHROME_BROWSER_PRELOADING_PREFETCH_SEARCH_PREFETCH_STREAMING_SEARCH_PREFETCH_URL_LOADER_H_

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_request.h"
#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_url_loader.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_response_head.mojom-forward.h"

// This class starts a search prefetch and is able to serve it once headers are
// received. This allows streaming the response from memory as the response
// finishes from the network. The class drains the network request URL Loader,
// and creates a data pipe to handoff, so it may close the network URL Loader
// after the read from the network is done.
// The ownership of this instance is quite complicated. Its owners can be:
// - `SearchPrefetchRequest::streaming_url_loader_`: the request uses this
//   instance for fetching, and keeps an reference to the
//   `StreamingSearchPrefetchURLLoader` so as to allow SearchPrefetchService to
//   take the fetched responses.
// - `StreamingSearchPrefetchURLLoader::self_pointer_`: This instance is serving
//   to a real navigation, so it is owned by itself, and the Mojo connection
//   would manage its lifetime.
// - `StreamingSearchPrefetchURLLoader::ResponseReader::loader_`: This instance
//   is serving to a prerender navigation, so it  is owned by the ResponseReader
//   that is reading its response, and the Mojo connection would manage its
//   lifetime.
// To summarize, it can be:
// | Case            | owned by Request | Owned by self | Owned by Reader |
// | --------------- | ---------------- | ------------- | --------------- |
// | Not serving     | YES              | NO            | NO              |
// | ----------------|------------------|---------------|-----------------|
// | Serving to      |                  |               |                 |
// | real navigation | NO               | YES           | NO              |
// | ----------------|------------------|---------------|-----------------|
// | Serving to      |                  |               |                 |
// | prerender navi  | NO/YES *1        | NO            | YES             |
// | ----------------|------------------|---------------|-----------------|
// | Serving to      |                  |               |                 |
// | both navi *2    | NO               | YES           | YES             |
// *0: During serving, the references may be owned by callbacks in the
//     navigation stack. The pointer would be destroyed (once the callback is
//     destroyed) or transited to this instance/a reader soon.
// *1: It depends on whether the response has been deleted or not.
//     This is because, for example, if the response is about to expire, it
//     should still serve all content to the prerender navigation, as the
//     prerender navigation might be used by a real navigation.
// *2: Though it is also possible that the prerender navigation is used by a
//     real navigation, this case only consider the condition that
//     SearchPrefetchURLLoaderInterceptor directly intercepts a real navigation.
class StreamingSearchPrefetchURLLoader
    : public network::mojom::URLLoader,
      public network::mojom::URLLoaderClient,
      public SearchPrefetchURLLoader,
      public mojo::DataPipeDrainer::Client,
      public base::RefCounted<StreamingSearchPrefetchURLLoader> {};

#endif  // CHROME_BROWSER_PRELOADING_PREFETCH_SEARCH_PREFETCH_STREAMING_SEARCH_PREFETCH_URL_LOADER_H_