/* ************************************************************************ # # DivConq # # http://divconq.com/ # # Copyright: # Copyright 2014 eTimeline, LLC. All rights reserved. # # License: # See the license.txt file in the project's top-level directory for details. # # Authors: # * Andy White # ************************************************************************ */ package divconq.web; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.http.HttpContent; import io.netty.handler.codec.http.LastHttpContent; import divconq.bus.MessageUtil; import divconq.bus.net.StreamMessage; import divconq.lang.op.OperationResult; import divconq.session.DataStreamChannel; public class HttpUploadDecoder implements IContentDecoder { protected int max = 0; protected int seq = 0; protected DataStreamChannel channel = null; public HttpUploadDecoder(int max, DataStreamChannel chan) { this.channel = chan; this.max = max; } @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; } 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()); } @Override public void release() { } }