@Override public void incomingFrame(Frame frame) { // Incoming frames are always non concurrent because // they are read and parsed with a single thread, and // therefore there is no need for synchronization. // This extension requires the RSV1 bit set only in the first frame. // Subsequent continuation frames don't have RSV1 set, but are compressed. if (frame.getType().isData()) incomingCompressed = frame.isRsv1(); if (OpCode.isControlFrame(frame.getOpCode()) || !frame.hasPayload() || !incomingCompressed) { nextIncomingFrame(frame); return; } boolean appendTail = frame.isFin(); ByteBuffer payload = frame.getPayload(); int remaining = payload.remaining(); byte[] input = new byte[remaining + (appendTail ? TAIL_BYTES.length : 0)]; payload.get(input, 0, remaining); if (appendTail) System.arraycopy(TAIL_BYTES, 0, input, remaining, TAIL_BYTES.length); forwardIncoming(frame, decompress(input)); if (frame.isFin()) incomingCompressed = false; }
private void fragment(FrameEntry entry, boolean first) { Frame frame = entry.frame; ByteBuffer payload = frame.getPayload(); int remaining = payload.remaining(); int length = Math.min(remaining, maxLength); finished = length == remaining; boolean continuation = frame.getType().isContinuation() || !first; DataFrame fragment = new DataFrame(frame, continuation); boolean fin = frame.isFin() && finished; fragment.setFin(fin); int limit = payload.limit(); int newLimit = payload.position() + length; payload.limit(newLimit); ByteBuffer payloadFragment = payload.slice(); payload.limit(limit); fragment.setPayload(payloadFragment); if (LOG.isDebugEnabled()) LOG.debug("Fragmented {}->{}", frame, fragment); payload.position(newLimit); nextOutgoingFrame(fragment, this, entry.batchMode); }