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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
|
// Copyright 2014 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_CRONET_URL_REQUEST_H_
#define COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
#include <memory>
#include <string>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "net/base/idempotency.h"
#include "net/base/network_handle.h"
#include "net/base/request_priority.h"
#include "net/shared_dictionary/shared_dictionary.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"
namespace net {
class HttpRequestHeaders;
enum LoadState;
class SSLCertRequestInfo;
class SSLInfo;
class UploadDataStream;
} // namespace net
namespace cronet {
class CronetContext;
class TestUtil;
// Wrapper around net::URLRequestContext.
// Created and configured from client thread. Start, ReadData, and Destroy are
// posted to network thread and all callbacks into the Callback() are
// done on the network thread. CronetUrlRequest client is expected to initiate
// the next step like FollowDeferredRedirect, ReadData or Destroy. Public
// methods can be called on any thread.
class CronetURLRequest {
public:
// Callback implemented by CronetURLRequest() caller and owned by
// CronetURLRequest::NetworkTasks. All callback methods are invoked on network
// thread.
class Callback {
public:
virtual ~Callback() = default;
// Invoked whenever a redirect is encountered. This will only be invoked
// between the call to CronetURLRequest::Start() and
// Callback::OnResponseStarted(). The body of the redirect response, if
// it has one, will be ignored.
//
// The redirect will not be followed until
// CronetURLRequest::FollowDeferredRedirect() method is called, either
// synchronously or asynchronously.
virtual void OnReceivedRedirect(const std::string& new_location,
int http_status_code,
const std::string& http_status_text,
const net::HttpResponseHeaders* headers,
bool was_cached,
const std::string& negotiated_protocol,
const std::string& proxy_server,
int64_t received_byte_count) = 0;
// Invoked when the final set of headers, after all redirects, is received.
// Will only be invoked once for each request.
//
// With the exception of Callback::OnCanceled(),
// no other Callback method will be invoked for the request,
// including Callback::OnSucceeded() and Callback::OnFailed(), until
// CronetUrlRequest::Read() is called to attempt to start reading the
// response body.
virtual void OnResponseStarted(int http_status_code,
const std::string& http_status_text,
const net::HttpResponseHeaders* headers,
bool was_cached,
const std::string& negotiated_protocol,
const std::string& proxy_server,
int64_t received_byte_count) = 0;
// Invoked whenever part of the response body has been read. Only part of
// the buffer may be populated, even if the entire response body has not yet
// been consumed.
//
// With the exception of Callback::OnCanceled(),
// no other Callback method will be invoked for the request,
// including Callback::OnSucceeded() and Callback::OnFailed(), until
// CronetUrlRequest::Read() is called to attempt to continue reading the
// response body.
virtual void OnReadCompleted(scoped_refptr<net::IOBuffer> buffer,
int bytes_read,
int64_t received_byte_count) = 0;
// Invoked when request is completed successfully.
virtual void OnSucceeded(int64_t received_byte_count) = 0;
// Invoked if request failed for any reason after CronetURLRequest::Start().
// |net_error| provides information about the failure. |quic_error| is only
// valid if |net_error| is net::QUIC_PROTOCOL_ERROR.
// |source| represents who asked to terminate the connection, it is only
// valid if the |net_error| is net::QUIC_PROTOCOL_ERROR.
virtual void OnError(int net_error,
int quic_error,
quic::ConnectionCloseSource source,
const std::string& error_string,
int64_t received_byte_count) = 0;
// Invoked if request was canceled via CronetURLRequest::Destroy().
virtual void OnCanceled() = 0;
// Invoked when request is destroyed. Once invoked, no other Callback
// methods will be invoked.
virtual void OnDestroyed() = 0;
// Reports metrics data about the request.
// This is called immediately before the terminal state callback (i.e.
// OnSucceeded()/OnError()/OnCanceled()).
virtual void OnMetricsCollected(
const base::Time& request_start_time,
const base::TimeTicks& request_start,
const base::TimeTicks& dns_start,
const base::TimeTicks& dns_end,
const base::TimeTicks& connect_start,
const base::TimeTicks& connect_end,
const base::TimeTicks& ssl_start,
const base::TimeTicks& ssl_end,
const base::TimeTicks& send_start,
const base::TimeTicks& send_end,
const base::TimeTicks& push_start,
const base::TimeTicks& push_end,
const base::TimeTicks& receive_headers_end,
const base::TimeTicks& request_end,
bool socket_reused,
int64_t sent_bytes_count,
int64_t received_bytes_count,
bool quic_connection_migration_attempted,
bool quic_connection_migration_successful) = 0;
};
// Invoked in response to CronetURLRequest::GetStatus() to allow multiple
// overlapping calls. The load states correspond to the lengthy periods of
// time that a request load may be blocked and unable to make progress.
using OnStatusCallback = base::OnceCallback<void(net::LoadState)>;
// Bypasses cache if |disable_cache| is true. If context is not set up to
// use cache, |disable_cache| has no effect. |disable_connection_migration|
// causes connection migration to be disabled for this request if true. If
// global connection migration flag is not enabled,
// |disable_connection_migration| has no effect.
CronetURLRequest(CronetContext* context,
std::unique_ptr<Callback> callback,
const GURL& url,
net::RequestPriority priority,
bool disable_cache,
bool disable_connection_migration,
bool traffic_stats_tag_set,
int32_t traffic_stats_tag,
bool traffic_stats_uid_set,
int32_t traffic_stats_uid,
net::Idempotency idempotency,
scoped_refptr<net::SharedDictionary> shared_dictionary,
net::handles::NetworkHandle network =
net::handles::kInvalidNetworkHandle);
CronetURLRequest(const CronetURLRequest&) = delete;
CronetURLRequest& operator=(const CronetURLRequest&) = delete;
// Methods called prior to Start are never called on network thread.
// Sets the request method GET, POST etc.
bool SetHttpMethod(const std::string& method);
// Adds a header to the request before it starts.
bool AddRequestHeader(const std::string& name, const std::string& value);
// Adds a request body to the request before it starts.
void SetUpload(std::unique_ptr<net::UploadDataStream> upload);
// Starts the request.
void Start();
// GetStatus invokes |on_status_callback| on network thread to allow multiple
// overlapping calls.
void GetStatus(OnStatusCallback on_status_callback) const;
// Follows redirect.
void FollowDeferredRedirect();
// Reads more data.
bool ReadData(net::IOBuffer* buffer, int max_bytes);
// Releases all resources for the request and deletes the object itself.
// |send_on_canceled| indicates whether OnCanceled callback should be
// issued to indicate when no more callbacks will be issued.
void Destroy(bool send_on_canceled);
// On the network thread, reports metrics to the registered
// CronetURLRequest::Callback, and then runs |callback| on the network thread.
//
// Since metrics are only reported once, this can be used to ensure metrics
// are reported to the registered CronetURLRequest::Callback before resources
// used by the callback are deleted.
void MaybeReportMetricsAndRunCallback(base::OnceClosure callback);
private:
friend class TestUtil;
// Private destructor invoked fron NetworkTasks::Destroy() on network thread.
~CronetURLRequest();
// NetworkTasks performs tasks on the network thread and owns objects that
// live on the network thread.
class NetworkTasks : public net::URLRequest::Delegate {
public:
// Invoked off the network thread.
NetworkTasks(std::unique_ptr<Callback> callback,
const GURL& url,
net::RequestPriority priority,
int load_flags,
bool traffic_stats_tag_set,
int32_t traffic_stats_tag,
bool traffic_stats_uid_set,
int32_t traffic_stats_uid,
net::Idempotency idempotency,
scoped_refptr<net::SharedDictionary> shared_dictionary,
net::handles::NetworkHandle network);
NetworkTasks(const NetworkTasks&) = delete;
NetworkTasks& operator=(const NetworkTasks&) = delete;
// Invoked on the network thread.
~NetworkTasks() override;
// Starts the request.
void Start(CronetContext* context,
const std::string& method,
std::unique_ptr<net::HttpRequestHeaders> request_headers,
std::unique_ptr<net::UploadDataStream> upload);
// Gets status of the requrest and invokes |on_status_callback| to allow
// multiple overlapping calls.
void GetStatus(OnStatusCallback on_status_callback) const;
// Follows redirect.
void FollowDeferredRedirect();
// Reads more data.
void ReadData(scoped_refptr<net::IOBuffer> read_buffer, int buffer_size);
// Releases all resources for the request and deletes the |request|, which
// owns |this|, so |this| is also deleted.
// |send_on_canceled| indicates whether OnCanceled callback should be
// issued to indicate when no more callbacks will be issued.
void Destroy(CronetURLRequest* request, bool send_on_canceled);
// Runs MaybeReportMetrics(), then runs |callback|.
void MaybeReportMetricsAndRunCallback(base::OnceClosure callback);
private:
friend class TestUtil;
// net::URLRequest::Delegate implementations:
void OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) override;
void OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) override;
void OnSSLCertificateError(net::URLRequest* request,
int net_error,
const net::SSLInfo& ssl_info,
bool fatal) override;
void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
// Report error and cancel request_adapter.
void ReportError(net::URLRequest* request, int net_error);
// Reports metrics collected.
void MaybeReportMetrics();
// Callback implemented by the client.
std::unique_ptr<CronetURLRequest::Callback> callback_;
const GURL initial_url_;
const net::RequestPriority initial_priority_;
const int initial_load_flags_;
// Count of bytes received during redirect is added to received byte count.
int64_t received_byte_count_from_redirects_;
// Whether error has been already reported, for example from
// OnSSLCertificateError().
bool error_reported_;
// Whether metrics have been reported.
bool metrics_reported_;
// Whether |traffic_stats_tag_| should be applied.
const bool traffic_stats_tag_set_;
// TrafficStats tag to apply to URLRequest.
const int32_t traffic_stats_tag_;
// Whether |traffic_stats_uid_| should be applied.
const bool traffic_stats_uid_set_;
// UID to be applied to URLRequest.
const int32_t traffic_stats_uid_;
// Idempotency of the request.
const net::Idempotency idempotency_;
// Optional compression dictionary for this request. != nullptr if present.
scoped_refptr<net::SharedDictionary> shared_dictionary_;
net::handles::NetworkHandle network_;
scoped_refptr<net::IOBuffer> read_buffer_;
std::unique_ptr<net::URLRequest> url_request_;
THREAD_CHECKER(network_thread_checker_);
};
raw_ptr<CronetContext> context_;
// |network_tasks_| is invoked on network thread.
NetworkTasks network_tasks_;
// Request parameters set off network thread before Start().
std::string initial_method_;
std::unique_ptr<net::HttpRequestHeaders> initial_request_headers_;
std::unique_ptr<net::UploadDataStream> upload_;
};
} // namespace cronet
#endif // COMPONENTS_CRONET_CRONET_URL_REQUEST_H_
|