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:divconq.api.LocalSession.java

License:Open Source License

@Override
public void sendStream(ScatteringByteChannel in, long size, long offset, final String channelid,
        final OperationCallback callback) {
    final DataStreamChannel chan = this.session.getChannel(channelid);

    if (chan == null) {
        callback.error(1, "Missing channel");
        callback.complete();/*from   w ww .  jav  a  2  s .  c om*/
        return;
    }

    chan.setDriver(new IStreamDriver() {
        @Override
        public void cancel() {
            callback.error(1, "Transfer canceled");
            chan.complete();
            callback.complete();
        }

        @Override
        public void message(StreamMessage msg) {
            if (msg.isFinal()) {
                System.out.println("Final on channel: " + channelid);
                chan.complete();
                callback.complete();
            }
        }

        @Override
        public void nextChunk() {
            // won't chunk so won't happen here
        }
    });

    long sent = offset;
    int seq = 0;

    if (size > 0) {
        callback.getContext().setAmountCompleted((int) (sent * 100 / size));
        chan.getContext().setAmountCompleted((int) (sent * 100 / size)); // keep the channel active so it does not timeout
    }

    try {
        ByteBuf bb = Hub.instance.getBufferAllocator().directBuffer(64 * 1024);

        long toskip = offset;

        if (in instanceof SeekableByteChannel) {
            ((SeekableByteChannel) in).position(toskip);
        } else {
            while (toskip > 0) {
                int skip = (int) Math.min(bb.capacity(), toskip);
                toskip -= bb.writeBytes(in, skip);
                bb.clear();
            }
        }

        chan.touch();

        // now start writing the upload
        int amt = bb.writeBytes(in, bb.capacity());

        while (amt != -1) {
            bb.retain(); // this ups ref cnt to 2 - we plan to reuse the buffer

            StreamMessage b = new StreamMessage("Block", bb);
            b.setField("Sequence", seq);

            OperationResult sr = chan.send(b);

            if (sr.hasErrors()) {
                chan.close();
                break;
            }

            seq++;
            sent += amt;

            if (size > 0) {
                callback.getContext().setAmountCompleted((int) (sent * 100 / size));
                chan.getContext().setAmountCompleted((int) (sent * 100 / size)); // keep the channel active so it does not timeout
            }

            callback.touch();
            chan.touch();

            // by the time we get here, that buffer has been used up and we can use it for the next buffer
            if (bb.refCnt() != 1)
                throw new IOException("Buffer reference count is not correct");

            // stop writing if canceled
            if (chan.isClosed())
                break;

            bb.clear();

            amt = bb.writeBytes(in, bb.capacity());
        }

        // we are now done with it
        bb.release();

        // final only if not canceled
        if (!chan.isClosed())
            chan.send(MessageUtil.streamFinal());
    } catch (IOException x) {
        callback.error(1, "Local read error: " + x);

        chan.send(MessageUtil.streamError(1, "Source read error: " + x));
        chan.close();

        callback.complete();
    } finally {
        try {
            in.close();
        } catch (IOException x) {
        }
    }
}

From source file:divconq.bus.net.StreamDecoder.java

License:Open Source License

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    if ((in instanceof EmptyByteBuf) || (in.readableBytes() == 0))
        return;/*  w w  w  . j  a  va 2  s  . com*/

    OperationContext.useHubContext();

    Logger.trace("Decoding Stream Data: " + in.readableBytes());

    switch (this.state) {
    case HEADER: {
        if (this.headerparser == null) {
            this.builder = new ObjectBuilder();
            this.headerparser = new BufferToCompositeParser(this.builder);
        }

        this.headerparser.parseStruct(in);

        // if not done wait for more bytes
        if (!this.headerparser.isDone())
            return;

        this.state = State.PAYLOAD_SIZE;

        // deliberate fall through 
    }
    case PAYLOAD_SIZE: {
        if (in.readableBytes() < 4)
            return;

        this.size = in.readInt();

        this.state = State.PAYLOAD;

        // deliberate fall through 
    }
    case PAYLOAD: {
        // return here, without any state reset, means we need more before we can decide what to do
        if (in.readableBytes() < this.size)
            return;

        // we have enough data to send the message...
        StreamMessage msg = new StreamMessage();

        // add Data only if there are some bytes, otherwise skip buffer allocation
        if (this.size > 0) {
            ByteBuf bb = in.readSlice(this.size);
            bb.retain();
            msg.setData(bb);
        }

        msg.copyFields((RecordStruct) this.builder.getRoot());
        out.add(msg);

        // set state to start over - ready to process next message 
        this.headerparser = null;
        this.size = 0;
        this.state = State.HEADER;
    }
    }
}

From source file:divconq.ctp.f.BlockCommand.java

License:Open Source License

@Override
public boolean decode(ByteBuf in) {
    while (this.state != State.DONE) {
        switch (this.state) {
        case BLOCK_TYPE: {
            if (in.readableBytes() < 1)
                return false;

            this.blocktype = in.readUnsignedByte();

            this.eof = ((this.blocktype & CtpConstants.CTP_F_BLOCK_TYPE_EOF) != 0);
            this.skipHeaders = ((this.blocktype & CtpConstants.CTP_F_BLOCK_TYPE_HEADER) == 0);
            this.skipPayload = ((this.blocktype & CtpConstants.CTP_F_BLOCK_TYPE_CONTENT) == 0);

            // completely done, exit the loop and decode
            if (this.skipHeaders && this.skipPayload) {
                this.state = State.DONE;
                break;
            }/*from w w w  .  j av  a  2  s.c  o  m*/

            // to skip headers, go back to loop
            if (this.skipHeaders) {
                this.state = State.STREAM_OFFSET;
                break;
            }

            this.state = State.HEADER_ATTR;

            // deliberate fall through 
        }
        case HEADER_ATTR: {
            if (in.readableBytes() < 2)
                return false;

            this.currattr = in.readShort();

            // done with headers, go back to loop to skip down to payload
            if (this.currattr == CtpConstants.CTP_F_ATTR_END) {
                if (this.skipPayload)
                    this.state = State.DONE;
                else
                    this.state = State.STREAM_OFFSET;

                break;
            }

            this.state = State.HEADER_SIZE;

            // deliberate fall through 
        }
        case HEADER_SIZE: {
            if (in.readableBytes() < 2)
                return false;

            this.currasize = in.readShort();

            // an empty attribute is like a flag - present but no data
            // go on to next header
            if (this.currasize == 0) {
                this.headers.put(this.currattr, new byte[0]);
                this.currattr = 0;
                this.state = State.HEADER_ATTR;
                break;
            }

            this.state = State.HEADER_VALUE;

            // deliberate fall through 
        }
        case HEADER_VALUE: {
            if (in.readableBytes() < this.currasize)
                return false;

            byte[] val = new byte[this.currasize];

            in.readBytes(val);

            this.headers.put(this.currattr, val);

            this.currattr = 0;
            this.currasize = 0;

            this.state = State.HEADER_ATTR;

            break;
        }
        case STREAM_OFFSET: {
            if (in.readableBytes() < 8)
                return false;

            this.streamOffset = in.readLong();

            this.state = State.PAYLOAD_SIZE;

            // deliberate fall through 
        }
        case PAYLOAD_SIZE: {
            if (in.readableBytes() < 3)
                return false;

            this.paysize = in.readMedium();

            this.state = State.PAYLOAD;

            // deliberate fall through 
        }
        case PAYLOAD: {
            // return here, without any state reset, means we need more before we can decide what to do
            if (in.readableBytes() < this.paysize)
                return false;

            // add Data only if there are some bytes, otherwise skip buffer allocation
            if (this.paysize > 0) {
                ByteBuf bb = in.readSlice(this.paysize);
                bb.retain();
                this.data = bb;
            }

            this.state = State.DONE;

            // deliberate fall through 
        }
        case DONE: {
            break;
        }
        }
    }

    return true;
}

From source file:divconq.http.multipart.MixedFileUpload.java

License:Apache License

@Override
public void addContent(ByteBuf buffer, boolean last) throws IOException {
    if (fileUpload instanceof MemoryFileUpload) {
        checkSize(fileUpload.length() + buffer.readableBytes());
        if (fileUpload.length() + buffer.readableBytes() > limitSize) {
            DiskFileUpload diskFileUpload = new DiskFileUpload(fileUpload.getName(), fileUpload.getFilename(),
                    fileUpload.getContentType(), fileUpload.getContentTransferEncoding(),
                    fileUpload.getCharset(), definedSize);
            diskFileUpload.setMaxSize(maxSize);
            ByteBuf data = fileUpload.getByteBuf();
            if (data != null && data.isReadable()) {
                diskFileUpload.addContent(data.retain(), false);
            }/*from  w  w w.java  2s  . c  om*/
            // release old upload
            fileUpload.release();

            fileUpload = diskFileUpload;
        }
    }
    fileUpload.addContent(buffer, last);
}

From source file:divconq.web.http.ServerHandler.java

License:Open Source License

public void handleHttpRequest(ChannelHandlerContext ctx, HttpObject httpobj) throws Exception {
    if (httpobj instanceof HttpContent) {
        this.context.offerContent((HttpContent) httpobj);
        return;//from   w ww . j a va  2  s  . co  m
    }

    if (!(httpobj instanceof HttpRequest)) {
        this.context.sendRequestBad();
        return;
    }

    HttpRequest httpreq = (HttpRequest) httpobj;

    this.context.load(ctx, httpreq);

    // Handle a bad request.
    if (!httpreq.getDecoderResult().isSuccess()) {
        this.context.sendRequestBad();
        return;
    }

    Request req = this.context.getRequest();
    Response resp = this.context.getResponse();

    // to avoid lots of unused sessions
    if (req.pathEquals("/favicon.ico") || req.pathEquals("/robots.txt")) {
        this.context.sendNotFound();
        return;
    }

    // make sure we don't have a leftover task context
    OperationContext.clear();

    String origin = "http:" + NetUtil.formatIpAddress((InetSocketAddress) ctx.channel().remoteAddress());

    // TODO use X-Forwarded-For  if available, maybe a plug in approach to getting client's IP?

    DomainInfo dinfo = this.context.getSiteman().resolveDomainInfo(req.getHeader("Host"));

    if (dinfo == null) {
        this.context.sendForbidden();
        return;
    }

    WebDomain wdomain = this.context.getSiteman().getDomain(dinfo.getId());

    // check into url re-routing
    String reroute = wdomain.route(req, (SslHandler) ctx.channel().pipeline().get("ssl"));

    if (StringUtil.isNotEmpty(reroute)) {
        this.context.getResponse().setStatus(HttpResponseStatus.FOUND);
        this.context.getResponse().setHeader("Location", reroute);
        this.context.send();
        return;
    }

    Cookie sesscookie = req.getCookie("SessionId");
    Session sess = null;

    if (sesscookie != null) {
        String v = sesscookie.getValue();
        String sessionid = v.substring(0, v.lastIndexOf('_'));
        String accesscode = v.substring(v.lastIndexOf('_') + 1);

        sess = Hub.instance.getSessions().lookupAuth(sessionid, accesscode);
    }

    if (sess == null) {
        sess = Hub.instance.getSessions().create(origin, dinfo.getId());

        Logger.info("Started new session: " + sess.getId() + " on " + req.getPath() + " for " + origin);

        // TODO if ssl set client key on user context
        //req.getSecuritySession().getPeerCertificates();

        sess.setAdatper(new ISessionAdapter() {
            protected volatile ListStruct msgs = new ListStruct();

            @Override
            public void stop() {
                ServerHandler.this.context.close();
            }

            @Override
            public ListStruct popMessages() {
                ListStruct ret = this.msgs;
                this.msgs = new ListStruct();
                return ret;
            }

            @Override
            public void deliver(Message msg) {
                // keep no more than 100 messages - this is not a "reliable" approach, just basic comm help               
                while (this.msgs.getSize() > 99)
                    this.msgs.removeItem(0);

                this.msgs.addItem(msg);
            }
        });

        Cookie sk = new DefaultCookie("SessionId", sess.getId() + "_" + sess.getKey());
        sk.setPath("/");
        sk.setHttpOnly(true);

        resp.setCookie(sk);
    }

    this.context.setSession(sess);

    sess.touch();

    OperationContext tc = sess.setContext(origin);

    tc.info("Web request for host: " + req.getHeader("Host") + " url: " + req.getPath() + " by: " + origin
            + " session: " + sess.getId());

    /*
    System.out.println("sess proto: " + ((SslHandler)ctx.channel().pipeline().get("ssl")).engine().getSession().getProtocol());
    System.out.println("sess suite: " + ((SslHandler)ctx.channel().pipeline().get("ssl")).engine().getSession().getCipherSuite());
    */

    try {
        if (req.pathEquals(ServerHandler.BUS_PATH)) {
            // Allow only GET methods.
            if (req.getMethod() != HttpMethod.GET) {
                this.context.sendForbidden();
                return;
            }

            // Handshake
            WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                    ServerHandler.getWebSocketLocation(
                            "True".equals(this.context.getConfig().getAttribute("Secure")), httpreq),
                    null, false);

            this.handshaker = wsFactory.newHandshaker(httpreq);

            if (this.handshaker == null)
                WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
            else {
                DefaultFullHttpRequest freq = new DefaultFullHttpRequest(httpreq.getProtocolVersion(),
                        httpreq.getMethod(), httpreq.getUri());

                freq.headers().add(httpreq.headers());

                this.handshaker.handshake(ctx.channel(), freq);

                return;
            }

            this.context.sendForbidden();
            return;
        }

        // "upload" is it's own built-in extension.  
        if ((req.getPath().getNameCount() == 3) && req.getPath().getName(0).equals(ServerHandler.UPLOAD_PATH)) {
            if (!Hub.instance.isRunning()) { // only allow uploads when running
                this.context.sendRequestBad();
                return;
            }

            // currently only supporting POST/PUT of pure binary - though support for form uploads can be restored, see below
            // we cannot rely on content type being meaningful
            //if (!"application/octet-stream".equals(req.getContentType().getPrimary())) {
            //    this.context.sendRequestBad();
            //    return;
            //}

            // TODO add CORS support if needed

            if ((req.getMethod() != HttpMethod.PUT) && (req.getMethod() != HttpMethod.POST)) {
                this.context.sendRequestBad();
                return;
            }

            final String cid = req.getPath().getName(1);
            final String op = req.getPath().getName(2);

            final DataStreamChannel dsc = sess.getChannel(cid);

            if (dsc == null) {
                this.context.sendRequestBad();
                return;
            }

            dsc.setDriver(new IStreamDriver() {
                @Override
                public void cancel() {
                    Logger.error("Transfer canceled on channel: " + cid);
                    dsc.complete();
                    ServerHandler.this.context.sendRequestBad(); // TODO headers?
                }

                @Override
                public void nextChunk() {
                    Logger.debug("Continue on channel: " + cid);
                    ServerHandler.this.context.sendRequestOk();
                }

                @Override
                public void message(StreamMessage msg) {
                    if (msg.isFinal()) {
                        Logger.debug("Final on channel: " + cid);
                        dsc.complete();
                        ServerHandler.this.context.sendRequestOk();
                    }
                }
            });

            //if (req.getMethod() == HttpMethod.PUT) {
            this.context.setDecoder(new IContentDecoder() {
                protected boolean completed = false;
                protected int seq = 0;

                @Override
                public void release() {
                    // trust that http connection is closing or what ever needs to happen, we just need to deal with datastream

                    Logger.debug("Releasing data stream");

                    // if not done with request then something went wrong, kill data channel
                    if (!this.completed)
                        dsc.abort();
                }

                @Override
                public void offer(HttpContent chunk) {
                    boolean finalchunk = (chunk instanceof LastHttpContent);

                    //System.out.println("Chunk: " + finalchunk);

                    ByteBuf buffer = chunk.content();

                    if (!dsc.isClosed()) {
                        int size = buffer.readableBytes();

                        //System.out.println("Chunk size: " + size);

                        dsc.touch(); // TODO try to set progress on dsc

                        // TODO set hint in netty as to where this buffer was handled and sent

                        if (size > 0) {
                            buffer.retain(); // we will be using a reference up during send

                            StreamMessage b = new StreamMessage("Block", buffer);
                            b.setField("Sequence", this.seq);

                            //System.out.println("Buffer ref cnt a: " + buffer.refCnt());

                            OperationResult or = dsc.send(b);

                            //System.out.println("Buffer ref cnt b: " + buffer.refCnt());

                            // indicate we have read the buffer?
                            buffer.readerIndex(buffer.writerIndex());

                            if (or.hasErrors()) {
                                dsc.close();
                                return;
                            }

                            this.seq++;
                        }

                        // if last buffer of last block then mark the upload as completed
                        if (finalchunk) {
                            if ("Final".equals(op))
                                dsc.send(MessageUtil.streamFinal());
                            else
                                dsc.getDriver().nextChunk();
                        }
                    }

                    // means this block is completed, not necessarily entire file uploaded
                    if (finalchunk)
                        this.completed = true;
                }
            });

            //return;
            //}

            /* old approach that supported multipart posts TODO review/remove
            if (req.getMethod() == HttpMethod.POST) {
               StreamingDataFactory sdf = new StreamingDataFactory(dsc, op);
                       
               // TODO consider supporting non-multipart?
               final HttpPostMultipartRequestDecoder prd = new HttpPostMultipartRequestDecoder(sdf, httpreq); 
                    
                 this.context.setDecoder(new IContentDecoder() {               
                 @Override
                 public void release() {
             // trust that http connection is closing or what ever needs to happen, we just need to deal with datastream
                     
             // if not done with request then something went wrong, kill data channel
             if ((prd.getStatus() != MultiPartStatus.EPILOGUE) && (prd.getStatus() != MultiPartStatus.PREEPILOGUE))
                dsc.kill();
                 }
                         
                 @Override
                 public void offer(HttpContent chunk) {
             //the only thing we care about is the file, the file will stream to dsc - the rest can disappear
             prd.offer(chunk);      
                 }
              });
                         
                  return;
            }                         
            */

            //this.context.sendRequestBad();
            return;
        }

        // "download" is it's own built-in extension.  
        if ((req.getPath().getNameCount() == 2)
                && req.getPath().getName(0).equals(ServerHandler.DOWNLOAD_PATH)) {
            if (!Hub.instance.isRunning()) { // only allow downloads when running
                this.context.sendRequestBad();
                return;
            }

            if (req.getMethod() != HttpMethod.GET) {
                this.context.sendRequestBad();
                return;
            }

            String cid = req.getPath().getName(1);

            final DataStreamChannel dsc = sess.getChannel(cid);

            if (dsc == null) {
                this.context.sendRequestBad();
                return;
            }

            dsc.setDriver(new IStreamDriver() {
                //protected long amt = 0;
                protected long seq = 0;

                @Override
                public void cancel() {
                    dsc.complete();
                    ServerHandler.this.context.close();
                }

                @Override
                public void nextChunk() {
                    // meaningless in download
                }

                @Override
                public void message(StreamMessage msg) {
                    int seqnum = (int) msg.getFieldAsInteger("Sequence", 0);

                    if (seqnum != this.seq) {
                        this.error(1, "Bad sequence number: " + seqnum);
                        return;
                    }

                    if (msg.hasData()) {
                        //this.amt += msg.getData().readableBytes();
                        HttpContent b = new DefaultHttpContent(Unpooled.copiedBuffer(msg.getData())); // TODO not copied
                        ServerHandler.this.context.sendDownload(b);
                    }

                    this.seq++;

                    // TODO update progress

                    if (msg.isFinal()) {
                        ServerHandler.this.context.sendDownload(new DefaultLastHttpContent());
                        ServerHandler.this.context.close();
                        dsc.complete();
                    }
                }

                public void error(int code, String msg) {
                    dsc.send(MessageUtil.streamError(code, msg));
                    ServerHandler.this.context.close();
                }
            });

            // for some reason HyperSession is sending content. 
            this.context.setDecoder(new IContentDecoder() {
                @Override
                public void release() {
                }

                @Override
                public void offer(HttpContent chunk) {
                    if (!(chunk instanceof LastHttpContent))
                        Logger.error("Unexplained and unwanted content during download: " + chunk);
                }
            });

            // tell the client that chunked content is coming
            this.context.sendDownloadHeaders(dsc.getPath() != null ? dsc.getPath().getFileName() : null,
                    dsc.getMime());

            // get the data flowing
            dsc.send(new StreamMessage("Start"));

            return;
        }

        if ((req.getPath().getNameCount() == 1) && req.getPath().getName(0).equals(ServerHandler.STATUS_PATH)) {
            if (Hub.instance.getState() == HubState.Running)
                this.context.sendRequestOk();
            else
                this.context.sendRequestBad();

            return;
        }

        // "rpc" is it's own built-in extension.  all requests to rpc are routed through
        // DivConq bus, if the request is valid
        if (req.pathEquals(ServerHandler.RPC_PATH)) {
            if (req.getMethod() != HttpMethod.POST) {
                this.context.sendRequestBad();
                return;
            }

            //System.out.println("looks like we have a rpc message");

            // max 4MB of json? -- TODO is that max chunk size or max total?  we don't need 4MB chunk... 
            this.context.setDecoder(new HttpBodyRequestDecoder(4096 * 1024, new RpcHandler(this.context)));
            return;
        }

        // otherwise we need to figure out which extension is being called
        // "local" is also used to mean default extension
        String ext = req.pathEquals("/") ? "local" : req.getPath().getName(0);

        IWebExtension ex = "local".equals(ext) ? this.context.getSiteman().getDefaultExtension()
                : this.context.getSiteman().getExtension(ext);

        // still cannot figure it out, use default
        if (ex == null)
            ex = this.context.getSiteman().getDefaultExtension();

        // then have extension handle it
        if (ex != null) {
            //OperationResult res = new OperationResult();  

            OperationResult res = ex.handle(sess, this.context);
            //resp.addBody("Hello");
            //this.context.send();

            // no errors starting page processing, return 
            if (!res.hasErrors())
                return;

            resp.setHeader("X-dcResultCode", res.getCode() + "");
            resp.setHeader("X-dcResultMesage", res.getMessage());
            this.context.sendNotFound();
            return;
        }
    } catch (Exception x) {
        this.context.sendInternalError();
        return;
    }

    this.context.sendNotFound();
}

From source file:divconq.web.HttpUploadDecoder.java

License:Open Source License

@Override
public void offer(HttpContent chunk) {
    if (this.channel.isClosed())
        return; // TODO somehow connect the cancel back to netsession 

    if (chunk.content().readableBytes() > this.max) {
        this.channel.abort(); // TODO somehow connect the cancel back to netsession
        return;//w  w  w.  ja v a 2s.  c o  m
    }

    ByteBuf bb = chunk.content();
    bb.retain(); // we will use it in upcoming send

    System.out.println("ref count a: " + bb.refCnt());

    StreamMessage b = new StreamMessage("Block", bb);
    b.setField("Sequence", this.seq);

    OperationResult or = this.channel.send(b);

    // bb should now be back to 1

    System.out.println("ref count b: " + bb.refCnt());

    if (or.hasErrors()) {
        this.channel.close();
        return;
    }

    this.seq++;

    // TODO track progress if possible

    // final only if not canceled
    if (chunk instanceof LastHttpContent)
        this.channel.send(MessageUtil.streamFinal());
}

From source file:eu.stratosphere.runtime.io.network.netty.InboundEnvelopeDecoderTest.java

License:Apache License

@Test
public void testEncodeDecode() throws Exception {
    final EmbeddedChannel ch = new EmbeddedChannel(new OutboundEnvelopeEncoder(),
            new InboundEnvelopeDecoder(this.bufferProviderBroker));

    when(this.bufferProviderBroker.getBufferProvider(anyJobId(), anyChannelId()))
            .thenReturn(this.bufferProvider);

    when(this.bufferProvider.requestBuffer(anyInt())).thenAnswer(new Answer<Object>() {
        @Override/*from www .j  a va 2s .  c om*/
        public Object answer(InvocationOnMock invocation) throws Throwable {
            // fulfill the buffer request
            return allocBuffer((Integer) invocation.getArguments()[0]);
        }
    });

    // --------------------------------------------------------------------

    Envelope[] envelopes = new Envelope[] { nextEnvelope(0), nextEnvelope(2), nextEnvelope(32768),
            nextEnvelope(3782, new TestEvent1(34872527)),
            nextEnvelope(88, new TestEvent1(8749653), new TestEvent1(365345)),
            nextEnvelope(0, new TestEvent2(34563456), new TestEvent1(598432), new TestEvent2(976293845)),
            nextEnvelope(23) };

    ByteBuf buf = encode(ch, envelopes);

    // 1. complete ByteBuf as input
    int refCount = buf.retain().refCnt();

    decodeAndVerify(ch, buf, envelopes);
    Assert.assertEquals(refCount - 1, buf.refCnt());

    // 2. random slices
    buf.readerIndex(0);
    ByteBuf[] slices = randomSlices(buf);

    ch.writeInbound(slices);

    for (ByteBuf slice : slices) {
        Assert.assertEquals(1, slice.refCnt());
    }

    decodeAndVerify(ch, envelopes);

    buf.release();
}

From source file:firebats.http.server.exts.form.Form.java

License:Apache License

private static Form decodeWithContent(Context context, ByteBuf content) {
    //new DefaultHttpDataFactory(/*useDisk*/true)decoder?
    //Mix?16K???/*from  w  w w . jav  a  2s .c  om*/
    //       final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(/*useDisk*/true),toNettyHttpRequest(context.request));
    HttpServerRequest<ByteBuf> rxRequest = context.getRequest();
    HttpRequest nettyRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, rxRequest.getHttpMethod(),
            rxRequest.getUri());
    for (Map.Entry<String, String> header : rxRequest.getHeaders().entries()) {
        nettyRequest.headers().add(header.getKey(), header.getValue());
    }
    final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(nettyRequest);
    HttpContent httpContent = new DefaultHttpContent(content);
    decoder.offer(httpContent);
    decoder.offer(LastHttpContent.EMPTY_LAST_CONTENT);

    Map<String, String> formParams = new LinkedHashMap<>();
    Map<String, UploadedFile> files = new LinkedHashMap<>();
    try {
        while (decoder.hasNext()) {
            InterfaceHttpData data = decoder.next();
            if (data.getHttpDataType().equals(InterfaceHttpData.HttpDataType.Attribute)) {
                try {
                    Attribute attr = (Attribute) data;
                    if (!formParams.containsKey(data.getName())) {
                        formParams.put(attr.getName(), attr.getValue());
                    }
                } catch (IOException e) {
                    Throwables.propagate(e);
                } finally {
                    //?
                    data.release();
                }
            } else if (data.getHttpDataType().equals(InterfaceHttpData.HttpDataType.FileUpload)) {
                try {
                    if (!files.containsKey(data.getName())) {
                        final FileUpload nettyFileUpload = (FileUpload) data;
                        final ByteBuf byteBuf = nettyFileUpload.content();
                        byteBuf.retain();
                        context.onComplete(new Action0() {
                            @Override
                            public void call() {
                                if (log.isDebugEnabled()) {
                                    log.debug("form upload file release[" + data.getName() + ":"
                                            + nettyFileUpload.getFilename() + "]");
                                }
                                byteBuf.release();
                            }
                        });
                        UploadedFile fileUpload = new UploadedFile(nettyFileUpload.getFilename(),
                                nettyFileUpload.getContentType(), byteBuf);
                        files.put(data.getName(), fileUpload);
                    }
                } finally {
                    data.release();
                }
            }
        }
    } catch (HttpPostRequestDecoder.EndOfDataDecoderException ignore) {
        // ignore
    } finally {
        decoder.destroy();
    }
    Map<String, String> query = Form.toFlatQueryParams(context.getRequest().getQueryParameters());
    return fromAll(query, formParams, files);
}

From source file:gribbit.server.siteresources.CacheExtension.java

License:Open Source License

/**
 * Create a hash URI (which allows the browser to cache this resource indefinitely) if the last modified
 * timestamp has increased, or if there is no hash URI yet for this resource. For a new hash URI to be created,
 * the passed object is scheduled to be hashed by a background thread.
 *
 * This method can be called by any route handler that stores or returns database objects. It should be called
 * both when storing objects and when returning them, since the hash URI cache is held in RAM and is empty when
 * the server starts, so it needs to be built as requests start to come in. IMPORTANT NOTE: If the database can
 * be written to by other database clients, then this method must also be called when those changes are
 * detected, otherwise web clients connected to this web server will continue to serve old linked resources.
 * //  www. j a v  a2 s .co  m
 * This method should only be used when the total keyspace of URIs that map to database objects easily fits in
 * RAM, and when the objects that need to be hashed are not large (i.e. tens of MB is OK, hundreds of MB is
 * probably not, since there are several background worker threads and they all can be hashing objects in
 * parallel).
 */
public static void updateHashURI(String origURI, ByteBuf content, long lastModifiedEpochSeconds) {
    // Can only hash absolute but local (i.e. domain-less) URIs that have not already been hashed
    if (origURI.startsWith("/") && !origURI.startsWith("//") && !origURI.startsWith("/_/")) {
        // Check to see if there is already a mapping to hash URI for this original URI
        HashInfo hashInfo = origURIToHashInfo.get(origURI);
        if (hashInfo == null || hashInfo.lastModifiedEpochSeconds < lastModifiedEpochSeconds) {
            // There is no hash URI yet for origURI, or there is already a hash URI corresponding to origURI,
            // but the modification time has increased since the cached version, so need to re-hash.
            // Check if another thread has already enqueued the URI for hashing.
            Object alreadyInQueue = scheduledURIsToHash.put(origURI, new Object());
            if (alreadyInQueue == null) {
                content.retain();
                // This URI is not currently queued for hashing by background workers, add it to the queue
                scheduleHasher(origURI, lastModifiedEpochSeconds, new Hasher() {
                    @Override
                    public String computeHashKey() {
                        // Compute MD5 hash of the ByteBuf contents, then base64-encode the results
                        try {
                            String hash = Base64Safe
                                    .base64Encode(DigestUtils.md5(new ByteBufInputStream(content)));
                            content.release(); // TODO: does ByteBufInputStream call release()?
                            return hash;
                        } catch (IOException e) {
                            return null;
                        }
                    }
                });
            }
        }
    }
}

From source file:http2.server.HelloWorldHttp2Handler.java

License:Apache License

@Override
public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) {
    logger.info("onDataRead, " + streamId + ", data : " + data.toString());
    int processed = data.readableBytes() + padding;
    if (endOfStream) {
        sendResponse(ctx, streamId, data.retain());
    }/*from   w ww.j a  va  2  s.c o  m*/
    return processed;
}