File: http_network_transaction.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (536 lines) | stat: -rw-r--r-- 21,018 bytes parent folder | download | duplicates (3)
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_HTTP_HTTP_NETWORK_TRANSACTION_H_
#define NET_HTTP_HTTP_NETWORK_TRANSACTION_H_

#include <stdint.h>

#include <array>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "build/buildflag.h"
#include "net/base/completion_once_callback.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/net_error_details.h"
#include "net/base/net_export.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/request_priority.h"
#include "net/http/http_auth.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_stream_factory.h"
#include "net/http/http_stream_request.h"
#include "net/http/http_transaction.h"
#include "net/log/net_log_with_source.h"
#include "net/net_buildflags.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/connection_attempts.h"
#include "net/ssl/ssl_config.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
#include "net/websockets/websocket_handshake_stream_base.h"

namespace net {

class BidirectionalStreamImpl;
class HttpAuthController;
class HttpNetworkSession;
class HttpStream;
class IOBuffer;
class ProxyInfo;
class SSLPrivateKey;
struct HttpRequestInfo;

class NET_EXPORT_PRIVATE HttpNetworkTransaction
    : public HttpTransaction,
      public HttpStreamRequest::Delegate {
 public:
  HttpNetworkTransaction(RequestPriority priority, HttpNetworkSession* session);

  HttpNetworkTransaction(const HttpNetworkTransaction&) = delete;
  HttpNetworkTransaction& operator=(const HttpNetworkTransaction&) = delete;

  ~HttpNetworkTransaction() override;

  // HttpTransaction methods:
  int Start(const HttpRequestInfo* request_info,
            CompletionOnceCallback callback,
            const NetLogWithSource& net_log) override;
  int RestartIgnoringLastError(CompletionOnceCallback callback) override;
  int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
                             scoped_refptr<SSLPrivateKey> client_private_key,
                             CompletionOnceCallback callback) override;
  int RestartWithAuth(const AuthCredentials& credentials,
                      CompletionOnceCallback callback) override;
  bool IsReadyToRestartForAuth() override;

  int Read(IOBuffer* buf,
           int buf_len,
           CompletionOnceCallback callback) override;
  void StopCaching() override;
  int64_t GetTotalReceivedBytes() const override;
  int64_t GetTotalSentBytes() const override;
  int64_t GetReceivedBodyBytes() const override;
  void DoneReading() override;
  const HttpResponseInfo* GetResponseInfo() const override;
  LoadState GetLoadState() const override;
  bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
  void PopulateLoadTimingInternalInfo(
      LoadTimingInternalInfo* load_timing_internal_info) const override;
  bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
  void PopulateNetErrorDetails(NetErrorDetails* details) const override;
  void SetPriority(RequestPriority priority) override;
  void SetWebSocketHandshakeStreamCreateHelper(
      WebSocketHandshakeStreamBase::CreateHelper* create_helper) override;
  void SetConnectedCallback(const ConnectedCallback& callback) override;
  void SetRequestHeadersCallback(RequestHeadersCallback callback) override;
  void SetEarlyResponseHeadersCallback(
      ResponseHeadersCallback callback) override;
  void SetResponseHeadersCallback(ResponseHeadersCallback callback) override;
  void SetModifyRequestHeadersCallback(
      base::RepeatingCallback<void(HttpRequestHeaders*)> callback) override;
  void SetIsSharedDictionaryReadAllowedCallback(
      base::RepeatingCallback<bool()> callback) override;
  void CloseConnectionOnDestruction() override;
  bool IsMdlMatchForMetrics() const override;

  // HttpStreamRequest::Delegate methods:
  void OnStreamReady(const ProxyInfo& used_proxy_info,
                     std::unique_ptr<HttpStream> stream) override;
  void OnBidirectionalStreamImplReady(
      const ProxyInfo& used_proxy_info,
      std::unique_ptr<BidirectionalStreamImpl> stream) override;
  void OnWebSocketHandshakeStreamReady(
      const ProxyInfo& used_proxy_info,
      std::unique_ptr<WebSocketHandshakeStreamBase> stream) override;
  void OnStreamFailed(int status,
                      const NetErrorDetails& net_error_details,
                      const ProxyInfo& used_proxy_info,
                      ResolveErrorInfo resolve_error_info) override;
  void OnCertificateError(int status, const SSLInfo& ssl_info) override;
  void OnNeedsProxyAuth(const HttpResponseInfo& response_info,
                        const ProxyInfo& used_proxy_info,
                        HttpAuthController* auth_controller) override;
  void OnNeedsClientAuth(SSLCertRequestInfo* cert_info) override;

  void OnQuicBroken() override;

  ConnectionAttempts GetConnectionAttempts() const override;

 private:
  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, ResetStateForRestart);
  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
                           CreateWebSocketHandshakeStream);
  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
                           SetProxyInfoInResponse_Direct);
  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
                           SetProxyInfoInResponse_Proxied);
  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
                           SetProxyInfoInResponse_Empty);
  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
                           SetProxyInfoInResponse_IpProtectionProxied);
  FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest,
                           SetProxyInfoInResponse_IpProtectionDirect);
  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateReceived);
  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateSent);
  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, WindowUpdateOverflow);
  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest, FlowControlStallResume);
  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
                           FlowControlStallResumeAfterSettings);
  FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionTest,
                           FlowControlNegativeSendWindowSize);

  enum State {
    STATE_CREATE_STREAM,
    STATE_CREATE_STREAM_COMPLETE,
    STATE_INIT_STREAM,
    STATE_INIT_STREAM_COMPLETE,
    STATE_CONNECTED_CALLBACK,
    STATE_CONNECTED_CALLBACK_COMPLETE,
    STATE_GENERATE_PROXY_AUTH_TOKEN,
    STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
    STATE_GENERATE_SERVER_AUTH_TOKEN,
    STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
    STATE_INIT_REQUEST_BODY,
    STATE_INIT_REQUEST_BODY_COMPLETE,
    STATE_BUILD_REQUEST,
    STATE_BUILD_REQUEST_COMPLETE,
    STATE_SEND_REQUEST,
    STATE_SEND_REQUEST_COMPLETE,
    STATE_READ_HEADERS,
    STATE_READ_HEADERS_COMPLETE,
    STATE_READ_BODY,
    STATE_READ_BODY_COMPLETE,
    STATE_DRAIN_BODY_FOR_AUTH_RESTART,
    STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE,
    STATE_NONE
  };

  bool IsSecureRequest() const;

  // Returns true if the request is using an HTTP(S) proxy without being
  // tunneled via the CONNECT method.
  bool UsingHttpProxyWithoutTunnel() const;

  void DoCallback(int result);
  void OnIOComplete(int result);

  // Runs the state transition loop.
  int DoLoop(int result);

  // Each of these methods corresponds to a State value.  Those with an input
  // argument receive the result from the previous state.  If a method returns
  // ERR_IO_PENDING, then the result from OnIOComplete will be passed to the
  // next state method as the result arg.
  int DoCreateStream();
  int DoCreateStreamComplete(int result);
  int DoConnectedCallback();
  int DoConnectedCallbackComplete(int result);
  int DoInitStream();
  int DoInitStreamComplete(int result);
  int DoGenerateProxyAuthToken();
  int DoGenerateProxyAuthTokenComplete(int result);
  int DoGenerateServerAuthToken();
  int DoGenerateServerAuthTokenComplete(int result);
  int DoInitRequestBody();
  int DoInitRequestBodyComplete(int result);
  int DoBuildRequest();
  int DoBuildRequestComplete(int result);
  int DoSendRequest();
  int DoSendRequestComplete(int result);
  int DoReadHeaders();
  int DoReadHeadersComplete(int result);
  int DoReadBody();
  int DoReadBodyComplete(int result);
  int DoDrainBodyForAuthRestart();
  int DoDrainBodyForAuthRestartComplete(int result);

  int BuildRequestHeaders(bool using_http_proxy_without_tunnel);

#if BUILDFLAG(ENABLE_REPORTING)
  // Processes the Report-To header, if one exists. This header configures where
  // the Reporting API (in //net/reporting) will send reports for the origin.
  void ProcessReportToHeader();

  // Processes the NEL header, if one exists. This header configures whether
  // network errors will be reported to a specified group of endpoints using the
  // Reporting API.
  void ProcessNetworkErrorLoggingHeader();

  // Calls GenerateNetworkErrorLoggingReport() if |rv| represents a NET_ERROR
  // other than ERR_IO_PENDING.
  void GenerateNetworkErrorLoggingReportIfError(int rv);

  // Generates a NEL report about this request.  The NetworkErrorLoggingService
  // will discard the report if there is no NEL policy registered for this
  // origin.
  void GenerateNetworkErrorLoggingReport(int rv);
#endif

  // Writes a log message to help debugging in the field when we block a proxy
  // response to a CONNECT request.
  void LogBlockedTunnelResponse(int response_code) const;

  // Called wherever ERR_HTTP_1_1_REQUIRED or
  // ERR_PROXY_HTTP_1_1_REQUIRED has to be handled.
  int HandleHttp11Required(int error);

  // Called to possibly handle a client authentication error. Sets next_state_
  // and returns OK if recovering from the error.  Otherwise, the same error
  // code is returned.
  int HandleSSLClientAuthError(int error);

  // Called to possibly recover from the given error.  Sets next_state_ and
  // returns OK if recovering from the error.  Otherwise, the same error code
  // is returned.
  int HandleIOError(int error);

  // Gets the response headers from the HttpStream.
  HttpResponseHeaders* GetResponseHeaders() const;

  // Called when the socket is unexpectedly closed.  Returns true if the request
  // should be resent in case of a socket reuse/close race.
  bool ShouldResendRequest() const;

  // Returns true if there have already been |kMaxRetryAttempts| retries for
  // HTTP2 or QUIC network errors, and no further retries should be attempted.
  bool HasExceededMaxRetries() const;

  // Increments the number of restarts and returns true if the restart may
  // proceed.
  bool CheckMaxRestarts();

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class RetryReason {
    kHttpRequestTimeout = 0,
    kHttpMisdirectedRequest = 1,
    kHttp11Required = 2,
    kSslClientAuthSignatureFailed = 3,
    kConnectionReset = 4,
    kConnectionClosed = 5,
    kConnectionAborted = 6,
    kSocketNotConnected = 7,
    kEmptyResponse = 8,
    kEarlyDataRejected = 9,
    kWrongVersionOnEarlyData = 10,
    kHttp2PingFailed = 11,
    kHttp2ServerRefusedStream = 12,
    // Entries 13, 14, 15 are removed.
    kQuicHandshakeFailed = 16,
    kQuicGoawayRequestCanBeRetried = 17,
    kQuicProtocolError = 18,
    kMaxValue = kQuicProtocolError,
  };
  static std::optional<RetryReason> GetRetryReasonForIOError(int error);

  // Resets the connection and the request headers for resend.  Called when
  // ShouldResendRequest() is true.
  void ResetConnectionAndRequestForResend(RetryReason retry_reason);

  // Sets up the state machine to restart the transaction with auth.
  void PrepareForAuthRestart(HttpAuth::Target target);

  // Called when we don't need to drain the response body or have drained it.
  // Resets |connection_| unless |keep_alive| is true, then calls
  // ResetStateForRestart.  Sets |next_state_| appropriately.
  void DidDrainBodyForAuthRestart(bool keep_alive);

  // Resets the members of the transaction so it can be restarted.
  void ResetStateForRestart();

  // Resets the members of the transaction, except |stream_|, which needs
  // to be maintained for multi-round auth.
  void ResetStateForAuthRestart();

  // Caches network error details from the stream if available
  // and resets the stream.
  void CacheNetErrorDetailsAndResetStream();

  // Returns true if we should try to add a Proxy-Authorization header
  bool ShouldApplyProxyAuth() const;

  // Returns true if we should try to add an Authorization header.
  bool ShouldApplyServerAuth() const;

  // Handles HTTP status code 401 or 407.
  // HandleAuthChallenge() returns a network error code, or OK on success.
  // May update |pending_auth_target_| or |response_.auth_challenge|.
  int HandleAuthChallenge();

  // Returns true if we have auth credentials for the given target.
  bool HaveAuth(HttpAuth::Target target) const;

  // Get the {scheme, host, path, port} for the authentication target
  GURL AuthURL(HttpAuth::Target target) const;

  // Returns true if this transaction is for a WebSocket handshake
  bool ForWebSocketHandshake() const;

  void CopyConnectionAttemptsFromStreamRequest();

  // Returns true if response "Content-Encoding" headers respect
  // "Accept-Encoding".
  bool ContentEncodingsValid() const;

  void ResumeAfterConnected(int result);

  void RecordStreamRequestResult(int result);

  void ProcessAltSvcHeader();

  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class QuicProtocolErrorRetryStatus {
    kNoRetryExceededMaxRetries = 0,
    kNoRetryHeaderReceived = 1,
    kNoRetryNoAlternativeService = 2,
    kRetryAltServiceBroken = 3,
    kRetryAltServiceNotBroken = 4,
    kMaxValue = kRetryAltServiceNotBroken,
  };

  static void SetProxyInfoInResponse(const ProxyInfo& proxy_info,
                                     HttpResponseInfo* response_info);

  std::array<scoped_refptr<HttpAuthController>, HttpAuth::AUTH_NUM_TARGETS>
      auth_controllers_;

  // Whether this transaction is waiting for proxy auth, server auth, or is
  // not waiting for any auth at all. |pending_auth_target_| is read and
  // cleared by RestartWithAuth().
  HttpAuth::Target pending_auth_target_ = HttpAuth::AUTH_NONE;

  CompletionRepeatingCallback io_callback_;
  CompletionOnceCallback callback_;

  raw_ptr<HttpNetworkSession> session_;

  NetLogWithSource net_log_;

  base::TimeTicks start_timeticks_;

  // Reset to null at the start of the Read state machine.
  raw_ptr<const HttpRequestInfo> request_ = nullptr;

  // The requested URL.
  GURL url_;
  RequestPriority priority_;
  HttpResponseInfo response_;

  // Copied from |request_|, as it's needed after the response body has been
  // read.
  NetworkAnonymizationKey network_anonymization_key_;

  // |proxy_info_| is the ProxyInfo used by the HttpStreamRequest.
  ProxyInfo proxy_info_;

  std::unique_ptr<HttpStreamRequest> stream_request_;
  std::unique_ptr<HttpStream> stream_;

  // True if we've validated the headers that the stream parser has returned.
  bool headers_valid_ = false;

  // True if we can send the request over early data.
  bool can_send_early_data_ = false;

  // True if the client certificate for the server (rather than the proxy) was
  // configured in this transaction.
  bool configured_client_cert_for_server_ = false;

  // Previously observed bad certs when establishing a connection. If the caller
  // chooses to retry despite the error, future connection attempts will be
  // configured to ignore these errors.
  std::vector<SSLConfig::CertAndStatus> observed_bad_certs_;

  HttpRequestHeaders request_headers_;
#if BUILDFLAG(ENABLE_REPORTING)
  // Whether a NEL report has already been generated. Reset when restarting.
  bool network_error_logging_report_generated_ = false;
  // Cache some fields from |request_| that we'll need to construct a NEL
  // report about the request.  (NEL report construction happens after we've
  // cleared the |request_| pointer.)
  std::string request_method_;
  std::string request_referrer_;
  std::string request_user_agent_;
  int request_reporting_upload_depth_ = 0;
#endif

  // The size in bytes of the buffer we use to drain the response body that
  // we want to throw away.  The response body is typically a small error
  // page just a few hundred bytes long.
  static const int kDrainBodyBufferSize = 1024;

  // User buffer and length passed to the Read method.
  scoped_refptr<IOBuffer> read_buf_;
  int read_buf_len_ = 0;

  // Total number of bytes received on all destroyed HttpStreams for this
  // transaction.
  int64_t total_received_bytes_ = 0;

  // Total number of bytes sent on all destroyed HttpStreams for this
  // transaction.
  int64_t total_sent_bytes_ = 0;

  // When the transaction started / finished creating a stream.
  base::TimeTicks create_stream_start_time_;
  base::TimeTicks create_stream_end_time_;

  // When the transaction started / finished sending the request, including
  // the body, if present. |send_start_time_| is set to |base::TimeTicks()|
  // until |SendRequest()| is called on |stream_|, and reset for auth restarts.
  base::TimeTicks send_start_time_;
  base::TimeTicks send_end_time_;

  // When the connection and request headers are reset, and the request is
  // resent.
  base::TimeTicks reset_connection_and_request_for_resend_start_time_;

  // The next state in the state machine.
  State next_state_ = STATE_NONE;

  // True when the tunnel is in the process of being established - we can't
  // read from the socket until the tunnel is done.
  bool establishing_tunnel_ = false;

  // Enable pooling to a SpdySession with matching IP and certificate
  // even if the SpdySessionKey is different.
  bool enable_ip_based_pooling_ = true;

  // Enable using alternative services for the request.
  bool enable_alternative_services_ = true;

  // When a request is retried because of errors with the alternative service,
  // this will store the alternative service used.
  AlternativeService retried_alternative_service_;

  // The helper object to use to create WebSocketHandshakeStreamBase
  // objects. Only relevant when establishing a WebSocket connection.
  raw_ptr<WebSocketHandshakeStreamBase::CreateHelper>
      websocket_handshake_stream_base_create_helper_ = nullptr;

  ConnectedCallback connected_callback_;
  RequestHeadersCallback request_headers_callback_;
  ResponseHeadersCallback early_response_headers_callback_;
  ResponseHeadersCallback response_headers_callback_;

  // The callback to modify the request header. They will be called just before
  // sending the request to the network.
  base::RepeatingCallback<void(HttpRequestHeaders*)> modify_headers_callbacks_;

  ConnectionAttempts connection_attempts_;
  IPEndPoint remote_endpoint_;
  // Network error details for this transaction.
  NetErrorDetails net_error_details_;
  NextProto negotiated_protocol_ = NextProto::kProtoUnknown;

  // Number of retries made for network errors like ERR_HTTP2_PING_FAILED,
  // ERR_HTTP2_SERVER_REFUSED_STREAM, ERR_QUIC_HANDSHAKE_FAILED and
  // ERR_QUIC_PROTOCOL_ERROR. Currently we stop after 3 tries
  // (including the initial request) and fail the request.
  // This count excludes retries on reused sockets since a well
  // behaved server may time those out and thus the number
  // of times we can retry a request on reused sockets is limited.
  size_t retry_attempts_ = 0;

  // Number of times the transaction was restarted via a RestartWith* call.
  size_t num_restarts_ = 0;

  bool close_connection_on_destruction_ = false;

  // Set to true when the server required HTTP/1.1 fallback.
  bool http_1_1_was_required_ = false;

  // If set, these values are used as DNS resolution times, rather than
  // using DNS times coming from the established stream.
  base::TimeTicks dns_resolution_start_time_override_;
  base::TimeTicks dns_resolution_end_time_override_;

  // The time at which initialize stream started / ended.
  base::TimeTicks initialize_stream_start_time_;
  base::TimeTicks initialize_stream_end_time_;

  base::TimeTicks blocked_initialize_stream_start_time_;
  base::TimeTicks blocked_generate_proxy_auth_token_start_time_;
  base::TimeTicks blocked_generate_server_auth_token_start_time_;

  // Timing information for the connected callback.
  base::TimeTicks connected_callback_start_time_;
  base::TimeTicks connected_callback_end_time_;

  // The number of bytes of the body received from network.
  int64_t received_body_bytes_ = 0;
};

}  // namespace net

#endif  // NET_HTTP_HTTP_NETWORK_TRANSACTION_H_