OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.cookies; | 5 package org.chromium.chrome.browser.cookies; |
6 | 6 |
7 import java.io.ByteArrayOutputStream; | |
7 import java.io.DataInputStream; | 8 import java.io.DataInputStream; |
8 import java.io.DataOutputStream; | 9 import java.io.DataOutputStream; |
10 import java.io.EOFException; | |
11 import java.io.File; | |
12 import java.io.FileInputStream; | |
9 import java.io.IOException; | 13 import java.io.IOException; |
14 import java.util.ArrayList; | |
15 import java.util.List; | |
16 | |
17 import javax.crypto.Cipher; | |
18 import javax.crypto.CipherInputStream; | |
19 import javax.crypto.CipherOutputStream; | |
10 | 20 |
11 /** | 21 /** |
12 * Java representation of net/cookies/canonical_cookie.h. | 22 * Java representation of net/cookies/canonical_cookie.h. |
23 * | |
24 * Also has static methods to write and restore list of CanonicalCookies to and from disk. | |
13 */ | 25 */ |
14 class CanonicalCookie { | 26 class CanonicalCookie { |
15 private final String mUrl; | 27 private final String mUrl; |
16 private final String mName; | 28 private final String mName; |
17 private final String mValue; | 29 private final String mValue; |
18 private final String mDomain; | 30 private final String mDomain; |
19 private final String mPath; | 31 private final String mPath; |
20 private final long mCreation; | 32 private final long mCreation; |
21 private final long mExpiration; | 33 private final long mExpiration; |
22 private final long mLastAccess; | 34 private final long mLastAccess; |
23 private final boolean mSecure; | 35 private final boolean mSecure; |
24 private final boolean mHttpOnly; | 36 private final boolean mHttpOnly; |
25 private final boolean mSameSite; | 37 private final int mSameSite; |
26 private final int mPriority; | 38 private final int mPriority; |
27 | 39 |
28 /** Constructs a CanonicalCookie */ | 40 /** Constructs a CanonicalCookie */ |
29 CanonicalCookie(String url, String name, String value, String domain, String path, | 41 CanonicalCookie(String url, String name, String value, String domain, String path, |
30 long creation, long expiration, long lastAccess, boolean secure, boo lean httpOnly, | 42 long creation, long expiration, long lastAccess, boolean secure, boo lean httpOnly, |
31 boolean sameSite, int priority) { | 43 int sameSite, int priority) { |
32 mUrl = url; | 44 mUrl = url; |
33 mName = name; | 45 mName = name; |
34 mValue = value; | 46 mValue = value; |
35 mDomain = domain; | 47 mDomain = domain; |
36 mPath = path; | 48 mPath = path; |
37 mCreation = creation; | 49 mCreation = creation; |
38 mExpiration = expiration; | 50 mExpiration = expiration; |
39 mLastAccess = lastAccess; | 51 mLastAccess = lastAccess; |
40 mSecure = secure; | 52 mSecure = secure; |
41 mHttpOnly = httpOnly; | 53 mHttpOnly = httpOnly; |
42 mSameSite = sameSite; | 54 mSameSite = sameSite; |
43 mPriority = priority; | 55 mPriority = priority; |
44 } | 56 } |
45 | 57 |
46 /** @return Priority of the cookie. */ | 58 /** @return Priority of the cookie. */ |
47 int getPriority() { | 59 int getPriority() { |
48 return mPriority; | 60 return mPriority; |
49 } | 61 } |
50 | 62 |
51 /** @return True if the cookie is HTTP only. */ | 63 /** @return True if the cookie is HTTP only. */ |
52 boolean isHttpOnly() { | 64 boolean isHttpOnly() { |
53 return mHttpOnly; | 65 return mHttpOnly; |
54 } | 66 } |
55 | 67 |
56 /** @return True if the cookie is Same-Site. */ | 68 /** @return SameSite enum */ |
57 boolean isSameSite() { | 69 int getSameSite() { |
58 return mSameSite; | 70 return mSameSite; |
59 } | 71 } |
60 | 72 |
61 /** @return True if the cookie is secure. */ | 73 /** @return True if the cookie is secure. */ |
62 boolean isSecure() { | 74 boolean isSecure() { |
63 return mSecure; | 75 return mSecure; |
64 } | 76 } |
65 | 77 |
66 /** @return Last accessed time. */ | 78 /** @return Last accessed time. */ |
67 long getLastAccessDate() { | 79 long getLastAccessDate() { |
(...skipping 28 matching lines...) Expand all Loading... | |
96 /** @return Cookie domain. */ | 108 /** @return Cookie domain. */ |
97 String getDomain() { | 109 String getDomain() { |
98 return mDomain; | 110 return mDomain; |
99 } | 111 } |
100 | 112 |
101 /** @return Cookie value. */ | 113 /** @return Cookie value. */ |
102 String getValue() { | 114 String getValue() { |
103 return mValue; | 115 return mValue; |
104 } | 116 } |
105 | 117 |
106 /** | 118 private static final int SERIALIZATION_VERSION = 20160426; |
107 * Serializes for saving to disk. Does not close the stream. | 119 |
108 * It is up to the caller to do so. | 120 // Not private for tests. |
109 * | 121 static void saveToStream(DataOutputStream out, CanonicalCookie[] cookies) th rows IOException { |
110 * @param out Stream to write the cookie to. | 122 if (out == null) { |
111 */ | 123 throw new IllegalArgumentException("out arg is null"); |
112 void saveToStream(DataOutputStream out) throws IOException { | 124 } |
125 if (cookies == null) { | |
126 throw new IllegalArgumentException("cookies arg is null"); | |
127 } | |
128 for (CanonicalCookie cookie : cookies) { | |
129 if (cookie == null) { | |
130 throw new IllegalArgumentException("cookies arg contains null va lue"); | |
131 } | |
132 } | |
133 | |
134 int length = cookies.length; | |
135 out.writeInt(SERIALIZATION_VERSION); | |
136 out.writeInt(length); | |
137 for (int i = 0; i < length; ++i) { | |
138 cookies[i].saveToStream(out); | |
139 } | |
140 } | |
141 | |
142 // Not private for tests. | |
143 static class UnexpectedFormatException extends Exception { | |
144 public UnexpectedFormatException(String message) { | |
145 super(message); | |
146 } | |
147 } | |
148 | |
149 // Not private for tests. | |
150 static List<CanonicalCookie> readFromStream(DataInputStream in) | |
151 throws IOException, UnexpectedFormatException { | |
152 if (in == null) { | |
153 throw new IllegalArgumentException("in arg is null"); | |
154 } | |
155 | |
156 final int version = in.readInt(); | |
157 if (version != SERIALIZATION_VERSION) { | |
158 throw new UnexpectedFormatException("Unexpected version"); | |
159 } | |
160 final int length = in.readInt(); | |
161 if (length < 0) { | |
162 throw new UnexpectedFormatException("Negative length: " + length); | |
163 } | |
164 | |
165 ArrayList<CanonicalCookie> cookies = new ArrayList<>(length); | |
166 for (int i = 0; i < length; ++i) { | |
167 cookies.add(createFromStream(in)); | |
168 } | |
169 return cookies; | |
170 } | |
171 | |
172 private void saveToStream(DataOutputStream out) throws IOException { | |
113 out.writeUTF(mUrl); | 173 out.writeUTF(mUrl); |
114 out.writeUTF(mName); | 174 out.writeUTF(mName); |
115 out.writeUTF(mValue); | 175 out.writeUTF(mValue); |
116 out.writeUTF(mDomain); | 176 out.writeUTF(mDomain); |
117 out.writeUTF(mPath); | 177 out.writeUTF(mPath); |
118 out.writeLong(mCreation); | 178 out.writeLong(mCreation); |
119 out.writeLong(mExpiration); | 179 out.writeLong(mExpiration); |
120 out.writeLong(mLastAccess); | 180 out.writeLong(mLastAccess); |
121 out.writeBoolean(mSecure); | 181 out.writeBoolean(mSecure); |
122 out.writeBoolean(mHttpOnly); | 182 out.writeBoolean(mHttpOnly); |
123 out.writeBoolean(mSameSite); | 183 out.writeInt(mSameSite); |
124 out.writeInt(mPriority); | 184 out.writeInt(mPriority); |
125 } | 185 } |
126 | 186 |
127 /** | 187 private static CanonicalCookie createFromStream(DataInputStream in) throws I OException { |
128 * Constructs a cookie by deserializing a single entry from the | |
129 * input stream. | |
130 * | |
131 * @param in Stream to read a cookie entry from. | |
132 */ | |
133 static CanonicalCookie createFromStream(DataInputStream in) | |
134 throws IOException { | |
135 return new CanonicalCookie(in.readUTF(), in.readUTF(), in.readUTF(), in. readUTF(), | 188 return new CanonicalCookie(in.readUTF(), in.readUTF(), in.readUTF(), in. readUTF(), |
136 in.readUTF(), in.readLong(), in.readLong(), in.readLong(), in.re adBoolean(), | 189 in.readUTF(), in.readLong(), in.readLong(), in.readLong(), in.re adBoolean(), |
137 in.readBoolean(), in.readBoolean(), in.readInt()); | 190 in.readBoolean(), in.readInt(), in.readInt()); |
191 } | |
192 | |
193 // Not private for tests. | |
194 static final String LEGACY_FORMAT_MAGIC_STRING = "c0Ok135"; | |
195 | |
196 // If this raises UnexpectedFormatException, then caller should rewind the s tream, and try | |
197 // readFromStream instead. | |
198 // Not private for tests. | |
199 static ArrayList<CanonicalCookie> readFromLegacyStream(DataInputStream in) | |
200 throws IOException, UnexpectedFormatException { | |
201 // Identify legacy format by the magic string. | |
202 try { | |
203 String check = in.readUTF(); | |
204 if (!LEGACY_FORMAT_MAGIC_STRING.equals(check)) { | |
205 throw new UnexpectedFormatException("No magic string"); | |
206 } | |
207 } catch (IOException e) { | |
208 throw new UnexpectedFormatException("IOException while reading magic string"); | |
209 } | |
210 | |
211 ArrayList<CanonicalCookie> cookies = new ArrayList<>(); | |
212 try { | |
213 while (true) { | |
214 CanonicalCookie cookie = createFromLegacyStream(in); | |
215 cookies.add(cookie); | |
216 } | |
217 } catch (EOFException ignored) { | |
218 // We are done. | |
219 } | |
220 return cookies; | |
221 } | |
222 | |
223 // Legacy format stored sameSite as a boolean. | |
224 private static CanonicalCookie createFromLegacyStream(DataInputStream in) th rows IOException { | |
225 return new CanonicalCookie(in.readUTF(), in.readUTF(), in.readUTF(), in. readUTF(), | |
226 in.readUTF(), in.readLong(), in.readLong(), in.readLong(), in.re adBoolean(), | |
227 in.readBoolean(), in.readBoolean() ? 1 : 0, in.readInt()); | |
228 } | |
229 | |
230 // This leaks implementation details from CookiesFetcher. But CookiesFetcher can't be unit | |
231 // tested. | |
232 public static List<CanonicalCookie> readFromFileUnknownFormat(File fileIn, C ipher cipher) | |
Yaron
2016/04/28 03:43:10
Couldn't you at least omit "public" and leave this
boliu
2016/04/28 17:49:26
I guess .cookies is its own package, so there actu
| |
233 throws IOException, UnexpectedFormatException { | |
234 DataInputStream in = null; | |
235 try { | |
236 FileInputStream streamIn = new FileInputStream(fileIn); | |
237 in = new DataInputStream(new CipherInputStream(streamIn, cipher)); | |
238 return readFromLegacyStream(in); | |
239 } catch (UnexpectedFormatException ignored) { | |
240 // Maybe in new format. | |
241 } finally { | |
242 if (in != null) { | |
243 in.close(); | |
244 } | |
245 in = null; | |
Yaron
2016/04/28 03:43:10
Do you really need to null this out?
boliu
2016/04/28 17:49:26
I want to make sure that the "in" here and the "in
| |
246 } | |
247 | |
248 try { | |
249 FileInputStream streamIn = new FileInputStream(fileIn); | |
250 in = new DataInputStream(new CipherInputStream(streamIn, cipher)); | |
251 return CanonicalCookie.readFromStream(in); | |
252 } finally { | |
253 if (in != null) { | |
254 in.close(); | |
255 } | |
256 in = null; | |
Yaron
2016/04/28 03:43:10
same here
boliu
2016/04/28 17:49:25
ditto
| |
257 } | |
258 } | |
259 | |
260 // This leaks implementation details from CookiesFetcher. But CookiesFetcher can't be unit | |
261 // tested. | |
262 public static byte[] writeToByteArray(Cipher cipher, CanonicalCookie cookies []) | |
263 throws IOException { | |
264 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); | |
265 CipherOutputStream cipherOut = new CipherOutputStream(byteOut, cipher); | |
266 DataOutputStream out = new DataOutputStream(cipherOut); | |
267 CanonicalCookie.saveToStream(out, cookies); | |
268 out.close(); | |
269 return byteOut.toByteArray(); | |
138 } | 270 } |
139 } | 271 } |
OLD | NEW |