use of com.linkedin.r2.message.stream.entitystream.EntityStream in project rest.li by linkedin.
the class ClientStreamCompressionFilter method onStreamResponse.
/**
* Decompresses server response
*/
@Override
public void onStreamResponse(StreamResponse res, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<StreamRequest, StreamResponse> nextFilter) {
Boolean decompressionOff = (Boolean) requestContext.getLocalAttr(R2Constants.RESPONSE_DECOMPRESSION_OFF);
if (decompressionOff == null || !decompressionOff) {
// Check for header encoding
String compressionHeader = res.getHeader(HttpConstants.CONTENT_ENCODING);
// decompress if necessary
if (compressionHeader != null) {
final StreamEncodingType encoding = StreamEncodingType.get(compressionHeader.trim().toLowerCase());
if (encoding == null) {
nextFilter.onError(new IllegalArgumentException("Server returned unrecognized content encoding: " + compressionHeader), requestContext, wireAttrs);
return;
}
final StreamingCompressor compressor = encoding.getCompressor(_executor);
EntityStream uncompressedStream = compressor.inflate(res.getEntityStream());
StreamResponseBuilder builder = res.builder();
Map<String, String> headers = stripHeaders(builder.getHeaders(), HttpConstants.CONTENT_ENCODING, HttpConstants.CONTENT_LENGTH);
res = builder.setHeaders(headers).build(uncompressedStream);
}
}
nextFilter.onResponse(res, requestContext, wireAttrs);
}
use of com.linkedin.r2.message.stream.entitystream.EntityStream in project rest.li by linkedin.
the class ClientStreamCompressionFilter method onStreamError.
@Override
public void onStreamError(Throwable ex, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<StreamRequest, StreamResponse> nextFilter) {
if (ex instanceof StreamException) {
Boolean decompressionOff = (Boolean) requestContext.getLocalAttr(R2Constants.RESPONSE_DECOMPRESSION_OFF);
if (decompressionOff == null || !decompressionOff) {
StreamException se = (StreamException) ex;
StreamResponse response = se.getResponse();
// Check for header encoding
String compressionHeader = response.getHeader(HttpConstants.CONTENT_ENCODING);
// decompress if necessary
if (compressionHeader != null) {
StreamEncodingType encoding = StreamEncodingType.get(compressionHeader.trim().toLowerCase());
if (encoding != null) {
final StreamingCompressor compressor = encoding.getCompressor(_executor);
EntityStream uncompressedStream = compressor.inflate(response.getEntityStream());
StreamResponseBuilder builder = response.builder();
Map<String, String> headers = stripHeaders(builder.getHeaders(), HttpConstants.CONTENT_ENCODING, HttpConstants.CONTENT_LENGTH);
response = builder.setHeaders(headers).build(uncompressedStream);
ex = new StreamException(response);
}
}
}
}
nextFilter.onError(ex, requestContext, wireAttrs);
}
use of com.linkedin.r2.message.stream.entitystream.EntityStream in project rest.li by linkedin.
the class PartialReader method onDone.
@Override
public void onDone() {
if (_remainingWh == null) {
EntityStream stream = EntityStreams.newEntityStream(new ByteStringsWriter(_buffer));
_callback.onSuccess(new EntityStream[] { stream });
} else {
_remainingWh.done();
}
}
use of com.linkedin.r2.message.stream.entitystream.EntityStream in project rest.li by linkedin.
the class PartialReader method onDataAvailable.
@Override
public void onDataAvailable(ByteString data) {
if (_remainingWh == null) {
_buffer.add(data);
_readLen += data.length();
if (_readLen <= _numBytes) {
_rh.request(1);
} else {
EntityStream stream = EntityStreams.newEntityStream(new ByteStringsWriter(_buffer));
EntityStream remaining = EntityStreams.newEntityStream(new RemainingWriter());
_callback.onSuccess(new EntityStream[] { stream, remaining });
}
} else {
_outstanding--;
_remainingWh.write(data);
int diff = _remainingWh.remaining() - _outstanding;
if (diff > 0) {
_rh.request(diff);
_outstanding += diff;
}
}
}
use of com.linkedin.r2.message.stream.entitystream.EntityStream in project rest.li by linkedin.
the class RAPStreamResponseDecoder method channelRead0.
@Override
protected void channelRead0(final ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpResponse) {
HttpResponse m = (HttpResponse) msg;
_shouldCloseConnection = !HttpUtil.isKeepAlive(m);
if (HttpUtil.is100ContinueExpected(m)) {
ctx.writeAndFlush(CONTINUE).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
ctx.fireExceptionCaught(future.cause());
}
}
});
}
if (!m.decoderResult().isSuccess()) {
ctx.fireExceptionCaught(m.decoderResult().cause());
return;
}
// remove chunked encoding.
if (HttpUtil.isTransferEncodingChunked(m)) {
HttpUtil.setTransferEncodingChunked(m, false);
}
Timeout<None> timeout = ctx.channel().attr(TIMEOUT_ATTR_KEY).getAndSet(null);
if (timeout == null) {
LOG.debug("dropped a response after channel inactive or exception had happened.");
return;
}
final TimeoutBufferedWriter writer = new TimeoutBufferedWriter(ctx, _maxContentLength, BUFFER_HIGH_WATER_MARK, BUFFER_LOW_WATER_MARK, timeout);
EntityStream entityStream = EntityStreams.newEntityStream(writer);
_chunkedMessageWriter = writer;
// Refactored duplicate code to new code pipeline.
StreamResponseBuilder builder = HttpMessageDecoders.ResponseDecoder.buildStreamResponse(m);
ctx.fireChannelRead(builder.build(entityStream));
} else if (msg instanceof HttpContent) {
HttpContent chunk = (HttpContent) msg;
TimeoutBufferedWriter currentWriter = _chunkedMessageWriter;
// Sanity check
if (currentWriter == null) {
throw new IllegalStateException("received " + HttpContent.class.getSimpleName() + " without " + HttpResponse.class.getSimpleName());
}
if (!chunk.decoderResult().isSuccess()) {
this.exceptionCaught(ctx, chunk.decoderResult().cause());
}
currentWriter.processHttpChunk(chunk);
if (chunk instanceof LastHttpContent) {
_chunkedMessageWriter = null;
}
} else {
// something must be wrong, but let's proceed so that
// handler after us has a chance to process it.
ctx.fireChannelRead(msg);
}
}
Aggregations