*/
if (!channel.isOpen() || !channel.isConnected()) {
return;
}
Body body = null;
if (!future.getNettyRequest().getMethod().equals(HttpMethod.CONNECT)) {
if (future.getRequest().getBodyGenerator() != null) {
try {
body = future.getRequest().getBodyGenerator().createBody();
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
long length = body.getContentLength();
if (length >= 0) {
nettyRequest.setHeader(HttpHeaders.Names.CONTENT_LENGTH, length);
} else {
nettyRequest.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
}
} else {
body = null;
}
}
if (TransferCompletionHandler.class.isAssignableFrom(future.getAsyncHandler().getClass())) {
FluentCaseInsensitiveStringsMap h = new FluentCaseInsensitiveStringsMap();
for (String s : future.getNettyRequest().getHeaderNames()) {
for (String header : future.getNettyRequest().getHeaders(s)) {
h.add(s, header);
}
}
TransferCompletionHandler.class.cast(future.getAsyncHandler()).transferAdapter(
new NettyTransferAdapter(h, nettyRequest.getContent(), future.getRequest().getFile()));
}
// Leave it to true.
if (future.getAndSetWriteHeaders(true)) {
try {
channel.write(nettyRequest).addListener(new ProgressListener(true, future.getAsyncHandler(), future));
} catch (Throwable cause) {
log.debug(cause.getMessage(), cause);
try {
channel.close();
} catch (RuntimeException ex) {
log.debug(ex.getMessage(), ex);
}
return;
}
}
if (future.getAndSetWriteBody(true)) {
if (!future.getNettyRequest().getMethod().equals(HttpMethod.CONNECT)) {
if (future.getRequest().getFile() != null) {
final File file = future.getRequest().getFile();
long fileLength = 0;
final RandomAccessFile raf = new RandomAccessFile(file, "r");
try {
fileLength = raf.length();
ChannelFuture writeFuture;
if (channel.getPipeline().get(SslHandler.class) != null) {
writeFuture = channel.write(new ChunkedFile(raf, 0, fileLength, 8192));
} else {
final FileRegion region = new OptimizedFileRegion(raf, 0, fileLength);
writeFuture = channel.write(region);
}
writeFuture.addListener(new ProgressListener(false, future.getAsyncHandler(), future));
} catch (IOException ex) {
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
}
}
throw ex;
}
} else if (body != null || future.getRequest().getParts() != null) {
/**
* TODO: AHC-78: SSL + zero copy isn't supported by the MultiPart class and pretty complex to implements.
*/
if (future.getRequest().getParts() != null) {
String boundary = future.getNettyRequest().getHeader("Content-Type");
String length = future.getNettyRequest().getHeader("Content-Length");
body = new MultipartBody(future.getRequest().getParts(), boundary, length);
}
ChannelFuture writeFuture;
if (channel.getPipeline().get(SslHandler.class) == null && (body instanceof RandomAccessBody)) {
BodyFileRegion bodyFileRegion = new BodyFileRegion((RandomAccessBody) body);
writeFuture = channel.write(bodyFileRegion);
} else {
BodyChunkedInput bodyChunkedInput = new BodyChunkedInput(body);
writeFuture = channel.write(bodyChunkedInput);
}
final Body b = body;
writeFuture.addListener(new ProgressListener(false, future.getAsyncHandler(), future) {
public void operationComplete(ChannelFuture cf) {
try {
b.close();
} catch (IOException e) {
log.warn("Failed to close request body: {}", e.getMessage(), e);
}
super.operationComplete(cf);
}