Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.

Commit f9069da

Browse files
committed
send file/fileinputstream using "zero-copy" when possible fix jooby-project#103
1 parent 490079c commit f9069da

File tree

65 files changed

+1060
-75312
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1060
-75312
lines changed

build

Lines changed: 0 additions & 73283 deletions
This file was deleted.

coverage-report/data/elasticsearch/nodes/1/node.lock

Whitespace-only changes.

coverage-report/data/elasticsearch/nodes/2/node.lock

Whitespace-only changes.

coverage-report/src/test/java/org/jooby/AssetFeature.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public void jsAsset() throws Exception {
1515
.get("/assets/file.js")
1616
.expect(200)
1717
.header("Content-Type", "application/javascript;charset=UTF-8")
18+
.header("Content-Length", 15)
1819
.header("Last-Modified", lastModified -> {
1920
request()
2021
.get("/assets/file.js")
@@ -30,9 +31,10 @@ public void cssAsset() throws Exception {
3031
.get("/assets/file.css")
3132
.expect(200)
3233
.header("Content-Type", "text/css;charset=UTF-8")
34+
.header("Content-Length", 22)
3335
.header("Last-Modified", lastModified -> {
3436
request()
35-
.get("/assets/file.js")
37+
.get("/assets/file.css")
3638
.header("If-Modified-Since", lastModified)
3739
.expect(304)
3840
.empty();
@@ -45,6 +47,7 @@ public void imageAsset() throws Exception {
4547
.get("/assets/favicon.ico")
4648
.expect(200)
4749
.header("Content-Type", "image/x-icon")
50+
.header("Content-Length", 2238)
4851
.header("Last-Modified", lastModified -> {
4952
request()
5053
.get("/assets/favicon.ico")
@@ -54,4 +57,20 @@ public void imageAsset() throws Exception {
5457
});
5558
}
5659

60+
@Test
61+
public void emptyFile() throws Exception {
62+
request()
63+
.get("/assets/empty.css")
64+
.expect(200)
65+
.header("Content-Type", "text/css;charset=UTF-8")
66+
.header("Content-Length", 0)
67+
.header("Last-Modified", lastModified -> {
68+
request()
69+
.get("/assets/empty.css")
70+
.header("If-Modified-Since", lastModified)
71+
.expect(304)
72+
.empty();
73+
});
74+
}
75+
5776
}

coverage-report/src/test/java/org/jooby/BodyConverters.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ public class BodyConverters {
66

77
public static final Renderer toJson = (body, ctx) -> {
88
if (ctx.accepts("json")) {
9-
ctx.type(MediaType.json);
10-
ctx.text(w -> w.write("{\"body\": \"" + body + "\"}"));
9+
ctx.type(MediaType.json)
10+
.send("{\"body\": \"" + body + "\"}");
1111
}
1212
};
1313

1414
public static final Renderer toHtml = (viewable, ctx) -> {
1515
if (ctx.accepts("html")) {
16-
ctx.type(MediaType.html);
17-
ctx.text(w -> w.write("<html><body>" + viewable + "</body></html>"));
16+
ctx.type(MediaType.html)
17+
.send("<html><body>" + viewable + "</body></html>");
1818
}
1919
};
2020
}

coverage-report/src/test/java/org/jooby/BodyParamFeature.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import org.jooby.test.ServerFeature;
88
import org.junit.Test;
99

10-
import com.google.common.io.CharSink;
11-
1210
public class BodyParamFeature extends ServerFeature {
1311

1412
private static class Bean {
@@ -46,12 +44,7 @@ public Bean body(final Bean param) throws IOException {
4644

4745
renderer((object, ctx) -> {
4846
if (ctx.accepts("json") && object instanceof Bean) {
49-
ctx.text(out -> new CharSink() {
50-
@Override
51-
public java.io.Writer openStream() throws IOException {
52-
return out;
53-
}
54-
}.write(object.toString()));
47+
ctx.send(object.toString());
5548
}
5649
});
5750

coverage-report/src/test/java/org/jooby/BufferSizeFeature.java

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package org.jooby;
22

3+
import java.io.ByteArrayInputStream;
34
import java.util.Optional;
45

56
import org.jooby.test.ServerFeature;
6-
import org.junit.Before;
77
import org.junit.Test;
88

99
import com.google.common.base.Charsets;
@@ -22,30 +22,17 @@ public class BufferSizeFeature extends ServerFeature {
2222
String value = req.param("data").value();
2323
Optional<Long> len = req.param("len").toOptional(Long.class);
2424
Optional<Boolean> chunked = req.param("chunked").toOptional(Boolean.class);
25-
Result rsp = Results.ok(value);
25+
Result result = Results.ok(value);
26+
if (!req.param("short").toOptional().isPresent()) {
27+
result = Results.ok(new ByteArrayInputStream(value.getBytes(req.charset())));
28+
}
29+
Result rsp = result;
2630
len.ifPresent(l -> rsp.header("Content-Length", l));
2731
chunked.ifPresent(c -> rsp.header("Transfer-Encoding", "Chunked"));
2832
return rsp;
2933
});
3034
}
3135

32-
@Before
33-
public void debug() {
34-
java.util.logging.Logger.getLogger("httpclient.wire.header").setLevel(
35-
java.util.logging.Level.FINEST);
36-
37-
java.util.logging.Logger.getLogger("httpclient.wire.content").setLevel(
38-
java.util.logging.Level.FINEST);
39-
40-
System.setProperty("org.apache.commons.logging.Log",
41-
"org.apache.commons.logging.impl.SimpleLog");
42-
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
43-
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
44-
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug");
45-
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers",
46-
"debug");
47-
}
48-
4936
@Test
5037
public void largeResponsesFallbackToTransferEncodingChunked() throws Exception {
5138
String data = rnd(len);
@@ -82,7 +69,7 @@ public void largeResponsesWithTransferEncodingMustBeKept() throws Exception {
8269
@Test
8370
public void shortResponseShouldGuessContentLength() throws Exception {
8471
request()
85-
.get("/?data=hello")
72+
.get("/?data=hello&short=yes")
8673
.expect("hello")
8774
.header("Content-Length", "5")
8875
.header("Connection", Optional.of("keep-alive"));
@@ -101,7 +88,7 @@ public void shortResponseShouldKeepContentLength() throws Exception {
10188
public void shortResponseShouldPreferContentLengthEvenIfTransferEncodingChunkWasSet()
10289
throws Exception {
10390
request()
104-
.get("/?data=hello&chunked=true")
91+
.get("/?data=hello&chunked=true&short=yes")
10592
.expect("hello")
10693
.header("Content-Length", "5")
10794
.header("Connection", Optional.of("keep-alive"));
@@ -123,4 +110,3 @@ private int len(final String data) {
123110
return data.getBytes(Charsets.UTF_8).length;
124111
}
125112
}
126-

coverage-report/src/test/java/org/jooby/BuiltinParserFormatterFeature.java

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.jooby;
22

33
import java.io.ByteArrayInputStream;
4-
import java.io.StringReader;
54
import java.nio.ByteBuffer;
65

76
import org.jooby.test.ServerFeature;
@@ -17,10 +16,9 @@ public class BuiltinParserFormatterFeature extends ServerFeature {
1716
get("/direct-buffer", () -> {
1817
ByteBuffer buffer = ByteBuffer.allocateDirect("direct-buffer".length());
1918
buffer.put("direct-buffer".getBytes());
19+
buffer.flip();
2020
return buffer;
2121
});
22-
23-
get("/reader", () -> new StringReader("reader"));
2422
}
2523

2624
@Test
@@ -53,15 +51,4 @@ public void directBuffer() throws Exception {
5351
.header("Content-Type", "application/octet-stream");
5452
}
5553

56-
@Test
57-
public void reader() throws Exception {
58-
request()
59-
.get("/reader")
60-
.expect(200)
61-
.expect("reader")
62-
.header("Content-Length", "6")
63-
.header("Content-Type", "text/html;charset=UTF-8");
64-
65-
}
66-
6754
}

coverage-report/src/test/java/org/jooby/DownloadFeature.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package org.jooby;
22

33
import java.io.File;
4-
import java.io.FileInputStream;
5-
import java.io.FileReader;
64

75
import org.jooby.test.ServerFeature;
86
import org.junit.Test;
@@ -11,22 +9,22 @@ public class DownloadFeature extends ServerFeature {
119

1210
{
1311
get("/download-reader", (req, rsp) -> rsp.download("name.js",
14-
new FileReader(new File("src/test/resources/"
15-
+ DownloadFeature.class.getName().replace('.', '/') + ".js"))));
12+
new File("src/test/resources/"
13+
+ DownloadFeature.class.getName().replace('.', '/') + ".js")));
1614

1715
get("/customtype", (req, rsp) -> {
1816
rsp.type(req.param("type").value()).download("/name.json",
19-
new FileReader(new File("src/test/resources/"
20-
+ DownloadFeature.class.getName().replace('.', '/') + ".json")));
17+
new File("src/test/resources/"
18+
+ DownloadFeature.class.getName().replace('.', '/') + ".json"));
2119
});
2220

2321
get("/location", (req, rsp) -> rsp.download("name", req.param("file").value()));
2422

2523
get("/fs", (req, rsp) -> rsp.download(new File(req.param("file").value())));
2624

2725
get("/favicon.ico", (req, rsp) -> rsp.download("favicon.ico",
28-
new FileInputStream(new File("src/test/resources/"
29-
+ DownloadFeature.class.getName().replace('.', '/') + ".ico"))));
26+
new File("src/test/resources/"
27+
+ DownloadFeature.class.getName().replace('.', '/') + ".ico")));
3028
}
3129

3230
@Test

coverage-report/src/test/java/org/jooby/HandlersFeature.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public Object get(final Request req) {
4242

4343
renderer((object, ctx) -> {
4444
if (ctx.accepts("text/plain")) {
45-
ctx.text(w -> w.write(object.toString()));
45+
ctx.send(object.toString());
4646
}
4747
});
4848
get("/id", "/id/:id", req ->

0 commit comments

Comments
 (0)