Example usage for io.netty.buffer ByteBuf retain

List of usage examples for io.netty.buffer ByteBuf retain

Introduction

In this page you can find the example usage for io.netty.buffer ByteBuf retain.

Prototype

@Override
    public abstract ByteBuf retain();

Source Link

Usage

From source file:com.kixeye.kixmpp.p2p.serialization.ProtostuffEncoder.java

License:Apache License

@Override
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
    if (msg instanceof ByteBuf) {
        // already serialized so just pass through
        ByteBuf buf = (ByteBuf) msg;
        out.add(buf.retain());
    } else {/*  w  w w .j a  va  2 s.c  o m*/
        // serialize
        ByteBuf buf = ctx.alloc().buffer();
        serializeToByteBuf(registry, buf, msg);
        out.add(buf);
    }
}

From source file:com.l2jmobius.commons.network.codecs.LengthFieldBasedFrameEncoder.java

License:Open Source License

@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) {
    final ByteBuf buf = ctx.alloc().buffer(2);
    final short length = (short) (msg.readableBytes() + 2);
    buf.writeShort(buf.order() != ByteOrder.LITTLE_ENDIAN ? Short.reverseBytes(length) : length);
    out.add(buf);// w  ww  .  j a va 2 s .com
    out.add(msg.retain());
}

From source file:com.linecorp.armeria.server.Http1RequestDecoder.java

License:Apache License

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    if (!(msg instanceof HttpObject)) {
        ctx.fireChannelRead(msg);/*from w w w  .  ja  va  2 s. com*/
        return;
    }

    // this.req can be set to null by fail(), so we keep it in a local variable.
    DecodedHttpRequest req = this.req;
    try {
        if (discarding) {
            return;
        }

        if (req == null) {
            if (msg instanceof HttpRequest) {
                final HttpRequest nettyReq = (HttpRequest) msg;
                if (!nettyReq.decoderResult().isSuccess()) {
                    fail(ctx, HttpResponseStatus.BAD_REQUEST);
                    return;
                }

                final HttpHeaders nettyHeaders = nettyReq.headers();
                final int id = ++receivedRequests;

                // Validate the method.
                if (!HttpMethod.isSupported(nettyReq.method().name())) {
                    fail(ctx, HttpResponseStatus.METHOD_NOT_ALLOWED);
                    return;
                }

                // Validate the 'content-length' header.
                final String contentLengthStr = nettyHeaders.get(HttpHeaderNames.CONTENT_LENGTH);
                final boolean contentEmpty;
                if (contentLengthStr != null) {
                    final long contentLength;
                    try {
                        contentLength = Long.parseLong(contentLengthStr);
                    } catch (NumberFormatException ignored) {
                        fail(ctx, HttpResponseStatus.BAD_REQUEST);
                        return;
                    }
                    if (contentLength < 0) {
                        fail(ctx, HttpResponseStatus.BAD_REQUEST);
                        return;
                    }

                    contentEmpty = contentLength == 0;
                } else {
                    contentEmpty = true;
                }

                nettyHeaders.set(ExtensionHeaderNames.SCHEME.text(), scheme);

                this.req = req = new DecodedHttpRequest(ctx.channel().eventLoop(), id, 1,
                        ArmeriaHttpUtil.toArmeria(nettyReq), HttpUtil.isKeepAlive(nettyReq),
                        inboundTrafficController, cfg.defaultMaxRequestLength());

                // Close the request early when it is sure that there will be
                // neither content nor trailing headers.
                if (contentEmpty && !HttpUtil.isTransferEncodingChunked(nettyReq)) {
                    req.close();
                }

                ctx.fireChannelRead(req);
            } else {
                fail(ctx, HttpResponseStatus.BAD_REQUEST);
                return;
            }
        }

        if (req != null && msg instanceof HttpContent) {
            final HttpContent content = (HttpContent) msg;
            final DecoderResult decoderResult = content.decoderResult();
            if (!decoderResult.isSuccess()) {
                fail(ctx, HttpResponseStatus.BAD_REQUEST);
                req.close(new ProtocolViolationException(decoderResult.cause()));
                return;
            }

            final ByteBuf data = content.content();
            final int dataLength = data.readableBytes();
            if (dataLength != 0) {
                req.increaseTransferredBytes(dataLength);
                final long maxContentLength = req.maxRequestLength();
                if (maxContentLength > 0 && req.transferredBytes() > maxContentLength) {
                    fail(ctx, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
                    req.close(ContentTooLargeException.get());
                    return;
                }

                if (req.isOpen()) {
                    req.write(new ByteBufHttpData(data.retain(), false));
                }
            }

            if (msg instanceof LastHttpContent) {
                final HttpHeaders trailingHeaders = ((LastHttpContent) msg).trailingHeaders();
                if (!trailingHeaders.isEmpty()) {
                    req.write(ArmeriaHttpUtil.toArmeria(trailingHeaders));
                }

                req.close();
                this.req = req = null;
            }
        }
    } catch (URISyntaxException e) {
        fail(ctx, HttpResponseStatus.BAD_REQUEST);
        if (req != null) {
            req.close(e);
        }
    } catch (Throwable t) {
        fail(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR);
        if (req != null) {
            req.close(t);
        } else {
            logger.warn("Unexpected exception:", t);
        }
    } finally {
        ReferenceCountUtil.release(msg);
    }
}

From source file:com.linecorp.armeria.server.Http2RequestDecoder.java

License:Apache License

@Override
public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream)
        throws Http2Exception {

    final DecodedHttpRequest req = requests.get(streamId);
    if (req == null) {
        throw connectionError(PROTOCOL_ERROR, "received a DATA Frame for an unknown stream: %d", streamId);
    }// w  ww. j a v a  2s  .  co  m

    final int dataLength = data.readableBytes();
    if (dataLength == 0) {
        // Received an empty DATA frame
        if (endOfStream) {
            req.close();
        }
        return padding;
    }

    req.increaseTransferredBytes(dataLength);

    final long maxContentLength = req.maxRequestLength();
    if (maxContentLength > 0 && req.transferredBytes() > maxContentLength) {
        if (req.isOpen()) {
            req.close(ContentTooLargeException.get());
        }

        if (isWritable(streamId)) {
            writeErrorResponse(ctx, streamId, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
        } else {
            // Cannot write to the stream. Just close it.
            final Http2Stream stream = writer.connection().stream(streamId);
            stream.close();
        }
    } else if (req.isOpen()) {
        try {
            req.write(new ByteBufHttpData(data.retain(), endOfStream));
        } catch (Throwable t) {
            req.close(t);
            throw connectionError(INTERNAL_ERROR, t, "failed to consume a DATA frame");
        }

        if (endOfStream) {
            req.close();
        }
    }

    // All bytes have been processed.
    return dataLength + padding;
}

From source file:com.mastfrog.acteur.server.HttpObjectAggregator.java

License:Open Source License

@Override
protected void decode(final ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception {
    FullHttpMessage currentMessage = this.currentMessage;

    if (msg instanceof HttpMessage) {
        tooLongFrameFound = false;//from  w  w  w . j av a2 s . c om
        assert currentMessage == null;

        HttpMessage m = (HttpMessage) msg;

        // Handle the 'Expect: 100-continue' header if necessary.
        // TODO: Respond with 413 Request Entity Too Large
        //   and discard the traffic or close the connection.
        //       No need to notify the upstream handlers - just log.
        //       If decoding a response, just throw an exception.
        if (is100ContinueExpected(m)) {
            ByteBuf buf = CONTINUE_LINE.duplicate();
            buf.retain();
            ctx.writeAndFlush(buf).addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        ctx.fireExceptionCaught(future.cause());
                    }
                }
            });
        }

        if (!m.getDecoderResult().isSuccess()) {
            removeTransferEncodingChunked(m);
            out.add(toFullMessage(m));
            this.currentMessage = null;
            return;
        }
        if (msg instanceof HttpRequest) {
            HttpRequest header = (HttpRequest) msg;
            this.currentMessage = currentMessage = new DefaultFullHttpRequest(header.getProtocolVersion(),
                    header.getMethod(), header.getUri(),
                    Unpooled.compositeBuffer(maxCumulationBufferComponents));
        } else if (msg instanceof HttpResponse) {
            HttpResponse header = (HttpResponse) msg;
            this.currentMessage = currentMessage = new DefaultFullHttpResponse(header.getProtocolVersion(),
                    header.getStatus(), Unpooled.compositeBuffer(maxCumulationBufferComponents));
        } else {
            throw new Error();
        }

        currentMessage.headers().set(m.headers());

        // A streamed message - initialize the cumulative buffer, and wait for incoming chunks.
        removeTransferEncodingChunked(currentMessage);
    } else if (msg instanceof HttpContent) {
        if (tooLongFrameFound) {
            if (msg instanceof LastHttpContent) {
                this.currentMessage = null;
            }
            // already detect the too long frame so just discard the content
            return;
        }
        assert currentMessage != null;

        // Merge the received chunk into the content of the current message.
        HttpContent chunk = (HttpContent) msg;
        CompositeByteBuf content = (CompositeByteBuf) currentMessage.content();

        if (content.readableBytes() > maxContentLength - chunk.content().readableBytes()) {
            tooLongFrameFound = true;

            // release current message to prevent leaks
            currentMessage.release();
            this.currentMessage = null;

            throw new TooLongFrameException("HTTP content length exceeded " + maxContentLength + " bytes.");
        }

        // Append the content of the chunk
        if (chunk.content().isReadable()) {
            chunk.retain();
            content.addComponent(chunk.content());
            content.writerIndex(content.writerIndex() + chunk.content().readableBytes());
        }

        final boolean last;
        if (!chunk.getDecoderResult().isSuccess()) {
            currentMessage.setDecoderResult(DecoderResult.failure(chunk.getDecoderResult().cause()));
            last = true;
        } else {
            last = chunk instanceof LastHttpContent;
        }

        if (last) {
            this.currentMessage = null;

            // Merge trailing headers into the message.
            if (chunk instanceof LastHttpContent) {
                LastHttpContent trailer = (LastHttpContent) chunk;
                currentMessage.headers().add(trailer.trailingHeaders());
            }

            // Set the 'Content-Length' header.
            currentMessage.headers().set(HttpHeaders.Names.CONTENT_LENGTH,
                    String.valueOf(content.readableBytes()));

            // All done
            out.add(currentMessage);
        }
    } else {
        throw new Error();
    }
}

From source file:com.mastfrog.tinymavenproxy.FileFinder.java

License:Open Source License

public synchronized void put(final Path path, final ByteBuf content, final DateTime lastModified) {
    // This method is currently unused, but if we enhance the server to accept
    // uploads, we will likely need code a lot like this
    if (content.readableBytes() == 0) {
        return;/*from   w  ww  . j  a  v  a 2  s . c o  m*/
    }
    final ByteBuf buf = content.duplicate();
    threadPool.submit(new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            final File target = new File(config.dir, path.toString().replace('/', File.separatorChar));
            buf.retain();
            if (!target.exists()) {
                if (!target.getParentFile().exists()) {
                    if (!target.getParentFile().mkdirs()) {
                        throw new IOException("Could not create " + target.getParentFile());
                    }
                }
                if (!target.createNewFile()) {
                    throw new IOException("Could not create " + target);
                }
            }
            try (ByteBufInputStream in = new ByteBufInputStream(buf)) {
                try (OutputStream out = new BufferedOutputStream(new FileOutputStream(target))) {
                    Streams.copy(in, out, 1024);
                }
            } catch (IOException ioe) {
                if (target.exists()) {
                    target.delete();
                }
                throw ioe;
            } finally {
                buf.release();
            }
            threadPool.submit(new Runnable() {

                @Override
                public void run() {
                    if (lastModified != null) {
                        target.setLastModified(lastModified.getMillis());
                    }
                }
            });
            return null;
        }
    });
}

From source file:com.netflix.prana.http.api.ProxyHandler.java

License:Apache License

@Override
public Observable<Void> handle(final HttpServerRequest<ByteBuf> serverRequest,
        final HttpServerResponse<ByteBuf> serverResponse) {
    String vip = Utils.forQueryParam(serverRequest.getQueryParameters(), "vip");
    String path = Utils.forQueryParam(serverRequest.getQueryParameters(), "path");
    if (Strings.isNullOrEmpty(vip)) {
        serverResponse.getHeaders().set("Content-Type", "application/xml");
        serverResponse.writeString(ERROR_RESPONSE);
        logger.error("VIP is empty");
        return serverResponse.close();
    }//  ww  w. j a va2  s. c o  m

    if (path == null) {
        path = "";
    }

    final LoadBalancingHttpClient<ByteBuf, ByteBuf> client = getClient(vip);
    final HttpClientRequest<ByteBuf> req = HttpClientRequest.create(serverRequest.getHttpMethod(), path);
    populateRequestHeaders(serverRequest, req);

    final UnicastDisposableCachingSubject<ByteBuf> cachedContent = UnicastDisposableCachingSubject.create();
    /**
     * Why do we retain here?
     * After the onNext on the content returns, RxNetty releases the sent ByteBuf. This ByteBuf is kept out of
     * the scope of the onNext for consumption of the client in the route. The client when eventually writes
     * this ByteBuf over the wire expects the ByteBuf to be usable (i.e. ref count => 1). If this retain() call
     * is removed, the ref count will be 0 after the onNext on the content returns and hence it will be unusable
     * by the client in the route.
     */
    serverRequest.getContent().map(new Func1<ByteBuf, ByteBuf>() {
        @Override
        public ByteBuf call(ByteBuf byteBuf) {
            return byteBuf.retain();
        }
    }).subscribe(cachedContent); // Caches data if arrived before client writes it out, else passes through

    req.withContentSource(cachedContent);

    return client.submit(req).flatMap(new Func1<HttpClientResponse<ByteBuf>, Observable<Void>>() {
        @Override
        public Observable<Void> call(final HttpClientResponse<ByteBuf> response) {
            serverResponse.setStatus(response.getStatus());
            List<Map.Entry<String, String>> headers = response.getHeaders().entries();
            for (Map.Entry<String, String> header : headers) {
                serverResponse.getHeaders().add(header.getKey(), header.getValue());
            }
            return response.getContent().map(new Func1<ByteBuf, ByteBuf>() {
                @Override
                public ByteBuf call(ByteBuf byteBuf) {
                    return byteBuf.retain();
                }
            }).map(new Func1<ByteBuf, Void>() {
                @Override
                public Void call(ByteBuf byteBuf) {
                    serverResponse.write(byteBuf);
                    return null;
                }
            });
        }
    }).onErrorResumeNext(new Func1<Throwable, Observable<Void>>() {
        @Override
        public Observable<Void> call(Throwable throwable) {
            serverResponse.getHeaders().set("Content-Type", "application/xml");
            serverResponse.writeString(ERROR_RESPONSE);
            return Observable.just(null);
        }
    }).doOnCompleted(new Action0() {
        @Override
        public void call() {
            serverResponse.close();
            cachedContent.dispose(new Action1<ByteBuf>() {
                @Override
                public void call(ByteBuf byteBuf) {
                    /**
                     * Why do we release here?
                     *
                     * All ByteBuf which were never consumed are disposed and sent here. This means that the
                     * client in the route never consumed this ByteBuf. Before sending this ByteBuf to the
                     * content subject, we do a retain (see above for reason) expecting the client in the route
                     * to release it when written over the wire. In this case, though, the client never consumed
                     * it and hence never released corresponding to the retain done by us.
                     */
                    if (byteBuf.refCnt() > 1) { // 1 refCount will be from the subject putting into the cache.
                        byteBuf.release();
                    }
                }
            });
        }
    });
}

From source file:com.spotify.ffwd.netty.DatagramPacketToByteBuf.java

License:Apache License

@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List<Object> out) throws Exception {
    final ByteBuf buf = packet.content();
    buf.retain();
    out.add(buf);/*from  w ww .  jav a  2  s .  c  om*/
}

From source file:com.spotify.netty4.handler.codec.zmtp.ZMTPMessage.java

License:Apache License

/**
 * Convenience method for reading a {@link ZMTPMessage} from a {@link ByteBuf}.
 *///from w  ww .  j  av  a2 s.c o  m
public static ZMTPMessage read(final ByteBuf in, final ZMTPVersion version) throws ZMTPParsingException {
    final int mark = in.readerIndex();
    final ZMTPWireFormat wireFormat = ZMTPWireFormats.wireFormat(version);
    final ZMTPWireFormat.Header header = wireFormat.header();
    final RecyclableArrayList frames = RecyclableArrayList.newInstance();
    while (true) {
        final boolean read = header.read(in);
        if (!read) {
            frames.recycle();
            in.readerIndex(mark);
            return null;
        }
        if (in.readableBytes() < header.length()) {
            frames.recycle();
            in.readerIndex(mark);
            return null;
        }
        if (header.length() > Integer.MAX_VALUE) {
            throw new ZMTPParsingException("frame is too large: " + header.length());
        }
        final ByteBuf frame = in.readSlice((int) header.length());
        frame.retain();
        frames.add(frame);
        if (!header.more()) {
            @SuppressWarnings("unchecked")
            final ZMTPMessage message = ZMTPMessage.from((List<ByteBuf>) (Object) frames);
            frames.recycle();
            return message;
        }
    }
}

From source file:com.spotify.netty4.handler.codec.zmtp.ZMTPMessage.java

License:Apache License

/**
 * Create a new {@link ZMTPMessage} with a frame added at the front.
 *//* www.j a  v  a 2  s  .  c o  m*/
public ZMTPMessage push(final ByteBuf frame) {
    for (final ByteBuf f : frames) {
        f.retain();
    }
    final ByteBuf[] frames = new ByteBuf[this.frames.length + 1];
    frames[0] = frame;
    System.arraycopy(this.frames, 0, frames, 1, this.frames.length);
    return new ZMTPMessage(frames);
}