1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_CRONET_NATIVE_URL_REQUEST_H_ 6 #define COMPONENTS_CRONET_NATIVE_URL_REQUEST_H_ 7 8 #include <memory> 9 #include <string> 10 #include <unordered_set> 11 12 #include "base/macros.h" 13 #include "base/synchronization/lock.h" 14 #include "base/synchronization/waitable_event.h" 15 #include "base/thread_annotations.h" 16 #include "components/cronet/cronet_url_request.h" 17 #include "components/cronet/cronet_url_request_context.h" 18 #include "components/cronet/native/generated/cronet.idl_impl_interface.h" 19 20 namespace net { 21 enum LoadState; 22 } // namespace net 23 24 namespace cronet { 25 26 class Cronet_EngineImpl; 27 class Cronet_UploadDataSinkImpl; 28 29 // Implementation of Cronet_UrlRequest that uses CronetURLRequestContext. 30 class Cronet_UrlRequestImpl : public Cronet_UrlRequest { 31 public: 32 Cronet_UrlRequestImpl(); 33 ~Cronet_UrlRequestImpl() override; 34 35 // Cronet_UrlRequest 36 Cronet_RESULT InitWithParams(Cronet_EnginePtr engine, 37 Cronet_String url, 38 Cronet_UrlRequestParamsPtr params, 39 Cronet_UrlRequestCallbackPtr callback, 40 Cronet_ExecutorPtr executor) override; 41 Cronet_RESULT Start() override; 42 Cronet_RESULT FollowRedirect() override; 43 Cronet_RESULT Read(Cronet_BufferPtr buffer) override; 44 void Cancel() override; 45 bool IsDone() override; 46 void GetStatus(Cronet_UrlRequestStatusListenerPtr listener) override; 47 48 // Upload data provider has reported error while reading or rewinding 49 // so request must fail. 50 void OnUploadDataProviderError(const std::string& error_message); 51 52 private: 53 class NetworkTasks; 54 55 // Return |true| if request has started and is now done. 56 // Must be called under |lock_| held. 57 bool IsDoneLocked() const SHARED_LOCKS_REQUIRED(lock_); 58 59 // Helper method to set final status of CronetUrlRequest and clean up the 60 // native request adapter. Returns true if request is already done, false 61 // request is not done and is destroyed. 62 bool DestroyRequestUnlessDone( 63 Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason); 64 65 // Helper method to set final status of CronetUrlRequest and clean up the 66 // native request adapter. Returns true if request is already done, false 67 // request is not done and is destroyed. Must be called under |lock_| held. 68 bool DestroyRequestUnlessDoneLocked( 69 Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason) 70 EXCLUSIVE_LOCKS_REQUIRED(lock_); 71 72 // Helper method to post |task| to the |executor_|. 73 void PostTaskToExecutor(base::OnceClosure task); 74 75 // Helper methods to invoke application |callback_|. 76 void InvokeCallbackOnRedirectReceived(const std::string& new_location); 77 void InvokeCallbackOnResponseStarted(); 78 void InvokeCallbackOnReadCompleted( 79 std::unique_ptr<Cronet_Buffer> cronet_buffer, 80 int bytes_read); 81 void InvokeCallbackOnSucceeded(); 82 void InvokeCallbackOnFailed(); 83 void InvokeCallbackOnCanceled(); 84 85 // Runs InvokeCallbackOnFailed() on the client executor. 86 void PostCallbackOnFailedToExecutor(); 87 88 // Invoke all members of |status_listeners_|. Should be called prior to 89 // invoking a final callback. Once a final callback has been called, |this| 90 // and |executor_| may be deleted and so the callbacks cannot be issued. 91 void InvokeAllStatusListeners(); 92 93 // Reports metrics if metrics were collected, otherwise does nothing. This 94 // method should only be called once on Callback's executor thread and before 95 // Callback's OnSucceeded, OnFailed and OnCanceled. 96 // 97 // Adds |finished_reason| to the reported RequestFinishedInfo. Also passes 98 // pointers to |response_info_| and |error_|. 99 // 100 // Also, the field |annotations_| is moved into the RequestFinishedInfo. 101 // 102 // |finished_reason|: Success / fail / cancel status of request. 103 void MaybeReportMetrics( 104 Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason); 105 106 // Synchronize access to |request_| and other objects below from different 107 // threads. 108 base::Lock lock_; 109 // NetworkTask object lives on the network thread. Owned by |request_|. 110 // Outlives this. 111 NetworkTasks* network_tasks_ GUARDED_BY(lock_) = nullptr; 112 // Cronet URLRequest used for this operation. 113 CronetURLRequest* request_ GUARDED_BY(lock_) = nullptr; 114 bool started_ GUARDED_BY(lock_) = false; 115 bool waiting_on_redirect_ GUARDED_BY(lock_) = false; 116 bool waiting_on_read_ GUARDED_BY(lock_) = false; 117 // Set of status_listeners_ that have not yet been called back. 118 std::unordered_multiset<Cronet_UrlRequestStatusListenerPtr> status_listeners_ 119 GUARDED_BY(lock_); 120 121 // Report containing metrics and other information to send to attached 122 // RequestFinishedListener(s). A nullptr value indicates that metrics haven't 123 // been collected. 124 // 125 // Ownership is shared since we guarantee that the RequestFinishedInfo will 126 // be valid if its UrlRequest isn't destroyed. We also guarantee that it's 127 // valid in RequestFinishedListener.OnRequestFinished() even if the 128 // UrlRequest is destroyed (and furthermore, each listener finishes at 129 // different times). 130 // 131 // NOTE: this field isn't protected by |lock_| since we pass this field as a 132 // unowned pointer to OnRequestFinished(). The pointee of this field cannot 133 // be updated after that call is made. 134 scoped_refptr<base::RefCountedData<Cronet_RequestFinishedInfo>> 135 request_finished_info_; 136 137 // Annotations passed via UrlRequestParams.annotations. These annotations 138 // aren't used by Cronet itself -- they're just moved into the 139 // RequestFinishedInfo passed to RequestFinishedInfoListener instances. 140 std::vector<Cronet_RawDataPtr> annotations_; 141 142 // Optional; allows a listener to receive request info and stats. 143 // 144 // A nullptr value indicates that there is no RequestFinishedInfo listener 145 // specified for the request (however, the Engine may have additional 146 // listeners -- Engine listeners apply to all its UrlRequests). 147 // 148 // Owned by the app -- must outlive this UrlRequest. 149 Cronet_RequestFinishedInfoListenerPtr request_finished_listener_ = nullptr; 150 151 // Executor upon which |request_finished_listener_| will run. If 152 // |request_finished_listener_| is not nullptr, this won't be nullptr either. 153 // 154 // Owned by the app -- must outlive this UrlRequest. 155 Cronet_ExecutorPtr request_finished_executor_ = nullptr; 156 157 // Response info updated by callback with number of bytes received. May be 158 // nullptr, if no response has been received. 159 // 160 // Ownership is shared since we guarantee that the UrlResponseInfo will 161 // be valid if its UrlRequest isn't destroyed. We also guarantee that it's 162 // valid in RequestFinishedListener.OnRequestFinished() even if the 163 // UrlRequest is destroyed (and furthermore, each listener finishes at 164 // different times). 165 // 166 // NOTE: the synchronization of this field is complex -- it can't be 167 // completely protected by |lock_| since we pass this field as a unowned 168 // pointer to OnSucceed(), OnFailed(), and OnCanceled(). The pointee of this 169 // field cannot be updated after one of those callback calls is made. 170 scoped_refptr<base::RefCountedData<Cronet_UrlResponseInfo>> response_info_; 171 172 // The error reported by request. May be nullptr if no error has occurred. 173 // 174 // Ownership is shared since we guarantee that the Error will be valid if its 175 // UrlRequest isn't destroyed. We also guarantee that it's valid in 176 // RequestFinishedListener.OnRequestFinished() even if the UrlRequest is 177 // destroyed (and furthermore, each listener finishes at different times). 178 // 179 // NOTE: the synchronization of this field is complex -- it can't be 180 // completely protected by |lock_| since we pass this field as an unowned 181 // pointer to OnSucceed(), OnFailed(), and OnCanceled(). The pointee of this 182 // field cannot be updated after one of those callback calls is made. 183 scoped_refptr<base::RefCountedData<Cronet_Error>> error_; 184 185 // The upload data stream if specified. 186 std::unique_ptr<Cronet_UploadDataSinkImpl> upload_data_sink_; 187 188 // Application callback interface, used, but not owned, by |this|. 189 Cronet_UrlRequestCallbackPtr callback_ = nullptr; 190 // Executor for application callback, used, but not owned, by |this|. 191 Cronet_ExecutorPtr executor_ = nullptr; 192 193 // Cronet Engine used to run network operations. Not owned, accessed from 194 // client thread. Must outlive this request. 195 Cronet_EngineImpl* engine_ = nullptr; 196 197 #if DCHECK_IS_ON() 198 // Event indicating Executor is properly destroying Runnables. 199 base::WaitableEvent runnable_destroyed_; 200 #endif // DCHECK_IS_ON() 201 202 DISALLOW_COPY_AND_ASSIGN(Cronet_UrlRequestImpl); 203 }; 204 205 } // namespace cronet 206 207 #endif // COMPONENTS_CRONET_NATIVE_URL_REQUEST_H_ 208