List of usage examples for io.netty.util ReferenceCountUtil retain
@SuppressWarnings("unchecked") public static <T> T retain(T msg)
From source file:cc.agentx.client.net.nio.XConnectHandler.java
License:Apache License
@Override public void channelRead0(final ChannelHandlerContext ctx, final SocksCmdRequest request) throws Exception { boolean proxyMode = isAgentXNeeded(request.host()); log.info("\tClient -> Proxy \tTarget {}:{} [{}]", request.host(), request.port(), proxyMode ? "AGENTX" : "DIRECT"); Promise<Channel> promise = ctx.executor().newPromise(); promise.addListener(new FutureListener<Channel>() { @Override/* w w w. j av a2s . c om*/ public void operationComplete(final Future<Channel> future) throws Exception { final Channel outboundChannel = future.getNow(); if (future.isSuccess()) { ctx.channel().writeAndFlush(new SocksCmdResponse(SocksCmdStatus.SUCCESS, request.addressType())) .addListener(channelFuture -> { ByteBuf byteBuf = Unpooled.buffer(); request.encodeAsByteBuf(byteBuf); if (byteBuf.hasArray()) { byte[] xRequestBytes = new byte[byteBuf.readableBytes()]; byteBuf.getBytes(0, xRequestBytes); if (proxyMode) { // handshaking to remote proxy xRequestBytes = requestWrapper.wrap(xRequestBytes); outboundChannel.writeAndFlush(Unpooled.wrappedBuffer( exposeRequest ? xRequestBytes : wrapper.wrap(xRequestBytes))); } // task handover ReferenceCountUtil.retain(request); // auto-release? a trap? ctx.pipeline().remove(XConnectHandler.this); outboundChannel.pipeline().addLast(new XRelayHandler(ctx.channel(), proxyMode ? wrapper : rawWrapper, false)); ctx.pipeline().addLast(new XRelayHandler(outboundChannel, proxyMode ? wrapper : rawWrapper, true)); } }); } else { ctx.channel() .writeAndFlush(new SocksCmdResponse(SocksCmdStatus.FAILURE, request.addressType())); if (ctx.channel().isActive()) { ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } } }); String host = request.host(); int port = request.port(); if (host.equals(config.getConsoleDomain())) { host = "localhost"; port = config.getConsolePort(); } else if (proxyMode) { host = config.getServerHost(); port = config.getServerPort(); } // ping target bootstrap.group(ctx.channel().eventLoop()).channel(NioSocketChannel.class) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000).option(ChannelOption.SO_KEEPALIVE, true) .handler(new XPingHandler(promise, System.currentTimeMillis())).connect(host, port) .addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { ctx.channel().writeAndFlush( new SocksCmdResponse(SocksCmdStatus.FAILURE, request.addressType())); if (ctx.channel().isActive()) { ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } } }); }
From source file:com.bloom.zerofs.rest.NettyMultipartRequest.java
License:Open Source License
/** * Adds content that will be decoded on a call to {@link #prepare()}. * </p>/*ww w . j a v a 2s.c om*/ * All content has to be added before {@link #prepare()} can be called. * @param httpContent the {@link HttpContent} that needs to be added. * @throws RestServiceException if request channel has been closed. */ @Override public void addContent(HttpContent httpContent) throws RestServiceException { if (!isOpen()) { nettyMetrics.multipartRequestAlreadyClosedError.inc(); throw new RestServiceException("The request has been closed and is not accepting content", RestServiceErrorCode.RequestChannelClosed); } else { rawRequestContents.add(ReferenceCountUtil.retain(httpContent)); } }
From source file:com.bloom.zerofs.rest.NettyMultipartRequest.java
License:Open Source License
/** * Processes a single decoded part in a multipart request. Exposes the data in the part either through the channel * itself (if it is the blob part) or via {@link #getArgs()}. * @param part the {@link InterfaceHttpData} that needs to be processed. * @throws RestServiceException if the request channel is closed, if there is more than one part of the same name, if * the size obtained from the headers does not match the actual size of the blob part or * if {@code part} is not of the expected type ({@link FileUpload}). *//*from w w w. j ava 2 s .c o m*/ private void processPart(InterfaceHttpData part) throws RestServiceException { if (part.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) { FileUpload fileUpload = (FileUpload) part; if (fileUpload.getName().equals(RestUtils.MultipartPost.BLOB_PART)) { // this is actual data. if (hasBlob) { nettyMetrics.repeatedPartsError.inc(); throw new RestServiceException("Request has more than one " + RestUtils.MultipartPost.BLOB_PART, RestServiceErrorCode.BadRequest); } else { hasBlob = true; if (fileUpload.length() != getSize()) { nettyMetrics.multipartRequestSizeMismatchError.inc(); throw new RestServiceException("Request size [" + fileUpload.length() + "] does not match Content-Length [" + getSize() + "]", RestServiceErrorCode.BadRequest); } else { contentLock.lock(); try { if (isOpen()) { requestContents.add( new DefaultHttpContent(ReferenceCountUtil.retain(fileUpload.content()))); } else { nettyMetrics.multipartRequestAlreadyClosedError.inc(); throw new RestServiceException("Request is closed", RestServiceErrorCode.RequestChannelClosed); } } finally { contentLock.unlock(); } } } } else { // this is any kind of data. (For Amber, this will be user metadata). // TODO: find a configurable way of rejecting unexpected file parts. String name = fileUpload.getName(); if (allArgs.containsKey(name)) { nettyMetrics.repeatedPartsError.inc(); throw new RestServiceException("Request already has a component named " + name, RestServiceErrorCode.BadRequest); } else { ByteBuffer buffer = ByteBuffer.allocate(fileUpload.content().readableBytes()); // TODO: Possible optimization - Upgrade ByteBufferReadableStreamChannel to take a list of ByteBuffer. This // TODO: will avoid the copy. fileUpload.content().readBytes(buffer); buffer.flip(); allArgs.put(name, buffer); } } } else { nettyMetrics.unsupportedPartError.inc(); throw new RestServiceException("Unexpected HTTP data", RestServiceErrorCode.BadRequest); } }
From source file:com.bloom.zerofs.rest.NettyRequest.java
License:Open Source License
/** * Adds some content in the form of {@link HttpContent} to this RestRequest. This content will be available to read * through the read operations./* w w w . ja v a 2 s . c om*/ * @param httpContent the {@link HttpContent} that needs to be added. * @throws IllegalStateException if content is being added when it is not expected (GET, DELETE, HEAD). * @throws RestServiceException if request channel has been closed. */ protected void addContent(HttpContent httpContent) throws RestServiceException { if (!getRestMethod().equals(RestMethod.POST) && (!(httpContent instanceof LastHttpContent) || httpContent.content().readableBytes() > 0)) { throw new IllegalStateException("There is no content expected for " + getRestMethod()); } else { validateState(httpContent); contentLock.lock(); try { if (!isOpen()) { nettyMetrics.requestAlreadyClosedError.inc(); throw new RestServiceException("The request has been closed and is not accepting content", RestServiceErrorCode.RequestChannelClosed); } else if (writeChannel != null) { writeContent(writeChannel, callbackWrapper, httpContent); } else { requestContents.add(ReferenceCountUtil.retain(httpContent)); } } finally { contentLock.unlock(); } } }
From source file:com.bloom.zerofs.rest.NettyRequest.java
License:Open Source License
/** * Writes the data in the provided {@code httpContent} to the given {@code writeChannel}. * @param writeChannel the {@link AsyncWritableChannel} to write the data of {@code httpContent} to. * @param callbackWrapper the {@link ReadIntoCallbackWrapper} for the read operation. * @param httpContent the piece of {@link HttpContent} that needs to be written to the {@code writeChannel}. *//*from w ww . j av a 2 s .c o m*/ protected void writeContent(AsyncWritableChannel writeChannel, ReadIntoCallbackWrapper callbackWrapper, HttpContent httpContent) { boolean retained = false; ByteBuffer[] contentBuffers; Callback<Long>[] writeCallbacks; // LastHttpContent in the end marker in netty http world. boolean isLast = httpContent instanceof LastHttpContent; if (httpContent.content().nioBufferCount() > 0) { // not a copy. httpContent = ReferenceCountUtil.retain(httpContent); retained = true; contentBuffers = httpContent.content().nioBuffers(); writeCallbacks = new ContentWriteCallback[contentBuffers.length]; int i = 0; for (; i < contentBuffers.length - 1; i++) { writeCallbacks[i] = new ContentWriteCallback(null, false, callbackWrapper); } writeCallbacks[i] = new ContentWriteCallback(httpContent, isLast, callbackWrapper); } else { // this will not happen (looking at current implementations of ByteBuf in Netty), but if it does, we cannot avoid // a copy (or we can introduce a read(GatheringByteChannel) method in ReadableStreamChannel if required). nettyMetrics.contentCopyCount.inc(); logger.warn("HttpContent had to be copied because ByteBuf did not have a backing ByteBuffer"); ByteBuffer contentBuffer = ByteBuffer.allocate(httpContent.content().readableBytes()); httpContent.content().readBytes(contentBuffer); // no need to retain httpContent since we have a copy. ContentWriteCallback writeCallback = new ContentWriteCallback(null, isLast, callbackWrapper); contentBuffers = new ByteBuffer[] { contentBuffer }; writeCallbacks = new ContentWriteCallback[] { writeCallback }; } boolean asyncWritesCalled = false; try { for (int i = 0; i < contentBuffers.length; i++) { if (digest != null) { long startTime = System.currentTimeMillis(); int savedPosition = contentBuffers[i].position(); digest.update(contentBuffers[i]); contentBuffers[i].position(savedPosition); digestCalculationTimeInMs += (System.currentTimeMillis() - startTime); } writeChannel.write(contentBuffers[i], writeCallbacks[i]); } asyncWritesCalled = true; } finally { if (retained && !asyncWritesCalled) { ReferenceCountUtil.release(httpContent); } } allContentReceived = isLast; }
From source file:com.caricah.iotracah.server.netty.channelgroup.IotChannelGroup.java
License:Apache License
private static Object safeDuplicate(Object message) { if (message instanceof ByteBuf) { return ((ByteBuf) message).duplicate().retain(); } else if (message instanceof ByteBufHolder) { return ((ByteBufHolder) message).duplicate().retain(); } else {/* w ww . j av a2 s . c om*/ return ReferenceCountUtil.retain(message); } }
From source file:com.flysoloing.learning.network.netty.http2.helloworld.multiplex.server.Http2ServerInitializer.java
License:Apache License
/** * Configure the pipeline for a cleartext upgrade from HTTP to HTTP/2.0 *///w w w . ja va 2s . co m private void configureClearText(SocketChannel ch) { final ChannelPipeline p = ch.pipeline(); final HttpServerCodec sourceCodec = new HttpServerCodec(); p.addLast(sourceCodec); p.addLast(new HttpServerUpgradeHandler(sourceCodec, upgradeCodecFactory)); p.addLast(new SimpleChannelInboundHandler<HttpMessage>() { @Override protected void channelRead0(ChannelHandlerContext ctx, HttpMessage msg) throws Exception { // If this handler is hit then no upgrade has been attempted and the client is just talking HTTP. System.err.println("Directly talking: " + msg.protocolVersion() + " (no upgrade was attempted)"); ChannelPipeline pipeline = ctx.pipeline(); ChannelHandlerContext thisCtx = pipeline.context(this); pipeline.addAfter(thisCtx.name(), null, new HelloWorldHttp1Handler("Direct. No Upgrade Attempted.")); pipeline.replace(this, null, new HttpObjectAggregator(maxHttpContentLength)); ctx.fireChannelRead(ReferenceCountUtil.retain(msg)); } }); p.addLast(new UserEventLogger()); }
From source file:com.github.ambry.rest.NettyMessageProcessorTest.java
License:Open Source License
/** * Tests the case where raw bytes are POSTed as chunks. * @throws InterruptedException/* w ww . j a v a 2 s . c o m*/ */ @Test public void rawBytesPostTest() throws InterruptedException { Random random = new Random(); // request also contains content. ByteBuffer content = ByteBuffer.wrap(RestTestUtils.getRandomBytes(random.nextInt(128) + 128)); HttpRequest postRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/", Unpooled.wrappedBuffer(content)); HttpHeaders.setHeader(postRequest, RestUtils.Headers.SERVICE_ID, "rawBytesPostTest"); HttpHeaders.setHeader(postRequest, RestUtils.Headers.BLOB_SIZE, content.remaining()); postRequest = ReferenceCountUtil.retain(postRequest); ByteBuffer receivedContent = doPostTest(postRequest, null); compareContent(receivedContent, Collections.singletonList(content)); // request and content separate. final int NUM_CONTENTS = 5; postRequest = RestTestUtils.createRequest(HttpMethod.POST, "/", null); List<ByteBuffer> contents = new ArrayList<ByteBuffer>(NUM_CONTENTS); int blobSize = 0; for (int i = 0; i < NUM_CONTENTS; i++) { ByteBuffer buffer = ByteBuffer.wrap(RestTestUtils.getRandomBytes(random.nextInt(128) + 128)); blobSize += buffer.remaining(); contents.add(i, buffer); } HttpHeaders.setHeader(postRequest, RestUtils.Headers.SERVICE_ID, "rawBytesPostTest"); HttpHeaders.setHeader(postRequest, RestUtils.Headers.BLOB_SIZE, blobSize); receivedContent = doPostTest(postRequest, contents); compareContent(receivedContent, contents); }
From source file:com.github.ambry.rest.NettyMultipartRequest.java
License:Open Source License
/** * Processes a single decoded part in a multipart request. Exposes the data in the part either through the channel * itself (if it is the blob part) or via {@link #getArgs()}. * @param part the {@link InterfaceHttpData} that needs to be processed. * @throws RestServiceException if the request channel is closed, if there is more than one part of the same name, if * the size obtained from the headers does not match the actual size of the blob part or * if {@code part} is not of the expected type ({@link FileUpload}). *///from ww w. j av a2 s . c o m private void processPart(InterfaceHttpData part) throws RestServiceException { if (part.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) { FileUpload fileUpload = (FileUpload) part; if (fileUpload.getName().equals(RestUtils.MultipartPost.BLOB_PART)) { // this is actual data. if (hasBlob) { nettyMetrics.repeatedPartsError.inc(); throw new RestServiceException("Request has more than one " + RestUtils.MultipartPost.BLOB_PART, RestServiceErrorCode.BadRequest); } else { hasBlob = true; if (fileUpload.length() != getSize()) { nettyMetrics.multipartRequestSizeMismatchError.inc(); throw new RestServiceException("Request size [" + fileUpload.length() + "] does not match Content-Length [" + getSize() + "]", RestServiceErrorCode.BadRequest); } else { contentLock.lock(); try { if (isOpen()) { requestContents.add( new DefaultHttpContent(ReferenceCountUtil.retain(fileUpload.content()))); } else { nettyMetrics.multipartRequestAlreadyClosedError.inc(); throw new RestServiceException("Request is closed", RestServiceErrorCode.RequestChannelClosed); } } finally { contentLock.unlock(); } } } } else { // this is any kind of data. (For ambry, this will be user metadata). // TODO: find a configurable way of rejecting unexpected file parts. String name = fileUpload.getName(); if (allArgs.containsKey(name)) { nettyMetrics.repeatedPartsError.inc(); throw new RestServiceException("Request already has a component named " + name, RestServiceErrorCode.BadRequest); } else { ByteBuffer buffer = ByteBuffer.allocate(fileUpload.content().readableBytes()); // TODO: Possible optimization - Upgrade ByteBufferReadableStreamChannel to take a list of ByteBuffer. This // TODO: will avoid the copy. fileUpload.content().readBytes(buffer); buffer.flip(); allArgs.put(name, buffer); } } } else { nettyMetrics.unsupportedPartError.inc(); throw new RestServiceException("Unexpected HTTP data", RestServiceErrorCode.BadRequest); } }
From source file:com.github.ambry.rest.NettyRequest.java
License:Open Source License
/** * Writes the data in the provided {@code httpContent} to the given {@code writeChannel}. * @param writeChannel the {@link AsyncWritableChannel} to write the data of {@code httpContent} to. * @param callbackWrapper the {@link ReadIntoCallbackWrapper} for the read operation. * @param httpContent the piece of {@link HttpContent} that needs to be written to the {@code writeChannel}. *///from w ww .java 2 s . c om protected void writeContent(AsyncWritableChannel writeChannel, ReadIntoCallbackWrapper callbackWrapper, HttpContent httpContent) { boolean retained = false; ByteBuffer[] contentBuffers; Callback<Long>[] writeCallbacks; // LastHttpContent in the end marker in netty http world. boolean isLast = httpContent instanceof LastHttpContent; if (httpContent.content().nioBufferCount() > 0) { // not a copy. httpContent = ReferenceCountUtil.retain(httpContent); retained = true; contentBuffers = httpContent.content().nioBuffers(); writeCallbacks = new ContentWriteCallback[contentBuffers.length]; int i = 0; for (; i < contentBuffers.length - 1; i++) { writeCallbacks[i] = new ContentWriteCallback(null, false, callbackWrapper); } writeCallbacks[i] = new ContentWriteCallback(httpContent, isLast, callbackWrapper); } else { // this will not happen (looking at current implementations of ByteBuf in Netty), but if it does, we cannot avoid // a copy (or we can introduce a read(GatheringByteChannel) method in ReadableStreamChannel if required). nettyMetrics.contentCopyCount.inc(); logger.warn("HttpContent had to be copied because ByteBuf did not have a backing ByteBuffer"); ByteBuffer contentBuffer = ByteBuffer.allocate(httpContent.content().readableBytes()); httpContent.content().readBytes(contentBuffer); // no need to retain httpContent since we have a copy. ContentWriteCallback writeCallback = new ContentWriteCallback(null, isLast, callbackWrapper); contentBuffers = new ByteBuffer[] { contentBuffer }; writeCallbacks = new ContentWriteCallback[] { writeCallback }; } boolean asyncWritesCalled = false; try { for (int i = 0; i < contentBuffers.length; i++) { writeChannel.write(contentBuffers[i], writeCallbacks[i]); } asyncWritesCalled = true; } finally { if (retained && !asyncWritesCalled) { ReferenceCountUtil.release(httpContent); } } }