/** Non-blocking method, read as much as possible and return. */ public int processInput() throws IOException { while (true) { if (inFrame == null) { inFrame = getSpdyContext().getFrame(); } if (inFrame.data == null) { inFrame.data = new byte[16 * 1024]; } // we might already have data from previous frame if (inFrame.endReadData < 8 || // we don't have the header inFrame.endReadData < inFrame.endData) { int rd = read(inFrame.data, inFrame.endReadData, inFrame.data.length - inFrame.endReadData); if (rd == -1) { if (channels.size() == 0) { return CLOSE; } else { abort("Closed"); } } else if (rd < 0) { abort("Closed - read error"); return CLOSE; } else if (rd == 0) { return LONG; // Non-blocking channel - will resume reading at off } inFrame.endReadData += rd; } if (inFrame.endReadData < 8) { continue; // keep reading } if (inFrame.endData == 0) { inFrame.parse(); if (inFrame.version != 2) { abort("Wrong version"); return CLOSE; } // MAX_FRAME_SIZE if (inFrame.endData < 0 || inFrame.endData > 32000) { abort("Framing error, size = " + inFrame.endData); return CLOSE; } // TODO: if data, split it in 2 frames // grow the buffer if needed. if (inFrame.data.length < inFrame.endData) { byte[] tmp = new byte[inFrame.endData]; System.arraycopy(inFrame.data, 0, tmp, 0, inFrame.endReadData); inFrame.data = tmp; } } if (inFrame.endReadData < inFrame.endData) { continue; // keep reading to fill current frame } // else: we have at least the current frame int extra = inFrame.endReadData - inFrame.endData; if (extra > 0) { // and a bit more - to keep things simple for now we // copy them to next frame, at least we saved reads. // it is possible to avoid copy - but later. nextFrame = getSpdyContext().getFrame(); nextFrame.makeSpace(extra); System.arraycopy(inFrame.data, inFrame.endData, nextFrame.data, 0, extra); nextFrame.endReadData = extra; inFrame.endReadData = inFrame.endData; } // decompress if (inFrame.type == TYPE_SYN_STREAM) { inFrame.streamId = inFrame.readInt(); // 4 lastChannel = inFrame.streamId; inFrame.associated = inFrame.readInt(); // 8 inFrame.pri = inFrame.read16(); // 10 pri and unused if (compressSupport != null) { compressSupport.decompress(inFrame, 18); } inFrame.nvCount = inFrame.read16(); } else if (inFrame.type == TYPE_SYN_REPLY || inFrame.type == TYPE_HEADERS) { inFrame.streamId = inFrame.readInt(); // 4 inFrame.read16(); if (compressSupport != null) { compressSupport.decompress(inFrame, 14); } inFrame.nvCount = inFrame.read16(); } if (SpdyContext.debug) { trace("< " + inFrame); } try { int state = handleFrame(); if (state == CLOSE) { return state; } } catch (Throwable t) { abort("Error handling frame"); t.printStackTrace(); return CLOSE; } if (inFrame != null) { inFrame.recyle(); if (nextFrame != null) { inFrame = nextFrame; nextFrame = null; } } else { inFrame = nextFrame; nextFrame = null; if (inFrame == null) { inFrame = getSpdyContext().getFrame(); } } } }