Commit 5803b253 by olly Committed by Oliver Woodman

No-op reorder of CronetDataSource methods

This change is a no-op reodering, as a precursor to
further cleanup. The public methods are grouped by
the class/interface they implement. The private methods
are ordered with things that will become static in
a subsequent change at the bottom.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=135372629
parent 93c2133f
...@@ -169,6 +169,8 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou ...@@ -169,6 +169,8 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
connectionState = IDLE_CONNECTION; connectionState = IDLE_CONNECTION;
} }
// HttpDataSource implementation.
@Override @Override
public void setRequestProperty(String name, String value) { public void setRequestProperty(String name, String value) {
synchronized (requestProperties) { synchronized (requestProperties) {
...@@ -196,6 +198,11 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou ...@@ -196,6 +198,11 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
} }
@Override @Override
public Uri getUri() {
return Uri.parse(currentUrl);
}
@Override
public long open(DataSpec dataSpec) throws HttpDataSourceException { public long open(DataSpec dataSpec) throws HttpDataSourceException {
Assertions.checkNotNull(dataSpec); Assertions.checkNotNull(dataSpec);
synchronized (this) { synchronized (this) {
...@@ -224,64 +231,99 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou ...@@ -224,64 +231,99 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
return contentLength; return contentLength;
} }
private void startRequest(DataSpec dataSpec) throws HttpDataSourceException { @Override
currentUrl = dataSpec.uri.toString(); public int read(byte[] buffer, int offset, int readLength) throws HttpDataSourceException {
currentDataSpec = dataSpec; synchronized (this) {
UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder(currentUrl, this, executor, Assertions.checkState(connectionState == OPEN_CONNECTION);
cronetEngine); }
fillCurrentRequestHeader(urlRequestBuilder);
fillCurrentRequestPostBody(urlRequestBuilder, dataSpec);
currentUrlRequest = urlRequestBuilder.build();
currentUrlRequest.start();
}
private void fillCurrentRequestHeader(UrlRequest.Builder urlRequestBuilder) { if (readLength == 0) {
synchronized (requestProperties) { return 0;
for (Entry<String, String> headerEntry : requestProperties.entrySet()) { }
urlRequestBuilder.addHeader(headerEntry.getKey(), headerEntry.getValue()); if (expectedBytesRemainingToRead != null && expectedBytesRemainingToRead.get() == 0) {
return C.RESULT_END_OF_INPUT;
}
if (!hasData) {
// Read more data from cronet.
operation.close();
readBuffer.clear();
currentUrlRequest.read(readBuffer);
if (!operation.block(readTimeoutMs)) {
throw new HttpDataSourceException(
new SocketTimeoutException(), currentDataSpec, HttpDataSourceException.TYPE_READ);
}
if (exception != null) {
throw exception;
}
// The expected response length is unknown, but cronet has indicated that the request
// already finished successfully.
if (responseFinished) {
return C.RESULT_END_OF_INPUT;
} }
} }
if (currentDataSpec.position == 0 && currentDataSpec.length == C.LENGTH_UNSET) {
// Not required. int bytesRead = Math.min(readBuffer.remaining(), readLength);
return; readBuffer.get(buffer, offset, bytesRead);
if (!readBuffer.hasRemaining()) {
hasData = false;
} }
StringBuilder rangeValue = new StringBuilder();
rangeValue.append("bytes="); if (expectedBytesRemainingToRead != null) {
rangeValue.append(currentDataSpec.position); expectedBytesRemainingToRead.addAndGet(-bytesRead);
rangeValue.append("-");
if (currentDataSpec.length != C.LENGTH_UNSET) {
rangeValue.append(currentDataSpec.position + currentDataSpec.length - 1);
} }
urlRequestBuilder.addHeader("Range", rangeValue.toString()); if (listener != null) {
listener.onBytesTransferred(this, bytesRead);
}
return bytesRead;
} }
private void fillCurrentRequestPostBody(UrlRequest.Builder urlRequestBuilder, DataSpec dataSpec) @Override
throws HttpDataSourceException { public synchronized void close() {
if (dataSpec.postBody != null) { if (currentUrlRequest != null) {
if (!requestProperties.containsKey("Content-Type")) { currentUrlRequest.cancel();
throw new OpenException("POST requests must set a Content-Type header", dataSpec, currentUrlRequest = null;
getCurrentRequestStatus()); }
currentDataSpec = null;
currentUrl = null;
exception = null;
contentLength = 0;
hasData = false;
responseInfo = null;
expectedBytesRemainingToRead = null;
responseFinished = false;
try {
if (listener != null && connectionState == OPEN_CONNECTION) {
listener.onTransferEnd(this);
} }
urlRequestBuilder.setUploadDataProvider( } finally {
new ByteArrayUploadDataProvider(dataSpec.postBody), executor); connectionState = IDLE_CONNECTION;
} }
} }
// UrlRequest.Callback implementation
@Override @Override
public synchronized void onFailed(UrlRequest request, UrlResponseInfo info, public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
UrlRequestException error) {
if (request != currentUrlRequest) { if (request != currentUrlRequest) {
return; return;
} }
if (connectionState == OPENING_CONNECTION) { if (currentDataSpec.postBody != null) {
IOException cause = error.getErrorCode() == UrlRequestException.ERROR_HOSTNAME_NOT_RESOLVED int responseCode = info.getHttpStatusCode();
? new UnknownHostException() : error; // The industry standard is to disregard POST redirects when the status code is 307 or 308.
exception = new OpenException(cause, currentDataSpec, getCurrentRequestStatus()); // For other redirect response codes the POST request is converted to a GET request and the
} else if (connectionState == OPEN_CONNECTION) { // redirect is followed.
exception = new HttpDataSourceException(error, currentDataSpec, if (responseCode == 307 || responseCode == 308) {
HttpDataSourceException.TYPE_READ); exception = new OpenException("POST request redirected with 307 or 308 response code",
currentDataSpec, getCurrentRequestStatus());
operation.open();
return;
}
} }
operation.open(); if (resetTimeoutOnRedirects) {
resetConnectTimeout();
}
request.followRedirect();
} }
@Override @Override
...@@ -322,21 +364,86 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou ...@@ -322,21 +364,86 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
} }
} }
/** @Override
* Returns {@code true} iff the content is compressed. public synchronized void onReadCompleted(UrlRequest request, UrlResponseInfo info,
* ByteBuffer buffer) {
* <p>If {@code true}, clients cannot use the value of content length from the request headers to if (request != currentUrlRequest) {
* read the data, since Cronet returns the uncompressed data and this content length reflects the return;
* compressed content length. }
*/ readBuffer.flip();
private boolean isCompressed(UrlResponseInfo info) { hasData = true;
for (Map.Entry<String, String> entry : info.getAllHeadersAsList()) { operation.open();
if (entry.getKey().equalsIgnoreCase("Content-Encoding")) { }
return !entry.getValue().equalsIgnoreCase("identity");
@Override
public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
if (request != currentUrlRequest) {
return;
}
responseFinished = true;
operation.open();
}
@Override
public synchronized void onFailed(UrlRequest request, UrlResponseInfo info,
UrlRequestException error) {
if (request != currentUrlRequest) {
return;
}
if (connectionState == OPENING_CONNECTION) {
IOException cause = error.getErrorCode() == UrlRequestException.ERROR_HOSTNAME_NOT_RESOLVED
? new UnknownHostException() : error;
exception = new OpenException(cause, currentDataSpec, getCurrentRequestStatus());
} else if (connectionState == OPEN_CONNECTION) {
exception = new HttpDataSourceException(error, currentDataSpec,
HttpDataSourceException.TYPE_READ);
}
operation.open();
}
// Internal methods.
private void fillCurrentRequestHeader(UrlRequest.Builder urlRequestBuilder) {
synchronized (requestProperties) {
for (Entry<String, String> headerEntry : requestProperties.entrySet()) {
urlRequestBuilder.addHeader(headerEntry.getKey(), headerEntry.getValue());
} }
} }
if (currentDataSpec.position == 0 && currentDataSpec.length == C.LENGTH_UNSET) {
// Not required.
return;
}
StringBuilder rangeValue = new StringBuilder();
rangeValue.append("bytes=");
rangeValue.append(currentDataSpec.position);
rangeValue.append("-");
if (currentDataSpec.length != C.LENGTH_UNSET) {
rangeValue.append(currentDataSpec.position + currentDataSpec.length - 1);
}
urlRequestBuilder.addHeader("Range", rangeValue.toString());
}
return false; private void fillCurrentRequestPostBody(UrlRequest.Builder urlRequestBuilder, DataSpec dataSpec)
throws HttpDataSourceException {
if (dataSpec.postBody != null) {
if (!requestProperties.containsKey("Content-Type")) {
throw new OpenException("POST requests must set a Content-Type header", dataSpec,
getCurrentRequestStatus());
}
urlRequestBuilder.setUploadDataProvider(
new ByteArrayUploadDataProvider(dataSpec.postBody), executor);
}
}
private void startRequest(DataSpec dataSpec) throws HttpDataSourceException {
currentUrl = dataSpec.uri.toString();
currentDataSpec = dataSpec;
UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder(currentUrl, this, executor,
cronetEngine);
fillCurrentRequestHeader(urlRequestBuilder);
fillCurrentRequestPostBody(urlRequestBuilder, dataSpec);
currentUrlRequest = urlRequestBuilder.build();
currentUrlRequest.start();
} }
private void validateResponse(UrlResponseInfo info) throws HttpDataSourceException { private void validateResponse(UrlResponseInfo info) throws HttpDataSourceException {
...@@ -361,6 +468,30 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou ...@@ -361,6 +468,30 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
} }
} }
private boolean blockUntilConnectTimeout() {
long now = clock.elapsedRealtime();
boolean opened = false;
while (!opened && now < currentConnectTimeoutMs) {
opened = operation.block(currentConnectTimeoutMs - now + 5 /* fudge factor */);
now = clock.elapsedRealtime();
}
return opened;
}
private void resetConnectTimeout() {
currentConnectTimeoutMs = clock.elapsedRealtime() + connectTimeoutMs;
}
private boolean isCompressed(UrlResponseInfo info) {
for (Map.Entry<String, String> entry : info.getAllHeadersAsList()) {
if (entry.getKey().equalsIgnoreCase("Content-Encoding")) {
return !entry.getValue().equalsIgnoreCase("identity");
}
}
return false;
}
private long getContentLength(Map<String, List<String>> headers) { private long getContentLength(Map<String, List<String>> headers) {
// Logic copied from {@code DefaultHttpDataSource} // Logic copied from {@code DefaultHttpDataSource}
long contentLength = C.LENGTH_UNSET; long contentLength = C.LENGTH_UNSET;
...@@ -404,130 +535,6 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou ...@@ -404,130 +535,6 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
return contentLength; return contentLength;
} }
@Override
public int read(byte[] buffer, int offset, int readLength) throws HttpDataSourceException {
synchronized (this) {
Assertions.checkState(connectionState == OPEN_CONNECTION);
}
if (readLength == 0) {
return 0;
}
if (expectedBytesRemainingToRead != null && expectedBytesRemainingToRead.get() == 0) {
return C.RESULT_END_OF_INPUT;
}
if (!hasData) {
// Read more data from cronet.
operation.close();
readBuffer.clear();
currentUrlRequest.read(readBuffer);
if (!operation.block(readTimeoutMs)) {
throw new HttpDataSourceException(
new SocketTimeoutException(), currentDataSpec, HttpDataSourceException.TYPE_READ);
}
if (exception != null) {
throw exception;
}
// The expected response length is unknown, but cronet has indicated that the request
// already finished successfully.
if (responseFinished) {
return C.RESULT_END_OF_INPUT;
}
}
int bytesRead = Math.min(readBuffer.remaining(), readLength);
readBuffer.get(buffer, offset, bytesRead);
if (!readBuffer.hasRemaining()) {
hasData = false;
}
if (expectedBytesRemainingToRead != null) {
expectedBytesRemainingToRead.addAndGet(-bytesRead);
}
if (listener != null) {
listener.onBytesTransferred(this, bytesRead);
}
return bytesRead;
}
@Override
public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
if (request != currentUrlRequest) {
return;
}
if (currentDataSpec.postBody != null) {
int responseCode = info.getHttpStatusCode();
// The industry standard is to disregard POST redirects when the status code is 307 or 308.
// For other redirect response codes the POST request is converted to a GET request and the
// redirect is followed.
if (responseCode == 307 || responseCode == 308) {
exception = new OpenException("POST request redirected with 307 or 308 response code",
currentDataSpec, getCurrentRequestStatus());
operation.open();
return;
}
}
if (resetTimeoutOnRedirects) {
resetConnectTimeout();
}
request.followRedirect();
}
@Override
public synchronized void onReadCompleted(UrlRequest request, UrlResponseInfo info,
ByteBuffer buffer) {
if (request != currentUrlRequest) {
return;
}
readBuffer.flip();
hasData = true;
operation.open();
}
@Override
public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
if (request != currentUrlRequest) {
return;
}
responseFinished = true;
operation.open();
}
@Override
public synchronized void close() {
if (currentUrlRequest != null) {
currentUrlRequest.cancel();
currentUrlRequest = null;
}
currentDataSpec = null;
currentUrl = null;
exception = null;
contentLength = 0;
hasData = false;
responseInfo = null;
expectedBytesRemainingToRead = null;
responseFinished = false;
try {
if (listener != null && connectionState == OPEN_CONNECTION) {
listener.onTransferEnd(this);
}
} finally {
connectionState = IDLE_CONNECTION;
}
}
@Override
public Uri getUri() {
return Uri.parse(currentUrl);
}
private void log(int priority, String message) {
if (Log.isLoggable(TAG, priority)) {
Log.println(priority, TAG, message);
}
}
private int getCurrentRequestStatus() { private int getCurrentRequestStatus() {
if (currentUrlRequest == null) { if (currentUrlRequest == null) {
return UrlRequest.Status.IDLE; return UrlRequest.Status.IDLE;
...@@ -544,18 +551,10 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou ...@@ -544,18 +551,10 @@ public class CronetDataSource extends UrlRequest.Callback implements HttpDataSou
return result.get(); return result.get();
} }
private boolean blockUntilConnectTimeout() { private void log(int priority, String message) {
long now = clock.elapsedRealtime(); if (Log.isLoggable(TAG, priority)) {
boolean opened = false; Log.println(priority, TAG, message);
while (!opened && now < currentConnectTimeoutMs) {
opened = operation.block(currentConnectTimeoutMs - now + 5 /* fudge factor */);
now = clock.elapsedRealtime();
} }
return opened;
}
private void resetConnectTimeout() {
currentConnectTimeoutMs = clock.elapsedRealtime() + connectTimeoutMs;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment