| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESPONSE_BODY_LOADER_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESPONSE_BODY_LOADER_H_ |
| |
| #include "base/containers/span.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "mojo/public/cpp/system/data_pipe.h" |
| #include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom-blink-forward.h" |
| #include "third_party/blink/public/platform/web_back_forward_cache_loader_helper.h" |
| #include "third_party/blink/public/platform/web_url_loader.h" |
| #include "third_party/blink/renderer/platform/heap/garbage_collected.h" |
| #include "third_party/blink/renderer/platform/heap/member.h" |
| #include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h" |
| #include "third_party/blink/renderer/platform/loader/fetch/response_body_loader_client.h" |
| #include "third_party/blink/renderer/platform/platform_export.h" |
| #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" |
| #include "third_party/blink/renderer/platform/wtf/vector.h" |
| |
| namespace base { |
| class SingleThreadTaskRunner; |
| } // namespace base |
| |
| namespace blink { |
| |
| class BackForwardCacheLoaderHelper; |
| class ResponseBodyLoader; |
| |
| // See ResponseBodyLoader for details. This is a virtual interface to expose |
| // only Drain functions. |
| class PLATFORM_EXPORT ResponseBodyLoaderDrainableInterface |
| : public GarbageCollected<ResponseBodyLoaderDrainableInterface> { |
| public: |
| virtual ~ResponseBodyLoaderDrainableInterface() = default; |
| |
| // Drains the response body and returns it. This function must not be called |
| // when the load has already been started or aborted, or the body has already |
| // been drained. This function may return an invalid handle when it is |
| // unable to convert the body to a data pipe, even when the body itself is |
| // valid. In that case, this function is no-op. If this function returns a |
| // valid handle, the caller is responsible for reading the body and providing |
| // the information to the client this function provides. |
| // Note that the notification from the client is *synchronously* propergated |
| // to the original client ResponseBodyLoader owns, e.g., when the caller |
| // calls ResponseBodyLoaderClient::DidCancelLoadingBody, it synchronously |
| // cancels the resource loading (if |this| is associated with |
| // blink::ResourceLoader). A user of this function should ensure that calling |
| // the client's method doesn't lead to a reentrant problem. |
| virtual mojo::ScopedDataPipeConsumerHandle DrainAsDataPipe( |
| ResponseBodyLoaderClient** client) = 0; |
| |
| // Drains the response body and returns it. This function must not be called |
| // when the load has already been started or aborted, or the body has already |
| // been drained. Unlike DrainAsDataPipe, this function always succeeds. |
| // This ResponseBodyLoader will still monitor the loading signals, and report |
| // them back to the associated client asynchronously. |
| virtual BytesConsumer& DrainAsBytesConsumer() = 0; |
| |
| virtual void Trace(Visitor*) const {} |
| }; |
| |
| // ResponseBodyLoader reads the response body and reports the contents to the |
| // associated client. There are two ways: |
| // - By calling Start(), ResponseBodyLoader reads the response body. and |
| // reports the contents to the client. Abort() aborts reading. |
| // - By calling DrainAsDataPipe, a user can "drain" the contents from |
| // ResponseBodyLoader. The caller is responsible for reading the body and |
| // providing the information to the client this function provides. |
| // - By calling DrainBytesConsumer, a user can "drain" the contents from |
| // ResponseBodyLoader. |
| // A ResponseBodyLoader is bound to the thread on which it is created. |
| class PLATFORM_EXPORT ResponseBodyLoader final |
| : public ResponseBodyLoaderDrainableInterface, |
| private ResponseBodyLoaderClient, |
| private BytesConsumer::Client { |
| public: |
| ResponseBodyLoader( |
| BytesConsumer&, |
| ResponseBodyLoaderClient&, |
| scoped_refptr<base::SingleThreadTaskRunner>, |
| BackForwardCacheLoaderHelper* back_forward_cache_loader_helper); |
| |
| // ResponseBodyLoaderDrainableInterface implementation. |
| mojo::ScopedDataPipeConsumerHandle DrainAsDataPipe( |
| ResponseBodyLoaderClient**) override; |
| BytesConsumer& DrainAsBytesConsumer() override; |
| |
| // Starts loading. |
| void Start(); |
| |
| // Aborts loading. This is expected to be called from the client's side, and |
| // does not report the failure to the client. This doesn't affect a |
| // drained data pipe. This function cannot be called when suspended. |
| void Abort(); |
| |
| // Suspends loading. |
| void Suspend(WebURLLoader::DeferType suspended_state); |
| |
| // Resumes loading. |
| void Resume(); |
| |
| bool IsAborted() const { return aborted_; } |
| bool IsSuspended() const { |
| return suspended_state_ != WebURLLoader::DeferType::kNotDeferred; |
| } |
| bool IsSuspendedForBackForwardCache() const { |
| return suspended_state_ == |
| WebURLLoader::DeferType::kDeferredWithBackForwardCache; |
| } |
| bool IsDrained() const { return drained_; } |
| |
| void EvictFromBackForwardCacheIfDrained(); |
| |
| void Trace(Visitor*) const override; |
| |
| // The maximal number of bytes consumed in a task. When there are more bytes |
| // in the data pipe, they will be consumed in following tasks. Setting a too |
| // small number will generate ton of tasks but setting a too large number will |
| // lead to thread janks. Also, some clients cannot handle too large chunks |
| // (512k for example). |
| static constexpr size_t kMaxNumConsumedBytesInTask = 64 * 1024; |
| |
| private: |
| class Buffer; |
| class DelegatingBytesConsumer; |
| |
| // ResponseBodyLoaderClient implementation. |
| void DidReceiveData(base::span<const char> data) override; |
| void DidFinishLoadingBody() override; |
| void DidFailLoadingBody() override; |
| void DidCancelLoadingBody() override; |
| void EvictFromBackForwardCache(mojom::blink::RendererEvictionReason); |
| void DidBufferLoadWhileInBackForwardCache(size_t num_bytes); |
| bool CanContinueBufferingWhileInBackForwardCache(); |
| |
| // BytesConsumer::Client implementation. |
| void OnStateChange() override; |
| String DebugName() const override { return "ResponseBodyLoader"; } |
| |
| Member<Buffer> body_buffer_; |
| Member<BytesConsumer> bytes_consumer_; |
| Member<DelegatingBytesConsumer> delegating_bytes_consumer_; |
| const Member<ResponseBodyLoaderClient> client_; |
| WeakMember<BackForwardCacheLoaderHelper> back_forward_cache_loader_helper_; |
| const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| WebURLLoader::DeferType suspended_state_ = |
| WebURLLoader::DeferType::kNotDeferred; |
| bool started_ = false; |
| bool aborted_ = false; |
| bool drained_ = false; |
| bool finish_signal_is_pending_ = false; |
| bool fail_signal_is_pending_ = false; |
| bool cancel_signal_is_pending_ = false; |
| bool in_two_phase_read_ = false; |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESPONSE_BODY_LOADER_H_ |