public AjpClientRequestClientStreamSinkChannel sendRequest(final HttpString method, final String path, final HttpString protocol, final HeaderMap headers, final Attachable attachable, ChannelListener<AjpClientRequestClientStreamSinkChannel> finishListener) { if (!sinkDone || !sourceDone) { throw UndertowMessages.MESSAGES.ajpRequestAlreadyInProgress(); } sinkDone = false; sourceDone = false; AjpClientRequestClientStreamSinkChannel ajpClientRequestStreamSinkChannel = new AjpClientRequestClientStreamSinkChannel(this, finishListener, headers, path, method, protocol, attachable); sink = ajpClientRequestStreamSinkChannel; source = null; return ajpClientRequestStreamSinkChannel; }
@Override public boolean insertFrame(AbstractAjpClientStreamSinkChannel newFrame, List<AbstractAjpClientStreamSinkChannel> pendingFrames) { if(newFrame instanceof AjpClientRequestClientStreamSinkChannel) { SendFrameHeader header = ((AjpClientRequestClientStreamSinkChannel) newFrame).generateSendFrameHeader(); if(header.getByteBuffer() == null) { //we clear the header, as we want to generate a new real header when the flow control window is updated ((AjpClientRequestClientStreamSinkChannel) newFrame).clearHeader(); return false; } } pendingFrames.add(newFrame); return true; }
SendFrameHeader generateSendFrameHeader() { header = createFrameHeaderImpl(); return header; }
public void startDiscard() { discardMode = true; try { getChannel().recalculateHeldFrames(); } catch (IOException e) { markBroken(); } }
private void handleFailedFlush(AjpClientRequestClientStreamSinkChannel sinkChannel) { sinkChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener(null, new ChannelExceptionHandler<StreamSinkChannel>() { @Override public void handleException(StreamSinkChannel channel, IOException exception) { handleError(exception); } })); sinkChannel.resumeWrites(); }
private SendFrameHeader createFrameHeaderImpl() { if (discardMode) { getBuffer().clear(); getBuffer().flip(); return new SendFrameHeader(new ImmediatePooledByteBuffer(ByteBuffer.wrap(new byte[0]))); PooledByteBuffer pooledHeaderBuffer = getChannel().getBufferPool().allocate(); try { ByteBuffer dataBuffer = getBuffer(); int dataInBuffer = dataBuffer.remaining(); if (!firstFrameWritten && requestedChunkSize == 0) { int maxData = getChannel().getSettings().get(UndertowOptions.MAX_AJP_PACKET_SIZE, DEFAULT_MAX_DATA_SIZE) - 6; } else if (isWritesShutdown() && !headers.contains(Headers.TRANSFER_ENCODING)) { if (isWritesShutdown() && dataInBuffer == 0) { buffer.put((byte) 0x12); buffer.put((byte) 0x34); requestedChunkSize = 0; if (remaining < dataInBuffer) { dataBuffer.limit(getBuffer().position() + remaining); buffer.flip(); return new SendFrameHeader(dataInBuffer - remaining, pooledHeaderBuffer, dataSize < 0); markBroken(); throw e;
sinkChannel.shutdownWrites(); if (!sinkChannel.flush()) { handleFailedFlush(sinkChannel);
void chunkRequested(int size) throws IOException { requestedChunkSize = size; getChannel().recalculateHeldFrames(); }
@Override protected AbstractAjpClientStreamSourceChannel createChannel(FrameHeaderData frameHeaderData, PooledByteBuffer frameData) throws IOException { if (frameHeaderData instanceof SendHeadersResponse) { SendHeadersResponse h = (SendHeadersResponse) frameHeaderData; AjpClientResponseStreamSourceChannel sourceChannel = new AjpClientResponseStreamSourceChannel(this, h.headers, h.statusCode, h.reasonPhrase, frameData, (int) frameHeaderData.getFrameLength()); this.source = sourceChannel; return sourceChannel; } else if (frameHeaderData instanceof RequestBodyChunk) { RequestBodyChunk r = (RequestBodyChunk) frameHeaderData; this.sink.chunkRequested(r.getLength()); frameData.close(); return null; } else if (frameHeaderData instanceof CpongResponse) { synchronized (pingListeners) { for(ClientConnection.PingListener i : pingListeners) { try { i.acknowledged(); } catch (Throwable t) { UndertowLogger.ROOT_LOGGER.debugf("Exception notifying ping listener", t); } } pingListeners.clear(); } return null; } else { frameData.close(); throw new RuntimeException("TODO: unknown frame"); } }
private SendFrameHeader createFrameHeaderImpl() { if (discardMode) { getBuffer().clear(); getBuffer().flip(); return new SendFrameHeader(new ImmediatePooledByteBuffer(ByteBuffer.wrap(new byte[0]))); PooledByteBuffer pooledHeaderBuffer = getChannel().getBufferPool().allocate(); try { ByteBuffer dataBuffer = getBuffer(); int dataInBuffer = dataBuffer.remaining(); if (!firstFrameWritten && requestedChunkSize == 0) { int maxData = getChannel().getSettings().get(UndertowOptions.MAX_AJP_PACKET_SIZE, DEFAULT_MAX_DATA_SIZE) - 6; } else if (isWritesShutdown() && !headers.contains(Headers.TRANSFER_ENCODING)) { if (isWritesShutdown() && dataInBuffer == 0) { buffer.put((byte) 0x12); buffer.put((byte) 0x34); requestedChunkSize = 0; if (remaining < dataInBuffer) { dataBuffer.limit(getBuffer().position() + remaining); buffer.flip(); return new SendFrameHeader(dataInBuffer - remaining, pooledHeaderBuffer, dataSize < 0); markBroken(); throw e;
private void handleFailedFlush(AjpClientRequestClientStreamSinkChannel sinkChannel) { sinkChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener(null, new ChannelExceptionHandler<StreamSinkChannel>() { @Override public void handleException(StreamSinkChannel channel, IOException exception) { handleError(exception); } })); sinkChannel.resumeWrites(); }
public void startDiscard() { discardMode = true; try { getChannel().recalculateHeldFrames(); } catch (IOException e) { markBroken(); } }
sinkChannel.shutdownWrites(); if (!sinkChannel.flush()) { handleFailedFlush(sinkChannel);
@Override protected void handleFlushComplete(boolean finalFrame) { super.handleFlushComplete(finalFrame); if (finalFrame) { getChannel().sinkDone(); } if (finalFrame && finishListener != null) { finishListener.handleEvent(this); } }
@Override protected AbstractAjpClientStreamSourceChannel createChannel(FrameHeaderData frameHeaderData, PooledByteBuffer frameData) throws IOException { if (frameHeaderData instanceof SendHeadersResponse) { SendHeadersResponse h = (SendHeadersResponse) frameHeaderData; AjpClientResponseStreamSourceChannel sourceChannel = new AjpClientResponseStreamSourceChannel(this, h.headers, h.statusCode, h.reasonPhrase, frameData, (int) frameHeaderData.getFrameLength()); this.source = sourceChannel; return sourceChannel; } else if (frameHeaderData instanceof RequestBodyChunk) { RequestBodyChunk r = (RequestBodyChunk) frameHeaderData; this.sink.chunkRequested(r.getLength()); frameData.close(); return null; } else if (frameHeaderData instanceof CpongResponse) { synchronized (pingListeners) { for(ClientConnection.PingListener i : pingListeners) { try { i.acknowledged(); } catch (Throwable t) { UndertowLogger.ROOT_LOGGER.debugf("Exception notifying ping listener", t); } } pingListeners.clear(); } return null; } else { frameData.close(); throw new RuntimeException("TODO: unknown frame"); } }
private SendFrameHeader createFrameHeaderImpl() { if (discardMode) { getBuffer().clear(); getBuffer().flip(); return new SendFrameHeader(new ImmediatePooledByteBuffer(ByteBuffer.wrap(new byte[0]))); PooledByteBuffer pooledHeaderBuffer = getChannel().getBufferPool().allocate(); try { ByteBuffer dataBuffer = getBuffer(); int dataInBuffer = dataBuffer.remaining(); if (!firstFrameWritten && requestedChunkSize == 0) { int maxData = getChannel().getSettings().get(UndertowOptions.MAX_AJP_PACKET_SIZE, DEFAULT_MAX_DATA_SIZE) - 6; } else if (isWritesShutdown() && !headers.contains(Headers.TRANSFER_ENCODING)) { if (isWritesShutdown() && dataInBuffer == 0) { buffer.put((byte) 0x12); buffer.put((byte) 0x34); requestedChunkSize = 0; if (remaining < dataInBuffer) { dataBuffer.limit(getBuffer().position() + remaining); buffer.flip(); return new SendFrameHeader(dataInBuffer - remaining, pooledHeaderBuffer, dataSize < 0); markBroken(); throw e;
@Override public void frameAdded(AbstractAjpClientStreamSinkChannel addedFrame, List<AbstractAjpClientStreamSinkChannel> pendingFrames, Deque<AbstractAjpClientStreamSinkChannel> holdFrames) { Iterator<AbstractAjpClientStreamSinkChannel> it = holdFrames.iterator(); while (it.hasNext()){ AbstractAjpClientStreamSinkChannel pending = it.next(); if(pending instanceof AjpClientRequestClientStreamSinkChannel) { SendFrameHeader header = ((AjpClientRequestClientStreamSinkChannel) pending).generateSendFrameHeader(); if(header.getByteBuffer() != null) { pendingFrames.add(pending); it.remove(); } else { //we clear the header, as we want to generate a new real header when the flow control window is updated ((AjpClientRequestClientStreamSinkChannel) pending).clearHeader(); } } } } }
private void handleFailedFlush(AjpClientRequestClientStreamSinkChannel sinkChannel) { sinkChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener(null, new ChannelExceptionHandler<StreamSinkChannel>() { @Override public void handleException(StreamSinkChannel channel, IOException exception) { handleError(exception); } })); sinkChannel.resumeWrites(); }
public void startDiscard() { discardMode = true; try { getChannel().recalculateHeldFrames(); } catch (IOException e) { markBroken(); } }
sinkChannel.shutdownWrites(); if (!sinkChannel.flush()) { handleFailedFlush(sinkChannel);