use of org.chromium.net.UrlResponseInfo in project grpc-java by grpc.
the class CronetClientStreamTest method streamFailedAfterResponseHeaderReceived.
@Test
public void streamFailedAfterResponseHeaderReceived() {
ArgumentCaptor<BidirectionalStream.Callback> callbackCaptor = ArgumentCaptor.forClass(BidirectionalStream.Callback.class);
verify(factory).newBidirectionalStreamBuilder(isA(String.class), callbackCaptor.capture(), isA(Executor.class));
BidirectionalStream.Callback callback = callbackCaptor.getValue();
// Receive response header
UrlResponseInfo info = new UrlResponseInfoImpl(new ArrayList<>(), 200, "", responseHeader("200"), false, "", "", 0);
callback.onResponseHeadersReceived(cronetStream, info);
CronetException exception = mock(CronetException.class);
callback.onFailed(cronetStream, info, exception);
verify(transport).finishStream(eq(clientStream), isA(Status.class));
// finishStream calls transportReportStatus.
clientStream.transportState().transportReportStatus(Status.UNAVAILABLE, false, new Metadata());
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
verify(clientListener).closed(statusCaptor.capture(), isA(RpcProgress.class), isA(Metadata.class));
Status status = statusCaptor.getValue();
assertEquals(Status.UNAVAILABLE.getCode(), status.getCode());
}
use of org.chromium.net.UrlResponseInfo in project grpc-java by grpc.
the class CronetClientStreamTest method reportTrailersWhenTrailersReceivedAfterReadClosed.
@Test
public void reportTrailersWhenTrailersReceivedAfterReadClosed() {
ArgumentCaptor<BidirectionalStream.Callback> callbackCaptor = ArgumentCaptor.forClass(BidirectionalStream.Callback.class);
verify(factory).newBidirectionalStreamBuilder(isA(String.class), callbackCaptor.capture(), isA(Executor.class));
BidirectionalStream.Callback callback = callbackCaptor.getValue();
callback.onStreamReady(cronetStream);
UrlResponseInfo info = new UrlResponseInfoImpl(new ArrayList<>(), 200, "", responseHeader("200"), false, "", "", 0);
callback.onResponseHeadersReceived(cronetStream, info);
// Receive cronet's endOfStream
callback.onReadCompleted(cronetStream, null, ByteBuffer.allocate(0), true);
verify(clientListener, times(0)).closed(isA(Status.class), isA(RpcProgress.class), isA(Metadata.class));
// Receive trailer
((CronetClientStream.BidirectionalStreamCallback) callback).processTrailers(trailers(Status.UNAUTHENTICATED.getCode().value()));
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
verify(clientListener, times(1)).closed(statusCaptor.capture(), isA(RpcProgress.class), isA(Metadata.class));
Status status = statusCaptor.getValue();
assertEquals(Status.UNAUTHENTICATED.getCode(), status.getCode());
}
use of org.chromium.net.UrlResponseInfo in project grpc-java by grpc.
the class CronetClientStreamTest method streamFailedAfterTrailerAndEndOfStreamReceived.
@Test
public void streamFailedAfterTrailerAndEndOfStreamReceived() {
ArgumentCaptor<BidirectionalStream.Callback> callbackCaptor = ArgumentCaptor.forClass(BidirectionalStream.Callback.class);
verify(factory).newBidirectionalStreamBuilder(isA(String.class), callbackCaptor.capture(), isA(Executor.class));
BidirectionalStream.Callback callback = callbackCaptor.getValue();
// Receive response header
UrlResponseInfo info = new UrlResponseInfoImpl(new ArrayList<>(), 200, "", responseHeader("200"), false, "", "", 0);
callback.onResponseHeadersReceived(cronetStream, info);
// Report trailer and endOfStream
callback.onReadCompleted(cronetStream, null, ByteBuffer.allocate(0), true);
((CronetClientStream.BidirectionalStreamCallback) callback).processTrailers(trailers(0));
CronetException exception = mock(CronetException.class);
callback.onFailed(cronetStream, info, exception);
verify(transport).finishStream(eq(clientStream), isA(Status.class));
// finishStream calls transportReportStatus.
clientStream.transportState().transportReportStatus(Status.UNAVAILABLE, false, new Metadata());
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
verify(clientListener).closed(statusCaptor.capture(), isA(RpcProgress.class), isA(Metadata.class));
Status status = statusCaptor.getValue();
// Stream has already finished so OK status should be reported.
assertEquals(Status.OK.getCode(), status.getCode());
}
use of org.chromium.net.UrlResponseInfo in project ExoPlayer by google.
the class CronetDataSource method open.
@Override
public long open(DataSpec dataSpec) throws HttpDataSourceException {
Assertions.checkNotNull(dataSpec);
Assertions.checkState(!opened);
operation.close();
resetConnectTimeout();
currentDataSpec = dataSpec;
UrlRequest urlRequest;
try {
urlRequest = buildRequestBuilder(dataSpec).build();
currentUrlRequest = urlRequest;
} catch (IOException e) {
if (e instanceof HttpDataSourceException) {
throw (HttpDataSourceException) e;
} else {
throw new OpenException(e, dataSpec, PlaybackException.ERROR_CODE_IO_UNSPECIFIED, Status.IDLE);
}
}
urlRequest.start();
transferInitializing(dataSpec);
try {
boolean connectionOpened = blockUntilConnectTimeout();
@Nullable IOException connectionOpenException = exception;
if (connectionOpenException != null) {
@Nullable String message = connectionOpenException.getMessage();
if (message != null && Ascii.toLowerCase(message).contains("err_cleartext_not_permitted")) {
throw new CleartextNotPermittedException(connectionOpenException, dataSpec);
}
throw new OpenException(connectionOpenException, dataSpec, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED, getStatus(urlRequest));
} else if (!connectionOpened) {
// The timeout was reached before the connection was opened.
throw new OpenException(new SocketTimeoutException(), dataSpec, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT, getStatus(urlRequest));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// is failing to swallow the interruption, which makes us enter an invalid state.
throw new OpenException(new InterruptedIOException(), dataSpec, PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK, Status.INVALID);
}
// Check for a valid response code.
UrlResponseInfo responseInfo = Assertions.checkNotNull(this.responseInfo);
int responseCode = responseInfo.getHttpStatusCode();
Map<String, List<String>> responseHeaders = responseInfo.getAllHeaders();
if (responseCode < 200 || responseCode > 299) {
if (responseCode == 416) {
long documentSize = HttpUtil.getDocumentSize(getFirstHeader(responseHeaders, HttpHeaders.CONTENT_RANGE));
if (dataSpec.position == documentSize) {
opened = true;
transferStarted(dataSpec);
return dataSpec.length != C.LENGTH_UNSET ? dataSpec.length : 0;
}
}
byte[] responseBody;
try {
responseBody = readResponseBody();
} catch (IOException e) {
responseBody = Util.EMPTY_BYTE_ARRAY;
}
@Nullable IOException cause = responseCode == 416 ? new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE) : null;
throw new InvalidResponseCodeException(responseCode, responseInfo.getHttpStatusText(), cause, responseHeaders, dataSpec, responseBody);
}
// Check for a valid content type.
Predicate<String> contentTypePredicate = this.contentTypePredicate;
if (contentTypePredicate != null) {
@Nullable String contentType = getFirstHeader(responseHeaders, HttpHeaders.CONTENT_TYPE);
if (contentType != null && !contentTypePredicate.apply(contentType)) {
throw new InvalidContentTypeException(contentType, dataSpec);
}
}
// If we requested a range starting from a non-zero position and received a 200 rather than a
// 206, then the server does not support partial requests. We'll need to manually skip to the
// requested position.
long bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0;
// Calculate the content length.
if (!isCompressed(responseInfo)) {
if (dataSpec.length != C.LENGTH_UNSET) {
bytesRemaining = dataSpec.length;
} else {
long contentLength = HttpUtil.getContentLength(getFirstHeader(responseHeaders, HttpHeaders.CONTENT_LENGTH), getFirstHeader(responseHeaders, HttpHeaders.CONTENT_RANGE));
bytesRemaining = contentLength != C.LENGTH_UNSET ? (contentLength - bytesToSkip) : C.LENGTH_UNSET;
}
} else {
// If the response is compressed then the content length will be that of the compressed data
// which isn't what we want. Always use the dataSpec length in this case.
bytesRemaining = dataSpec.length;
}
opened = true;
transferStarted(dataSpec);
skipFully(bytesToSkip, dataSpec);
return bytesRemaining;
}
use of org.chromium.net.UrlResponseInfo in project grpc-java by grpc.
the class CronetClientStreamTest method streamFailedAfterTrailerReceived.
@Test
public void streamFailedAfterTrailerReceived() {
ArgumentCaptor<BidirectionalStream.Callback> callbackCaptor = ArgumentCaptor.forClass(BidirectionalStream.Callback.class);
verify(factory).newBidirectionalStreamBuilder(isA(String.class), callbackCaptor.capture(), isA(Executor.class));
BidirectionalStream.Callback callback = callbackCaptor.getValue();
// Receive response header
UrlResponseInfo info = new UrlResponseInfoImpl(new ArrayList<>(), 200, "", responseHeader("200"), false, "", "", 0);
callback.onResponseHeadersReceived(cronetStream, info);
// Report trailer but not endOfStream.
((CronetClientStream.BidirectionalStreamCallback) callback).processTrailers(trailers(0));
CronetException exception = mock(CronetException.class);
callback.onFailed(cronetStream, info, exception);
verify(transport).finishStream(eq(clientStream), isA(Status.class));
// finishStream calls transportReportStatus.
clientStream.transportState().transportReportStatus(Status.UNAVAILABLE, false, new Metadata());
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
verify(clientListener).closed(statusCaptor.capture(), isA(RpcProgress.class), isA(Metadata.class));
Status status = statusCaptor.getValue();
// Stream has already finished so OK status should be reported.
assertEquals(Status.UNAVAILABLE.getCode(), status.getCode());
}
Aggregations