Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.net; | |
| 6 | |
| 7 import java.util.ArrayList; | |
| 8 import java.util.Collections; | |
| 9 import java.util.List; | |
| 10 import java.util.Locale; | |
| 11 import java.util.Map; | |
| 12 import java.util.TreeMap; | |
| 13 | |
| 14 /** | |
| 15 * Contains basic information about a response. Sent to the embedder whenever | |
| 16 * headers are received. | |
| 17 */ | |
| 18 // TODO(mef): Remove ResponseInfo after caller updates. | |
|
pauljensen
2015/09/25 18:30:16
This class has pretty crazy mutability requirement
| |
| 19 public final class UrlResponseInfo implements ResponseInfo { | |
| 20 private final List<String> mResponseInfoUrlChain; | |
| 21 private final int mHttpStatusCode; | |
| 22 private final String mHttpStatusText; | |
| 23 private final boolean mWasCached; | |
| 24 private final String mNegotiatedProtocol; | |
| 25 private final String mProxyServer; | |
| 26 private final List<Map.Entry<String, String>> mAllHeadersList; | |
| 27 private Map<String, List<String>> mResponseHeaders; | |
| 28 private volatile long mReceivedBytesCount; | |
|
xunjieli
2015/09/25 13:54:32
We are only updating this on the network thread. O
mef
2015/09/25 15:58:27
Um, what if the app holds on to UrlResponseInfo an
xunjieli
2015/09/25 16:16:34
I see. that volatile keyword might help then.
pauljensen
2015/09/25 18:30:16
volatile is insufficient for items larger than sig
mef
2015/09/25 20:08:50
Arghh! Thanks for catching this. Done.
| |
| 29 | |
| 30 UrlResponseInfo(List<String> urlChain, int httpStatusCode, String httpStatus Text, | |
| 31 List<Map.Entry<String, String>> allHeadersList, boolean wasCached, | |
| 32 String negotiatedProtocol, String proxyServer) { | |
| 33 mResponseInfoUrlChain = Collections.unmodifiableList(urlChain); | |
| 34 mHttpStatusCode = httpStatusCode; | |
| 35 mHttpStatusText = httpStatusText; | |
| 36 mAllHeadersList = Collections.unmodifiableList(allHeadersList); | |
| 37 mWasCached = wasCached; | |
| 38 mNegotiatedProtocol = negotiatedProtocol; | |
| 39 mProxyServer = proxyServer; | |
| 40 mReceivedBytesCount = 0; | |
| 41 } | |
| 42 | |
| 43 /** | |
| 44 * Returns the URL the response is for. This is the URL after following | |
| 45 * redirects, so it may not be the originally requested URL. | |
| 46 * @return the URL the response is for. | |
| 47 */ | |
| 48 @Override | |
| 49 public String getUrl() { | |
| 50 return mResponseInfoUrlChain.get(mResponseInfoUrlChain.size() - 1); | |
| 51 } | |
| 52 | |
| 53 /** | |
| 54 * Returns the URL chain. The first entry is the origianlly requested URL; | |
| 55 * the following entries are redirects followed. | |
| 56 * @return the URL chain. | |
| 57 */ | |
| 58 @Override | |
| 59 public List<String> getUrlChain() { | |
| 60 return mResponseInfoUrlChain; | |
| 61 } | |
| 62 | |
| 63 /** | |
| 64 * Returns the HTTP status code. When a resource is retrieved from the cache , | |
| 65 * whether it was revalidated or not, the original status code is returned. | |
| 66 * @return the HTTP status code. | |
| 67 */ | |
| 68 @Override | |
| 69 public int getHttpStatusCode() { | |
| 70 return mHttpStatusCode; | |
| 71 } | |
| 72 | |
| 73 /** | |
| 74 * Returns the HTTP status text of the status line. For example, if the | |
| 75 * request has a "HTTP/1.1 200 OK" response, this method returns "OK". | |
| 76 * @return the HTTP status text of the status line. | |
| 77 */ | |
| 78 @Override | |
| 79 public String getHttpStatusText() { | |
| 80 return mHttpStatusText; | |
| 81 } | |
| 82 | |
| 83 /** | |
| 84 * Returns an unmodifiable list of response header field and value pairs. | |
| 85 * The headers are in the same order they are received over the wire. | |
| 86 * @return an unmodifiable list of response header field and value pairs. | |
| 87 */ | |
| 88 @Override | |
| 89 public List<Map.Entry<String, String>> getAllHeadersAsList() { | |
| 90 return mAllHeadersList; | |
| 91 } | |
| 92 | |
| 93 /** | |
| 94 * Returns an unmodifiable map of the response-header fields and values. | |
| 95 * Each list of values for a single header field is in the same order they | |
| 96 * were received over the wire. | |
| 97 * @return an unmodifiable map of the response-header fields and values. | |
| 98 */ | |
| 99 @Override | |
| 100 public Map<String, List<String>> getAllHeaders() { | |
|
xunjieli
2015/09/25 13:54:32
It's sad that even though we have Map.Entry, we st
mef
2015/09/25 15:58:27
Theoretically it will help if they want to headers
xunjieli
2015/09/25 16:16:34
I see. That makes sense. Thanks!
| |
| 101 if (mResponseHeaders != null) { | |
| 102 return mResponseHeaders; | |
| 103 } | |
| 104 Map<String, List<String>> map = | |
| 105 new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER) ; | |
| 106 for (Map.Entry<String, String> entry : mAllHeadersList) { | |
| 107 List<String> values = new ArrayList<String>(); | |
| 108 if (map.containsKey(entry.getKey())) { | |
| 109 values.addAll(map.get(entry.getKey())); | |
| 110 } | |
| 111 values.add(entry.getValue()); | |
| 112 map.put(entry.getKey(), Collections.unmodifiableList(values)); | |
| 113 } | |
| 114 mResponseHeaders = Collections.unmodifiableMap(map); | |
| 115 return mResponseHeaders; | |
| 116 } | |
| 117 | |
| 118 /** | |
| 119 * Returns {@code true} if the response came from the cache, including | |
| 120 * requests that were revalidated over the network before being retrieved | |
| 121 * from the cache. | |
| 122 * @return {@code true} if the response came from the cache, {@code false} | |
| 123 * otherwise. | |
| 124 */ | |
| 125 @Override | |
| 126 public boolean wasCached() { | |
| 127 return mWasCached; | |
| 128 } | |
| 129 | |
| 130 /** | |
| 131 * Returns the protocol (e.g. "quic/1+spdy/3") negotiated with the server. | |
| 132 * Returns an empty string if no protocol was negotiated, the protocol is | |
| 133 * not known, or when using plain HTTP or HTTPS. | |
| 134 * @return the protocol negotiated with the server. | |
| 135 */ | |
| 136 // TODO(mef): Figure out what this returns in the cached case, both with | |
| 137 // and without a revalidation request. | |
| 138 @Override | |
| 139 public String getNegotiatedProtocol() { | |
| 140 return mNegotiatedProtocol; | |
| 141 } | |
| 142 | |
| 143 /** | |
| 144 * Returns the proxy server that was used for the request. | |
| 145 * @return the proxy server that was used for the request. | |
| 146 */ | |
| 147 @Override | |
| 148 public String getProxyServer() { | |
| 149 return mProxyServer; | |
| 150 } | |
| 151 | |
| 152 /** | |
| 153 * Returns the total amount of data received from network after SSL | |
| 154 * decoding and proxy handling but before gzip and SDCH decompression. | |
|
pauljensen
2015/09/25 18:30:17
Though this sentence is very accurate and precise,
mef
2015/09/25 20:08:50
Done.
| |
| 155 * Available on request completion. | |
|
pauljensen
2015/09/25 18:30:16
I think we need a further comment about how this v
pauljensen
2015/09/25 18:30:17
I don't think "Available on request completion." i
mef
2015/09/25 20:08:50
In order to reduce magic nature, would it make sen
pauljensen
2015/10/06 12:55:41
So I'd actually like to live in a world where it g
| |
| 156 */ | |
| 157 public long getReceivedBytesCount() { | |
| 158 return mReceivedBytesCount; | |
| 159 } | |
| 160 | |
| 161 @Override | |
| 162 public String toString() { | |
| 163 return String.format(Locale.ROOT, "UrlResponseInfo[%s]: urlChain = %s, " | |
| 164 + "httpStatus = %d %s, headers = %s, wasCached = %b, " | |
| 165 + "negotiatedProtocol = %s, proxyServer= %s, receivedByt esCount = %d", | |
| 166 getUrl(), getUrlChain().toString(), getHttpStatusCode(), getHttp StatusText(), | |
| 167 getAllHeadersAsList().toString(), wasCached(), getNegotiatedProt ocol(), | |
| 168 getProxyServer(), getReceivedBytesCount()); | |
| 169 } | |
| 170 | |
| 171 void updateReceivedBytesCount(long currentReceivedBytesCount) { | |
|
xunjieli
2015/09/25 13:54:32
Maybe rename this method as "setReceivedBytesCount
mef
2015/09/25 15:58:27
Sounds good, will do. I also wonder whether it sho
xunjieli
2015/09/25 16:16:34
I will vote for that. But could also be in a separ
mef
2015/09/25 20:08:50
Acknowledged.
mef
2015/09/25 20:53:42
Done.
| |
| 172 mReceivedBytesCount = currentReceivedBytesCount; | |
| 173 } | |
| 174 } | |
| 175 ; | |
| OLD | NEW |