1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
// Copyright 2018 The Chromium Authors
// 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/memory/raw_ptr.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/thread_annotations.h"
#include "components/cronet/cronet_context.h"
#include "components/cronet/cronet_url_request.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 CronetContext.
class Cronet_UrlRequestImpl : public Cronet_UrlRequest {
public:
Cronet_UrlRequestImpl();
Cronet_UrlRequestImpl(const Cronet_UrlRequestImpl&) = delete;
Cronet_UrlRequestImpl& operator=(const Cronet_UrlRequestImpl&) = delete;
~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();
// Reports metrics if metrics were collected, otherwise does nothing. This
// method should only be called once on Callback's executor thread and before
// Callback's OnSucceeded, OnFailed and OnCanceled.
//
// Adds |finished_reason| to the reported RequestFinishedInfo. Also passes
// pointers to |response_info_| and |error_|.
//
// Also, the field |annotations_| is moved into the RequestFinishedInfo.
//
// |finished_reason|: Success / fail / cancel status of request.
void MaybeReportMetrics(
Cronet_RequestFinishedInfo_FINISHED_REASON finished_reason);
// 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.
raw_ptr<NetworkTasks, AcrossTasksDanglingUntriaged> network_tasks_
GUARDED_BY(lock_) = nullptr;
// Cronet URLRequest used for this operation.
raw_ptr<CronetURLRequest, AcrossTasksDanglingUntriaged> 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_);
// Report containing metrics and other information to send to attached
// RequestFinishedListener(s). A nullptr value indicates that metrics haven't
// been collected.
//
// Ownership is shared since we guarantee that the RequestFinishedInfo will
// be valid if its UrlRequest isn't destroyed. We also guarantee that it's
// valid in RequestFinishedListener.OnRequestFinished() even if the
// UrlRequest is destroyed (and furthermore, each listener finishes at
// different times).
//
// NOTE: this field isn't protected by |lock_| since we pass this field as a
// unowned pointer to OnRequestFinished(). The pointee of this field cannot
// be updated after that call is made.
scoped_refptr<base::RefCountedData<Cronet_RequestFinishedInfo>>
request_finished_info_;
// Annotations passed via UrlRequestParams.annotations. These annotations
// aren't used by Cronet itself -- they're just moved into the
// RequestFinishedInfo passed to RequestFinishedInfoListener instances.
std::vector<Cronet_RawDataPtr> annotations_;
// 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.
//
// Ownership is shared since we guarantee that the UrlResponseInfo will
// be valid if its UrlRequest isn't destroyed. We also guarantee that it's
// valid in RequestFinishedListener.OnRequestFinished() even if the
// UrlRequest is destroyed (and furthermore, each listener finishes at
// different times).
//
// NOTE: the synchronization of this field is complex -- it can't be
// completely protected by |lock_| since we pass this field as a unowned
// pointer to OnSucceed(), OnFailed(), and OnCanceled(). The pointee of this
// field cannot be updated after one of those callback calls is made.
scoped_refptr<base::RefCountedData<Cronet_UrlResponseInfo>> response_info_;
// The error reported by request. May be nullptr if no error has occurred.
//
// Ownership is shared since we guarantee that the Error will be valid if its
// UrlRequest isn't destroyed. We also guarantee that it's valid in
// RequestFinishedListener.OnRequestFinished() even if the UrlRequest is
// destroyed (and furthermore, each listener finishes at different times).
//
// NOTE: the synchronization of this field is complex -- it can't be
// completely protected by |lock_| since we pass this field as an unowned
// pointer to OnSucceed(), OnFailed(), and OnCanceled(). The pointee of this
// field cannot be updated after one of those callback calls is made.
scoped_refptr<base::RefCountedData<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.
raw_ptr<Cronet_EngineImpl> engine_ = nullptr;
#if DCHECK_IS_ON()
// Event indicating Executor is properly destroying Runnables.
base::WaitableEvent runnable_destroyed_;
#endif // DCHECK_IS_ON()
};
} // namespace cronet
#endif // COMPONENTS_CRONET_NATIVE_URL_REQUEST_H_
|