1 // Copyright 2014 The Chromium Authors 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_CRONET_URL_REQUEST_H_ 6 #define COMPONENTS_CRONET_CRONET_URL_REQUEST_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/functional/callback.h" 12 #include "base/memory/raw_ptr.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/time/time.h" 15 #include "net/base/idempotency.h" 16 #include "net/base/network_handle.h" 17 #include "net/base/request_priority.h" 18 #include "net/url_request/url_request.h" 19 #include "url/gurl.h" 20 21 namespace net { 22 class HttpRequestHeaders; 23 enum LoadState; 24 class SSLCertRequestInfo; 25 class SSLInfo; 26 class UploadDataStream; 27 } // namespace net 28 29 namespace cronet { 30 31 class CronetContext; 32 class TestUtil; 33 34 // Wrapper around net::URLRequestContext. 35 // Created and configured from client thread. Start, ReadData, and Destroy are 36 // posted to network thread and all callbacks into the Callback() are 37 // done on the network thread. CronetUrlRequest client is expected to initiate 38 // the next step like FollowDeferredRedirect, ReadData or Destroy. Public 39 // methods can be called on any thread. 40 class CronetURLRequest { 41 public: 42 // Callback implemented by CronetURLRequest() caller and owned by 43 // CronetURLRequest::NetworkTasks. All callback methods are invoked on network 44 // thread. 45 class Callback { 46 public: 47 virtual ~Callback() = default; 48 49 // Invoked whenever a redirect is encountered. This will only be invoked 50 // between the call to CronetURLRequest::Start() and 51 // Callback::OnResponseStarted(). The body of the redirect response, if 52 // it has one, will be ignored. 53 // 54 // The redirect will not be followed until 55 // CronetURLRequest::FollowDeferredRedirect() method is called, either 56 // synchronously or asynchronously. 57 virtual void OnReceivedRedirect(const std::string& new_location, 58 int http_status_code, 59 const std::string& http_status_text, 60 const net::HttpResponseHeaders* headers, 61 bool was_cached, 62 const std::string& negotiated_protocol, 63 const std::string& proxy_server, 64 int64_t received_byte_count) = 0; 65 66 // Invoked when the final set of headers, after all redirects, is received. 67 // Will only be invoked once for each request. 68 // 69 // With the exception of Callback::OnCanceled(), 70 // no other Callback method will be invoked for the request, 71 // including Callback::OnSucceeded() and Callback::OnFailed(), until 72 // CronetUrlRequest::Read() is called to attempt to start reading the 73 // response body. 74 virtual void OnResponseStarted(int http_status_code, 75 const std::string& http_status_text, 76 const net::HttpResponseHeaders* headers, 77 bool was_cached, 78 const std::string& negotiated_protocol, 79 const std::string& proxy_server, 80 int64_t received_byte_count) = 0; 81 82 // Invoked whenever part of the response body has been read. Only part of 83 // the buffer may be populated, even if the entire response body has not yet 84 // been consumed. 85 // 86 // With the exception of Callback::OnCanceled(), 87 // no other Callback method will be invoked for the request, 88 // including Callback::OnSucceeded() and Callback::OnFailed(), until 89 // CronetUrlRequest::Read() is called to attempt to continue reading the 90 // response body. 91 virtual void OnReadCompleted(scoped_refptr<net::IOBuffer> buffer, 92 int bytes_read, 93 int64_t received_byte_count) = 0; 94 95 // Invoked when request is completed successfully. 96 virtual void OnSucceeded(int64_t received_byte_count) = 0; 97 98 // Invoked if request failed for any reason after CronetURLRequest::Start(). 99 // |net_error| provides information about the failure. |quic_error| is only 100 // valid if |net_error| is net::QUIC_PROTOCOL_ERROR. 101 virtual void OnError(int net_error, 102 int quic_error, 103 const std::string& error_string, 104 int64_t received_byte_count) = 0; 105 106 // Invoked if request was canceled via CronetURLRequest::Destroy(). 107 virtual void OnCanceled() = 0; 108 109 // Invoked when request is destroyed. Once invoked, no other Callback 110 // methods will be invoked. 111 virtual void OnDestroyed() = 0; 112 113 // Reports metrics data about the request. 114 // This is called immediately before the terminal state callback (i.e. 115 // OnSucceeded()/OnError()/OnCanceled()). 116 virtual void OnMetricsCollected( 117 const base::Time& request_start_time, 118 const base::TimeTicks& request_start, 119 const base::TimeTicks& dns_start, 120 const base::TimeTicks& dns_end, 121 const base::TimeTicks& connect_start, 122 const base::TimeTicks& connect_end, 123 const base::TimeTicks& ssl_start, 124 const base::TimeTicks& ssl_end, 125 const base::TimeTicks& send_start, 126 const base::TimeTicks& send_end, 127 const base::TimeTicks& push_start, 128 const base::TimeTicks& push_end, 129 const base::TimeTicks& receive_headers_end, 130 const base::TimeTicks& request_end, 131 bool socket_reused, 132 int64_t sent_bytes_count, 133 int64_t received_bytes_count, 134 bool quic_connection_migration_attempted, 135 bool quic_connection_migration_successful) = 0; 136 }; 137 // Invoked in response to CronetURLRequest::GetStatus() to allow multiple 138 // overlapping calls. The load states correspond to the lengthy periods of 139 // time that a request load may be blocked and unable to make progress. 140 using OnStatusCallback = base::OnceCallback<void(net::LoadState)>; 141 142 // Bypasses cache if |disable_cache| is true. If context is not set up to 143 // use cache, |disable_cache| has no effect. |disable_connection_migration| 144 // causes connection migration to be disabled for this request if true. If 145 // global connection migration flag is not enabled, 146 // |disable_connection_migration| has no effect. 147 CronetURLRequest(CronetContext* context, 148 std::unique_ptr<Callback> callback, 149 const GURL& url, 150 net::RequestPriority priority, 151 bool disable_cache, 152 bool disable_connection_migration, 153 bool traffic_stats_tag_set, 154 int32_t traffic_stats_tag, 155 bool traffic_stats_uid_set, 156 int32_t traffic_stats_uid, 157 net::Idempotency idempotency, 158 net::handles::NetworkHandle network = 159 net::handles::kInvalidNetworkHandle); 160 161 CronetURLRequest(const CronetURLRequest&) = delete; 162 CronetURLRequest& operator=(const CronetURLRequest&) = delete; 163 164 // Methods called prior to Start are never called on network thread. 165 166 // Sets the request method GET, POST etc. 167 bool SetHttpMethod(const std::string& method); 168 169 // Adds a header to the request before it starts. 170 bool AddRequestHeader(const std::string& name, const std::string& value); 171 172 // Adds a request body to the request before it starts. 173 void SetUpload(std::unique_ptr<net::UploadDataStream> upload); 174 175 // Starts the request. 176 void Start(); 177 178 // GetStatus invokes |on_status_callback| on network thread to allow multiple 179 // overlapping calls. 180 void GetStatus(OnStatusCallback on_status_callback) const; 181 182 // Follows redirect. 183 void FollowDeferredRedirect(); 184 185 // Reads more data. 186 bool ReadData(net::IOBuffer* buffer, int max_bytes); 187 188 // Releases all resources for the request and deletes the object itself. 189 // |send_on_canceled| indicates whether OnCanceled callback should be 190 // issued to indicate when no more callbacks will be issued. 191 void Destroy(bool send_on_canceled); 192 193 // On the network thread, reports metrics to the registered 194 // CronetURLRequest::Callback, and then runs |callback| on the network thread. 195 // 196 // Since metrics are only reported once, this can be used to ensure metrics 197 // are reported to the registered CronetURLRequest::Callback before resources 198 // used by the callback are deleted. 199 void MaybeReportMetricsAndRunCallback(base::OnceClosure callback); 200 201 private: 202 friend class TestUtil; 203 204 // Private destructor invoked fron NetworkTasks::Destroy() on network thread. 205 ~CronetURLRequest(); 206 207 // NetworkTasks performs tasks on the network thread and owns objects that 208 // live on the network thread. 209 class NetworkTasks : public net::URLRequest::Delegate { 210 public: 211 // Invoked off the network thread. 212 NetworkTasks(std::unique_ptr<Callback> callback, 213 const GURL& url, 214 net::RequestPriority priority, 215 int load_flags, 216 bool traffic_stats_tag_set, 217 int32_t traffic_stats_tag, 218 bool traffic_stats_uid_set, 219 int32_t traffic_stats_uid, 220 net::Idempotency idempotency, 221 net::handles::NetworkHandle network); 222 223 NetworkTasks(const NetworkTasks&) = delete; 224 NetworkTasks& operator=(const NetworkTasks&) = delete; 225 226 // Invoked on the network thread. 227 ~NetworkTasks() override; 228 229 // Starts the request. 230 void Start(CronetContext* context, 231 const std::string& method, 232 std::unique_ptr<net::HttpRequestHeaders> request_headers, 233 std::unique_ptr<net::UploadDataStream> upload); 234 235 // Gets status of the requrest and invokes |on_status_callback| to allow 236 // multiple overlapping calls. 237 void GetStatus(OnStatusCallback on_status_callback) const; 238 239 // Follows redirect. 240 void FollowDeferredRedirect(); 241 242 // Reads more data. 243 void ReadData(scoped_refptr<net::IOBuffer> read_buffer, int buffer_size); 244 245 // Releases all resources for the request and deletes the |request|, which 246 // owns |this|, so |this| is also deleted. 247 // |send_on_canceled| indicates whether OnCanceled callback should be 248 // issued to indicate when no more callbacks will be issued. 249 void Destroy(CronetURLRequest* request, bool send_on_canceled); 250 251 // Runs MaybeReportMetrics(), then runs |callback|. 252 void MaybeReportMetricsAndRunCallback(base::OnceClosure callback); 253 254 private: 255 friend class TestUtil; 256 257 // net::URLRequest::Delegate implementations: 258 void OnReceivedRedirect(net::URLRequest* request, 259 const net::RedirectInfo& redirect_info, 260 bool* defer_redirect) override; 261 void OnCertificateRequested( 262 net::URLRequest* request, 263 net::SSLCertRequestInfo* cert_request_info) override; 264 void OnSSLCertificateError(net::URLRequest* request, 265 int net_error, 266 const net::SSLInfo& ssl_info, 267 bool fatal) override; 268 void OnResponseStarted(net::URLRequest* request, int net_error) override; 269 void OnReadCompleted(net::URLRequest* request, int bytes_read) override; 270 271 // Report error and cancel request_adapter. 272 void ReportError(net::URLRequest* request, int net_error); 273 // Reports metrics collected. 274 void MaybeReportMetrics(); 275 276 // Callback implemented by the client. 277 std::unique_ptr<CronetURLRequest::Callback> callback_; 278 279 const GURL initial_url_; 280 const net::RequestPriority initial_priority_; 281 const int initial_load_flags_; 282 // Count of bytes received during redirect is added to received byte count. 283 int64_t received_byte_count_from_redirects_; 284 285 // Whether error has been already reported, for example from 286 // OnSSLCertificateError(). 287 bool error_reported_; 288 289 // Whether metrics have been reported. 290 bool metrics_reported_; 291 292 // Whether |traffic_stats_tag_| should be applied. 293 const bool traffic_stats_tag_set_; 294 // TrafficStats tag to apply to URLRequest. 295 const int32_t traffic_stats_tag_; 296 // Whether |traffic_stats_uid_| should be applied. 297 const bool traffic_stats_uid_set_; 298 // UID to be applied to URLRequest. 299 const int32_t traffic_stats_uid_; 300 // Idempotency of the request. 301 const net::Idempotency idempotency_; 302 303 net::handles::NetworkHandle network_; 304 305 scoped_refptr<net::IOBuffer> read_buffer_; 306 std::unique_ptr<net::URLRequest> url_request_; 307 308 THREAD_CHECKER(network_thread_checker_); 309 }; 310 311 raw_ptr<CronetContext> context_; 312 // |network_tasks_| is invoked on network thread. 313 NetworkTasks network_tasks_; 314 315 // Request parameters set off network thread before Start(). 316 std::string initial_method_; 317 std::unique_ptr<net::HttpRequestHeaders> initial_request_headers_; 318 std::unique_ptr<net::UploadDataStream> upload_; 319 }; 320 321 } // namespace cronet 322 323 #endif // COMPONENTS_CRONET_CRONET_URL_REQUEST_H_ 324