OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/http/disk_based_cert_cache.h" | |
6 | |
7 #include <string> | |
wtc
2014/06/12 03:13:16
Nit: since the .h file includes <string>, the .cc
| |
8 | |
9 #include "base/bind.h" | |
10 #include "base/callback.h" | |
11 #include "base/callback_helpers.h" | |
12 #include "base/memory/ref_counted.h" | |
13 #include "base/memory/weak_ptr.h" | |
14 #include "base/strings/string_number_conversions.h" | |
15 #include "net/base/io_buffer.h" | |
16 #include "net/base/net_errors.h" | |
17 #include "net/cert/x509_certificate.h" | |
18 #include "net/disk_cache/disk_cache.h" | |
wtc
2014/06/12 03:13:16
The headers that are included by the .h file don't
| |
19 | |
20 namespace net { | |
21 | |
22 DiskBasedCertCache::DiskBasedCertCache(disk_cache::Backend* backend) | |
23 : backend_(backend), | |
24 active_entry_(NULL), | |
25 state_(NONE), | |
26 create_failed_(false), | |
27 active_entry_size_(0), | |
28 weak_factory_(this) { | |
29 DCHECK(backend_); | |
30 io_callback_ = | |
31 base::Bind(&DiskBasedCertCache::OnIOComplete, weak_factory_.GetWeakPtr()); | |
32 } | |
33 | |
34 DiskBasedCertCache::~DiskBasedCertCache() { | |
35 weak_factory_.InvalidateWeakPtrs(); | |
36 } | |
37 | |
38 void DiskBasedCertCache::Get( | |
39 std::string& key, | |
40 base::Callback<void(X509Certificate::OSCertHandle cert_handle)> cb) { | |
41 user_read_callback_ = cb; | |
42 | |
43 state_ = START_READ; | |
44 | |
45 int rv = backend_->OpenEntry(key, &active_entry_, io_callback_); | |
46 | |
47 DoLoop(rv); | |
48 } | |
49 | |
50 int DiskBasedCertCache::DoStartRead(int rv) { | |
51 // todo(brandonsalmon) implement error handling | |
wtc
2014/06/12 03:13:16
Our convention is all caps TODO.
| |
52 if (rv <= 0) | |
53 NOTIMPLEMENTED(); | |
54 | |
55 active_entry_size_ = active_entry_->GetDataSize(0 /* index */); | |
56 buffer = new IOBuffer(active_entry_size_); | |
57 | |
58 state_ = FINISH_READ; | |
59 | |
60 return active_entry_->ReadData( | |
61 0 /* index */, 0 /* offset */, buffer, active_entry_size_, io_callback_); | |
62 } | |
63 | |
64 int DiskBasedCertCache::DoFinishRead(int rv) { | |
65 // todo(brandonsalmon) implement error handling | |
66 if (rv <= 0) | |
67 NOTIMPLEMENTED(); | |
68 | |
69 if (user_read_callback_.is_null()) { | |
70 ResetState(); | |
71 return OK; // todo(brandonsalmon): is this ERR_ABORTED? | |
72 } | |
73 | |
74 active_cert_handle_ = X509Certificate::CreateOSCertHandleFromBytes( | |
75 buffer->data(), active_entry_size_); | |
76 | |
77 CHECK(active_cert_handle_); | |
78 | |
79 base::ResetAndReturn(&user_read_callback_).Run(active_cert_handle_); | |
80 | |
81 ResetState(); | |
82 return OK; | |
83 } | |
84 | |
85 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle, | |
86 base::Callback<void(const std::string&)> cb) { | |
87 DCHECK(!cb.is_null()); | |
88 | |
89 active_cert_handle_ = cert_handle; | |
90 | |
91 state_ = CREATE_OR_OPEN; | |
92 user_write_callback_ = cb; | |
93 DoLoop(OK); | |
94 } | |
95 | |
96 std::string DiskBasedCertCache::Key() { | |
97 CHECK(active_cert_handle_); | |
98 | |
99 SHA1HashValue fingerprint = | |
100 X509Certificate::CalculateFingerprint(active_cert_handle_); | |
101 | |
102 // should update to store the key so the data doesn't have to be encoded | |
103 // multiple times. | |
104 | |
105 return "cert:" + base::HexEncode(fingerprint.data, 20); | |
wtc
2014/06/12 03:13:16
Avoid the use of 20. Try arraysize(fingerprint.dat
| |
106 } | |
107 | |
108 void DiskBasedCertCache::DoLoop(int rv) { | |
109 do { | |
110 switch (state_) { | |
111 case CREATE_OR_OPEN: | |
112 rv = DoCreateOrOpen(rv); | |
113 break; | |
114 case START_WRITE: | |
115 rv = DoStartWrite(rv); | |
116 break; | |
117 case FINISH_CREATE_OR_OPEN: | |
118 rv = DoFinishCreateOrOpen(rv); | |
119 break; | |
120 case FINISH_WRITE: | |
121 rv = DoFinishWrite(rv); | |
122 break; | |
123 case START_READ: | |
124 rv = DoStartRead(rv); | |
125 break; | |
126 case FINISH_READ: | |
127 rv = DoFinishRead(rv); | |
128 break; | |
129 case NONE: | |
130 break; | |
131 } | |
132 } while (rv != ERR_IO_PENDING && state_ != NONE); | |
133 } | |
134 | |
135 void DiskBasedCertCache::OnIOComplete(int rv) { | |
136 // todo(brandonsalmon) Check for fatal errors? | |
137 DoLoop(rv); | |
138 } | |
139 | |
140 int DiskBasedCertCache::DoStartWrite(int rv) { | |
141 // todo(brandonsalmon) implement error handling | |
142 if (rv <= 0) | |
143 NOTIMPLEMENTED(); | |
144 | |
145 std::string write_data; | |
146 // todo(brandonsalmon) deal with faulty encoding. | |
147 bool encoded = | |
148 X509Certificate::GetDEREncoded(active_cert_handle_, &write_data); | |
149 | |
150 if (!encoded) | |
151 NOTIMPLEMENTED(); | |
152 | |
153 buffer = new IOBuffer(write_data.size()); | |
154 memcpy(buffer->data(), write_data.data(), write_data.size()); | |
155 | |
156 state_ = FINISH_WRITE; | |
157 | |
158 return active_entry_->WriteData(0 /* index */, | |
159 0 /* offset */, | |
160 buffer, | |
161 write_data.size(), | |
162 io_callback_, | |
163 true /* truncate */); | |
164 } | |
165 | |
166 int DiskBasedCertCache::DoCreateOrOpen(int rv) { | |
167 DCHECK(active_entry_ == NULL); | |
168 | |
169 state_ = FINISH_CREATE_OR_OPEN; | |
170 | |
171 if (create_failed_) { | |
172 return backend_->OpenEntry(Key(), &active_entry_, io_callback_); | |
173 } | |
174 | |
175 return backend_->CreateEntry(Key(), &active_entry_, io_callback_); | |
176 } | |
177 | |
178 int DiskBasedCertCache::DoFinishCreateOrOpen(int rv) { | |
179 // ERR_FAILED implies create entry failed, and we should try opening instead. | |
180 //!create_failed is checked to make sure we only try to open once. | |
181 if (rv == ERR_FAILED && !create_failed_) { | |
182 create_failed_ = true; | |
183 state_ = CREATE_OR_OPEN; | |
184 return OK; | |
185 } else if (rv <= 0) { | |
186 NOTIMPLEMENTED(); | |
187 } | |
188 | |
189 state_ = START_WRITE; | |
190 return OK; | |
191 } | |
192 | |
193 int DiskBasedCertCache::DoFinishWrite(int rv) { | |
194 // todo(brandonsalmon) implement error handling | |
195 if (rv <= 0) | |
196 NOTIMPLEMENTED(); | |
197 | |
198 if (user_write_callback_.is_null()) { | |
199 ResetState(); | |
200 return OK; // todo(brandonsalmon): is this ERR_ABORTED? | |
201 } | |
202 | |
203 base::ResetAndReturn(&user_write_callback_).Run(Key()); | |
204 ResetState(); | |
205 return OK; | |
206 } | |
207 | |
208 void DiskBasedCertCache::ResetState() { | |
209 state_ = NONE; | |
210 active_entry_->Close(); | |
211 active_entry_ = NULL; | |
212 active_cert_handle_ = NULL; | |
213 user_write_callback_.Reset(); | |
214 user_read_callback_.Reset(); | |
215 } | |
216 | |
217 } // namespace net | |
OLD | NEW |