| // Copyright 2018 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 COMPONENTS_CRONET_NATIVE_URL_REQUEST_H_ |
| #define COMPONENTS_CRONET_NATIVE_URL_REQUEST_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <unordered_set> |
| |
| #include "base/macros.h" |
| #include "base/synchronization/lock.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "base/thread_annotations.h" |
| #include "components/cronet/cronet_url_request.h" |
| #include "components/cronet/cronet_url_request_context.h" |
| #include "components/cronet/native/generated/cronet.idl_impl_interface.h" |
| |
| namespace net { |
| enum LoadState; |
| } // namespace net |
| |
| namespace cronet { |
| |
| class Cronet_EngineImpl; |
| class Cronet_UploadDataSinkImpl; |
| |
| // Implementation of Cronet_UrlRequest that uses CronetURLRequestContext. |
| class Cronet_UrlRequestImpl : public Cronet_UrlRequest { |
| public: |
| Cronet_UrlRequestImpl(); |
| ~Cronet_UrlRequestImpl() override; |
| |
| // Cronet_UrlRequest |
| Cronet_RESULT InitWithParams(Cronet_EnginePtr engine, |
| Cronet_String url, |
| Cronet_UrlRequestParamsPtr params, |
| Cronet_UrlRequestCallbackPtr callback, |
| Cronet_ExecutorPtr executor) override; |
| Cronet_RESULT Start() override; |
| Cronet_RESULT FollowRedirect() override; |
| Cronet_RESULT Read(Cronet_BufferPtr buffer) override; |
| void Cancel() override; |
| bool IsDone() override; |
| void GetStatus(Cronet_UrlRequestStatusListenerPtr listener) override; |
| |
| // Upload data provider has reported error while reading or rewinding |
| // so request must fail. |
| void OnUploadDataProviderError(const std::string& error_message); |
| |
| private: |
| class NetworkTasks; |
| |
| // Return |true| if request has started and is now done. |
| // Must be called under |lock_| held. |
| bool IsDoneLocked() const SHARED_LOCKS_REQUIRED(lock_); |
| |
| // Helper method to set final status of CronetUrlRequest and clean up the |
| // native request adapter. Returns true if request is already done, false |
| // request is not done and is destroyed. |
| bool DestroyRequestUnlessDone( |
| Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason); |
| |
| // Helper method to set final status of CronetUrlRequest and clean up the |
| // native request adapter. Returns true if request is already done, false |
| // request is not done and is destroyed. Must be called under |lock_| held. |
| bool DestroyRequestUnlessDoneLocked( |
| Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason) |
| EXCLUSIVE_LOCKS_REQUIRED(lock_); |
| |
| // Helper method to post |task| to the |executor_|. |
| void PostTaskToExecutor(base::OnceClosure task); |
| |
| // Helper methods to invoke application |callback_|. |
| void InvokeCallbackOnRedirectReceived(const std::string& new_location); |
| void InvokeCallbackOnResponseStarted(); |
| void InvokeCallbackOnReadCompleted( |
| std::unique_ptr<Cronet_Buffer> cronet_buffer, |
| int bytes_read); |
| void InvokeCallbackOnSucceeded(); |
| void InvokeCallbackOnFailed(); |
| void InvokeCallbackOnCanceled(); |
| |
| // Runs InvokeCallbackOnFailed() on the client executor. |
| void PostCallbackOnFailedToExecutor(); |
| |
| // Invoke all members of |status_listeners_|. Should be called prior to |
| // invoking a final callback. Once a final callback has been called, |this| |
| // and |executor_| may be deleted and so the callbacks cannot be issued. |
| void InvokeAllStatusListeners(); |
| |
| // Synchronize access to |request_| and other objects below from different |
| // threads. |
| base::Lock lock_; |
| // NetworkTask object lives on the network thread. Owned by |request_|. |
| // Outlives this. |
| NetworkTasks* network_tasks_ GUARDED_BY(lock_) = nullptr; |
| // Cronet URLRequest used for this operation. |
| CronetURLRequest* request_ GUARDED_BY(lock_) = nullptr; |
| bool started_ GUARDED_BY(lock_) = false; |
| bool waiting_on_redirect_ GUARDED_BY(lock_) = false; |
| bool waiting_on_read_ GUARDED_BY(lock_) = false; |
| // Set of status_listeners_ that have not yet been called back. |
| std::unordered_multiset<Cronet_UrlRequestStatusListenerPtr> status_listeners_ |
| GUARDED_BY(lock_); |
| |
| // Metrics to include in RequestFinishedInfo report sent to attached |
| // RequestFinishedListener(s). A nullptr value indicates that the metrics |
| // haven't been collected. |
| std::unique_ptr<Cronet_Metrics> metrics_ GUARDED_BY(lock_); |
| |
| // Optional; allows a listener to receive request info and stats. |
| // |
| // A nullptr value indicates that there is no RequestFinishedInfo listener |
| // specified for the request (however, the Engine may have additional |
| // listeners -- Engine listeners apply to all its UrlRequests). |
| // |
| // Owned by the app -- must outlive this UrlRequest. |
| Cronet_RequestFinishedInfoListenerPtr request_finished_listener_ = nullptr; |
| |
| // Executor upon which |request_finished_listener_| will run. If |
| // |request_finished_listener_| is not nullptr, this won't be nullptr either. |
| // |
| // Owned by the app -- must outlive this UrlRequest. |
| Cronet_ExecutorPtr request_finished_executor_ = nullptr; |
| |
| // Response info updated by callback with number of bytes received. May be |
| // nullptr, if no response has been received. |
| std::unique_ptr<Cronet_UrlResponseInfo> response_info_; |
| // The error reported by request. May be nullptr if no error has occurred. |
| std::unique_ptr<Cronet_Error> error_; |
| |
| // The upload data stream if specified. |
| std::unique_ptr<Cronet_UploadDataSinkImpl> upload_data_sink_; |
| |
| // Application callback interface, used, but not owned, by |this|. |
| Cronet_UrlRequestCallbackPtr callback_ = nullptr; |
| // Executor for application callback, used, but not owned, by |this|. |
| Cronet_ExecutorPtr executor_ = nullptr; |
| |
| // Cronet Engine used to run network operations. Not owned, accessed from |
| // client thread. Must outlive this request. |
| Cronet_EngineImpl* engine_ = nullptr; |
| |
| #if DCHECK_IS_ON() |
| // Event indicating Executor is properly destroying Runnables. |
| base::WaitableEvent runnable_destroyed_; |
| #endif // DCHECK_IS_ON() |
| |
| DISALLOW_COPY_AND_ASSIGN(Cronet_UrlRequestImpl); |
| }; |
| |
| } // namespace cronet |
| |
| #endif // COMPONENTS_CRONET_NATIVE_URL_REQUEST_H_ |