英文:
Netty 4.1.51.Final has a bug in Http File Upload
问题
以下是翻译好的代码部分:
package com.cauliflower.netty.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.*;
import io.netty.util.ReferenceCountUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
public class HttpUploadHandler extends SimpleChannelInboundHandler<HttpObject> {
public HttpUploadHandler() {
super(false);
}
private static final HttpDataFactory factory = new DefaultHttpDataFactory(true);
private static final String FILE_UPLOAD = "/home/joker/Desktop/";
private static final String URI = "/upload";
private HttpPostRequestDecoder httpDecoder;
HttpRequest request;
@Override
protected void channelRead0(final ChannelHandlerContext ctx, final HttpObject httpObject)
throws Exception {
if (httpObject instanceof HttpRequest) {
request = (HttpRequest) httpObject;
if (request.method().equals(HttpMethod.POST)) {
httpDecoder = new HttpPostRequestDecoder(factory, request);
httpDecoder.setDiscardThreshold(0);
} else {
ctx.fireChannelRead(httpObject);
}
}
if (httpObject instanceof HttpContent) {
if (httpDecoder != null) {
final HttpContent chunk = (HttpContent) httpObject;
httpDecoder.offer(chunk);
if (chunk instanceof LastHttpContent) {
writeChunk(ctx);
httpDecoder.destroy();
httpDecoder = null;
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
ByteBuf byteBuf = Unpooled.copiedBuffer("0".getBytes(StandardCharsets.UTF_8));
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
ctx.write(response);
ctx.write(byteBuf);
ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
}
ReferenceCountUtil.release(httpObject);
} else {
ctx.fireChannelRead(httpObject);
}
}
}
private void writeChunk(ChannelHandlerContext ctx) throws IOException {
while (httpDecoder.hasNext()) {
InterfaceHttpData data = httpDecoder.next();
if (data != null && InterfaceHttpData.HttpDataType.FileUpload.equals(data.getHttpDataType())) {
final FileUpload fileUpload = (FileUpload) data;
final File file = new File(FILE_UPLOAD + fileUpload.getFilename());
try (FileChannel inputChannel = new FileInputStream(fileUpload.getFile()).getChannel();
FileChannel outputChannel = new FileOutputStream(file).getChannel()) {
System.out.println(inputChannel.size());
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
}
}
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (httpDecoder != null) {
httpDecoder.cleanFiles();
}
}
}
英文:
Netty 4.1.51.Final has a bug in Http File Upload.
When I use HttpPostRequestDecoder to receive file uploaded but only get an incomplete file. The method offer() may not put segmented file body into one file because I test the Sum of bytes is true but inputChannel.size() is false.
If change the version to Netty 4.1.49.Final, everything is OK!
Here is my code:
package com.cauliflower.netty.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.*;
import io.netty.util.ReferenceCountUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
public class HttpUploadHandler extends SimpleChannelInboundHandler<HttpObject> {
public HttpUploadHandler() {
super(false);
}
private static final HttpDataFactory factory = new DefaultHttpDataFactory(true);
private static final String FILE_UPLOAD = "/home/joker/Desktop/";
private static final String URI = "/upload";
private HttpPostRequestDecoder httpDecoder;
HttpRequest request;
@Override
protected void channelRead0(final ChannelHandlerContext ctx, final HttpObject httpObject)
throws Exception {
if (httpObject instanceof HttpRequest) {
request = (HttpRequest) httpObject;
if (request.method().equals(HttpMethod.POST)) {
httpDecoder = new HttpPostRequestDecoder(factory, request);
httpDecoder.setDiscardThreshold(0);
} else {
ctx.fireChannelRead(httpObject);
}
}
if (httpObject instanceof HttpContent) {
if (httpDecoder != null) {
final HttpContent chunk = (HttpContent) httpObject;
httpDecoder.offer(chunk);
if (chunk instanceof LastHttpContent) {
writeChunk(ctx);
httpDecoder.destroy();
httpDecoder = null;
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
ByteBuf byteBuf = Unpooled.copiedBuffer("0".getBytes(StandardCharsets.UTF_8));
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, byteBuf.readableBytes());
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
ctx.write(response);
ctx.write(byteBuf);
ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
}
ReferenceCountUtil.release(httpObject);
} else {
ctx.fireChannelRead(httpObject);
}
}
}
private void writeChunk(ChannelHandlerContext ctx) throws IOException {
while (httpDecoder.hasNext()) {
InterfaceHttpData data = httpDecoder.next();
if (data != null && InterfaceHttpData.HttpDataType.FileUpload.equals(data.getHttpDataType())) {
final FileUpload fileUpload = (FileUpload) data;
final File file = new File(FILE_UPLOAD + fileUpload.getFilename());
try (FileChannel inputChannel = new FileInputStream(fileUpload.getFile()).getChannel();
FileChannel outputChannel = new FileOutputStream(file).getChannel()) {
System.out.println(inputChannel.size());
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
}
}
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (httpDecoder != null) {
httpDecoder.cleanFiles();
}
}
}
答案1
得分: 0
是的,这是一个错误~ 4.1.52版本已经修复...
问题链接
英文:
yes,it's a bug ~ 4.1.52 already fixed...
issues
专注分享java语言的经验与见解,让所有开发者获益!
评论