summaryrefslogtreecommitdiffstats
path: root/net/http/disk_cache_based_quic_server_info.h
blob: e95d5355c97d27bc8f1bf35eeec31e562f623170 (plain)
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
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_
#define NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_

#include <string>

#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "net/base/completion_callback.h"
#include "net/disk_cache/disk_cache.h"
#include "net/quic/crypto/quic_server_info.h"

namespace net {

class HttpCache;
class IOBuffer;
class QuicServerId;

// DiskCacheBasedQuicServerInfo fetches information about a QUIC server from
// our standard disk cache. Since the information is defined to be
// non-sensitive, it's ok for us to keep it on disk.
class NET_EXPORT_PRIVATE DiskCacheBasedQuicServerInfo
    : public QuicServerInfo,
      public NON_EXPORTED_BASE(base::NonThreadSafe) {
 public:
  DiskCacheBasedQuicServerInfo(const QuicServerId& server_id,
                               HttpCache* http_cache);

  // QuicServerInfo implementation.
  void Start() override;
  int WaitForDataReady(const CompletionCallback& callback) override;
  void CancelWaitForDataReadyCallback() override;
  bool IsDataReady() override;
  bool IsReadyToPersist() override;
  void Persist() override;
  void OnExternalCacheHit() override;

 private:
  struct CacheOperationDataShim;

  enum State {
    GET_BACKEND,
    GET_BACKEND_COMPLETE,
    OPEN,
    OPEN_COMPLETE,
    READ,
    READ_COMPLETE,
    WAIT_FOR_DATA_READY_DONE,
    CREATE_OR_OPEN,
    CREATE_OR_OPEN_COMPLETE,
    WRITE,
    WRITE_COMPLETE,
    SET_DONE,
    NONE,
  };

  // Enum to track number of times data read/parse/write API calls of
  // QuicServerInfo to and from disk cache is called.
  enum QuicServerInfoAPICall {
    QUIC_SERVER_INFO_START = 0,
    QUIC_SERVER_INFO_WAIT_FOR_DATA_READY = 1,
    QUIC_SERVER_INFO_PARSE = 2,
    QUIC_SERVER_INFO_WAIT_FOR_DATA_READY_CANCEL = 3,
    QUIC_SERVER_INFO_READY_TO_PERSIST = 4,
    QUIC_SERVER_INFO_PERSIST = 5,
    QUIC_SERVER_INFO_EXTERNAL_CACHE_HIT = 6,
    QUIC_SERVER_INFO_NUM_OF_API_CALLS = 7,
  };

  // Enum to track failure reasons to read/load/write of QuicServerInfo to
  // and from disk cache.
  enum FailureReason {
    WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE = 0,
    GET_BACKEND_FAILURE = 1,
    OPEN_FAILURE = 2,
    CREATE_OR_OPEN_FAILURE = 3,
    PARSE_NO_DATA_FAILURE = 4,
    PARSE_FAILURE = 5,
    READ_FAILURE = 6,
    READY_TO_PERSIST_FAILURE = 7,
    PERSIST_NO_BACKEND_FAILURE = 8,
    WRITE_FAILURE = 9,
    NO_FAILURE = 10,
    NUM_OF_FAILURES = 11,
  };

  ~DiskCacheBasedQuicServerInfo() override;

  // Persists |pending_write_data_| if it is not empty, otherwise serializes the
  // data and pesists it.
  void PersistInternal();

  std::string key() const;

  // The |unused| parameter is a small hack so that we can have the
  // CacheOperationDataShim object owned by the Callback that is created for
  // this method.  See comment above CacheOperationDataShim for details.
  void OnIOComplete(CacheOperationDataShim* unused, int rv);

  int DoLoop(int rv);

  int DoGetBackendComplete(int rv);
  int DoOpenComplete(int rv);
  int DoReadComplete(int rv);
  int DoWriteComplete(int rv);
  int DoCreateOrOpenComplete(int rv);

  int DoGetBackend();
  int DoOpen();
  int DoRead();
  int DoWrite();
  int DoCreateOrOpen();

  // DoWaitForDataReadyDone is the terminal state of the read operation.
  int DoWaitForDataReadyDone();

  // DoSetDone is the terminal state of the write operation.
  int DoSetDone();

  // Tracks in a histogram the number of times data read/parse/write API calls
  // of QuicServerInfo to and from disk cache is called.
  void RecordQuicServerInfoStatus(QuicServerInfoAPICall call);

  // Tracks in a histogram the failure reasons to read/load/write of
  // QuicServerInfo to and from disk cache. It also saves the |failure| in
  // |last_failure_|.
  void RecordQuicServerInfoFailure(FailureReason failure);

  // Tracks in a histogram if |last_failure_| is not NO_FAILURE.
  void RecordLastFailure();

  CacheOperationDataShim* data_shim_;  // Owned by |io_callback_|.
  CompletionCallback io_callback_;
  State state_;
  bool ready_;
  bool found_entry_;  // Controls the behavior of DoCreateOrOpen.
  std::string new_data_;
  std::string pending_write_data_;
  const QuicServerId server_id_;
  HttpCache* const http_cache_;
  disk_cache::Backend* backend_;
  disk_cache::Entry* entry_;
  CompletionCallback wait_for_ready_callback_;
  scoped_refptr<IOBuffer> read_buffer_;
  scoped_refptr<IOBuffer> write_buffer_;
  std::string data_;
  base::TimeTicks load_start_time_;
  FailureReason last_failure_;

  base::WeakPtrFactory<DiskCacheBasedQuicServerInfo> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(DiskCacheBasedQuicServerInfo);
};

}  // namespace net

#endif  // NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_