我試圖圍繞Netty 4實現一個HTTP服務器,當總數據大小未知時使用分塊傳輸編碼來服務HttpResponses主體。作爲一個起點,我只是簡單地將HttpStaticFileServerHandler(在https://github.com/netty/netty/tree/netty-4.0.0.CR1/example/src/main/java/io/netty/example/http/file中找到)改爲使用ChunkedStream而不是ChunkedFile(它們都是ChunkedByteInputs)。更改Netty 4 HTTP文件服務器示例以使用ChunkedStream而不是ChunkedFile
據我所知,它在原始示例用例中使用FileInputStream並不理想,但我認爲它是重用已知代碼的一個好例子。
所以,這裏距離io.netty.example.http.file包(與4.0.0.CR1)對HttpStaticFileServerHandler類DIFF:
diff --git a/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java b/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java
index 904579b..0d3592f 100644
--- a/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java
+++ b/example/src/main/java/io/netty/example/http/file/HttpStaticFileServerHandler.java
@@ -27,13 +27,14 @@ import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
-import io.netty.handler.stream.ChunkedFile;
+import io.netty.handler.stream.ChunkedStream;
import io.netty.util.CharsetUtil;
import javax.activation.MimetypesFileTypeMap;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.RandomAccessFile;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
@@ -159,17 +160,15 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda
}
}
- RandomAccessFile raf;
+ InputStream raf; // Use an InputStream instead of a RandomAccessFile
try {
- raf = new RandomAccessFile(file, "r");
+ raf = new FileInputStream(file);
} catch (FileNotFoundException fnfe) {
sendError(ctx, NOT_FOUND);
return;
}
- long fileLength = raf.length();
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
- setContentLength(response, fileLength);
setContentTypeHeader(response, file);
setDateAndCacheHeaders(response, file);
if (isKeepAlive(request)) {
@@ -180,7 +179,7 @@ public class HttpStaticFileServerHandler extends ChannelInboundMessageHandlerAda
ctx.write(response);
// Write the content.
- ChannelFuture writeFuture = ctx.write(new ChunkedFile(raf, 0, fileLength, 8192));
+ ChannelFuture writeFuture = ctx.write(new ChunkedStream(raf)); // Use a ChunkedStream instead of a ChunkedFile
// Decide whether to close the connection or not.
if (!isKeepAlive(request)) {
這裏完整的更改的文件: https://gist.github.com/eskatos/5311587
更改最小化:使用FileInputStream而不是使用RandomAccessFile和ChunkedStream而不是ChunkedFile。管道未觸及。
要重現,只需將更改應用到Netty示例,運行它並嘗試下載任何文件。
在此更改之後,目錄列表顯然起作用,因爲響應沒有被分塊,但文件下載沒有。客戶端下載文件,但永遠不會完成下載,保持連接並永遠等待。我已經嘗試了幾個來自瀏覽器的curl,wget等等。我還試圖在管道中添加一個ByteLoggingHandler,並且我可以看到一個空的尾部塊,所以我不明白瀏覽器爲什麼仍在等待數據。
任何線索?
我們最近添加了一個'ChunkedInput'實現專用於此:https:// github。com/netty/netty/blob/master/codec -http/src/main/java/io/netty/handler/codec/http/HttpChunkedInput.java – trustin 2014-01-19 13:38:18
很好看:正如我剛纔所做的那樣,內容壓縮問題:http://andreas.haufler.info/2014/01/making-http-content-compression-work-in.html。也許你們也可以改進HttpContentCompressor(不壓縮JPEG,ZIP等或小文件......)我會很樂意提供一個請求... – 2014-01-21 21:25:44
當然!讓我期待您的拉動請求/功能建議等。 – trustin 2014-01-22 06:29:19