Files
brave-core/components/speedreader/speedreader_url_loader.h
T
Kevin Kuehler ce90b1e434 speedreader: Pass result correctly for CR94
Prior to CR94 we were able to assume that the URLLoaderThrottle would
outlive the URLLoader. This is no longer the case, so we pass the
result_delegate_ to the loader.

Resolves https://github.com/brave/brave-browser/issues/18151
2021-09-15 23:45:10 -07:00

165 lines
7.0 KiB
C++

/* Copyright 2020 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_URL_LOADER_H_
#define BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_URL_LOADER_H_
#include <string>
#include <tuple>
#include <vector>
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece.h"
#include "brave/components/speedreader/speedreader_result_delegate.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/simple_watcher.h"
#include "services/network/public/mojom/early_hints.mojom-forward.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom-forward.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace speedreader {
class SpeedReaderThrottle;
class SpeedreaderRewriterService;
// Loads the whole response body and tries to Speedreader-distill it.
// Cargoculted from |`SniffingURLLoader|.
//
// This loader has five states:
// kWaitForBody: The initial state until the body is received (=
// OnStartLoadingResponseBody() is called) or the response is
// finished (= OnComplete() is called). When body is provided, the
// state is changed to kLoading. Otherwise the state goes to
// kCompleted.
// kLoading: Receives the body from the source loader and distills the page.
// The received body is kept in this loader until distilling
// is finished. When all body has been received and distilling is
// done, this loader will dispatch queued messages like
// OnStartLoadingResponseBody() to the destination
// loader client, and then the state is changed to kSending.
// kSending: Receives the body and sends it to the destination loader client.
// The state changes to kCompleted after all data is sent.
// kCompleted: All data has been sent to the destination loader.
// kAborted: Unexpected behavior happens. Watchers, pipes and the binding from
// the source loader to |this| are stopped. All incoming messages from
// the destination (through network::mojom::URLLoader) are ignored in
class SpeedReaderURLLoader : public network::mojom::URLLoaderClient,
public network::mojom::URLLoader {
public:
~SpeedReaderURLLoader() override;
SpeedReaderURLLoader(const SpeedReaderURLLoader&) = delete;
SpeedReaderURLLoader& operator=(const SpeedReaderURLLoader&) = delete;
// Start waiting for the body.
void Start(
mojo::PendingRemote<network::mojom::URLLoader> source_url_loader_remote,
mojo::PendingReceiver<network::mojom::URLLoaderClient>
source_url_client_receiver);
// mojo::PendingRemote<network::mojom::URLLoader> controls the lifetime of the
// loader.
static std::tuple<mojo::PendingRemote<network::mojom::URLLoader>,
mojo::PendingReceiver<network::mojom::URLLoaderClient>,
SpeedReaderURLLoader*>
CreateLoader(base::WeakPtr<SpeedReaderThrottle> throttle,
base::WeakPtr<SpeedreaderResultDelegate> delegate,
const GURL& response_url,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
SpeedreaderRewriterService* rewriter_service);
private:
SpeedReaderURLLoader(base::WeakPtr<SpeedReaderThrottle> throttle,
base::WeakPtr<SpeedreaderResultDelegate> delegate,
const GURL& response_url,
mojo::PendingRemote<network::mojom::URLLoaderClient>
destination_url_loader_client,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
SpeedreaderRewriterService* rewriter_service);
// network::mojom::URLLoaderClient implementation (called from the source of
// the response):
void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
void OnReceiveResponse(
network::mojom::URLResponseHeadPtr response_head) override;
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
network::mojom::URLResponseHeadPtr response_head) override;
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback ack_callback) override;
void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override;
void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus& status) override;
// network::mojom::URLLoader implementation (called from the destination of
// the response):
void FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers,
const absl::optional<GURL>& new_url) override;
void SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) override;
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
void OnBodyReadable(MojoResult);
void OnBodyWritable(MojoResult);
void MaybeLaunchSpeedreader();
// Gets either distilled or untouched body.
void CompleteLoading(std::string body);
void CompleteSending();
void SendReceivedBodyToClient();
void Abort();
base::WeakPtr<SpeedReaderThrottle> throttle_;
base::WeakPtr<SpeedreaderResultDelegate> delegate_;
mojo::Receiver<network::mojom::URLLoaderClient> source_url_client_receiver_{
this};
mojo::Remote<network::mojom::URLLoader> source_url_loader_;
mojo::Remote<network::mojom::URLLoaderClient> destination_url_loader_client_;
GURL response_url_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
enum class State { kWaitForBody, kLoading, kSending, kCompleted, kAborted };
State state_ = State::kWaitForBody;
// Set if OnComplete() is called during distilling.
absl::optional<network::URLLoaderCompletionStatus> complete_status_;
// Note that this could be replaced by a distilled version.
std::string buffered_body_;
size_t bytes_remaining_in_buffer_;
mojo::ScopedDataPipeConsumerHandle body_consumer_handle_;
mojo::ScopedDataPipeProducerHandle body_producer_handle_;
mojo::SimpleWatcher body_consumer_watcher_;
mojo::SimpleWatcher body_producer_watcher_;
// Not Owned
SpeedreaderRewriterService* rewriter_service_;
base::WeakPtrFactory<SpeedReaderURLLoader> weak_factory_{this};
};
} // namespace speedreader
#endif // BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_URL_LOADER_H_