private void setOpWrite() { ConduitStreamSinkChannel sink = connection().getSinkChannel(); if (!sink.isWriteResumed()) { ChannelListener<ConduitStreamSinkChannel> writeListener = this.writeListener; if (writeListener == null) { writeListener = this.writeListener = new WriteListener(); } sink.getWriteSetter().set(writeListener); sink.resumeWrites(); } }
private void initiateRequest(HttpClientExchange httpClientExchange) { currentRequest = httpClientExchange; pendingResponse = new HttpResponseBuilder(); ClientRequest request = httpClientExchange.getRequest(); String connectionString = request.getRequestHeaders().getFirst(CONNECTION); if (connectionString != null) { HttpString connectionHttpString = new HttpString(connectionString); if (connectionHttpString.equals(CLOSE)) { state |= CLOSE_REQ; } else if (connectionHttpString.equals(UPGRADE)) { state |= UPGRADE_REQUESTED; } } else if (request.getProtocol() != Protocols.HTTP_1_1) { state |= CLOSE_REQ; } if (request.getRequestHeaders().contains(UPGRADE)) { state |= UPGRADE_REQUESTED; } // setup the client request conduits final ConduitStreamSourceChannel sourceChannel = connection.getSourceChannel(); sourceChannel.setReadListener(clientReadListener); sourceChannel.resumeReads(); ConduitStreamSinkChannel sinkChannel = connection.getSinkChannel(); StreamSinkConduit conduit = originalSinkConduit; conduit = new HttpRequestConduit(conduit, bufferPool, request); String fixedLengthString = request.getRequestHeaders().getFirst(CONTENT_LENGTH); String transferEncodingString = request.getRequestHeaders().getLast(TRANSFER_ENCODING); boolean hasContent = true; if (fixedLengthString != null) { try { long length = Long.parseLong(fixedLengthString); conduit = new ClientFixedLengthStreamSinkConduit(conduit, length, false, false, currentRequest); hasContent = length != 0; } catch (NumberFormatException e) { handleError(new IOException(e)); return; } } else if (transferEncodingString != null) { if (!transferEncodingString .toLowerCase(Locale.ENGLISH) .contains(Headers.CHUNKED.toString())) { handleError( UndertowClientMessages.MESSAGES.unknownTransferEncoding(transferEncodingString)); return; } conduit = new ChunkedStreamSinkConduit( conduit, httpClientExchange.getConnection().getBufferPool(), false, false, httpClientExchange.getRequest().getRequestHeaders(), requestFinishListener, httpClientExchange); } else { conduit = new ClientFixedLengthStreamSinkConduit(conduit, 0, false, false, currentRequest); hasContent = false; } sinkChannel.setConduit(conduit); httpClientExchange.invokeReadReadyCallback(httpClientExchange); if (!hasContent) { // if there is no content we flush the response channel. // otherwise it is up to the user try { sinkChannel.shutdownWrites(); if (!sinkChannel.flush()) { sinkChannel.setWriteListener( ChannelListeners.flushingChannelListener( null, new ChannelExceptionHandler<ConduitStreamSinkChannel>() { @Override public void handleException( ConduitStreamSinkChannel channel, IOException exception) { handleError(exception); } })); } } catch (IOException e) { handleError(e); } } else if (!sinkChannel.isWriteResumed()) { try { // TODO: this needs some more thought if (!sinkChannel.flush()) { sinkChannel.setWriteListener( new ChannelListener<ConduitStreamSinkChannel>() { @Override public void handleEvent(ConduitStreamSinkChannel channel) { try { if (channel.flush()) { channel.suspendWrites(); } } catch (IOException e) { handleError(e); } } }); sinkChannel.resumeWrites(); } } catch (IOException e) { handleError(e); } } }