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

Commit 713672e

Browse files
committed
Netty fix while sending chunk on the same context (Last content was missing)
* add a few more webjars tests
1 parent 546e40c commit 713672e

12 files changed

Lines changed: 196 additions & 55 deletions

File tree

coverage-report/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,18 @@
225225
<version>${project.version}</version>
226226
</dependency>
227227

228+
<dependency>
229+
<groupId>org.webjars</groupId>
230+
<artifactId>jquery</artifactId>
231+
<version>2.1.3</version>
232+
</dependency>
233+
234+
<dependency>
235+
<groupId>org.webjars</groupId>
236+
<artifactId>bootstrap</artifactId>
237+
<version>3.3.4</version>
238+
</dependency>
239+
228240
<!-- Servers -->
229241
<dependency>
230242
<groupId>org.jooby</groupId>

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ public class AssetLocationFeature extends ServerFeature {
88
{
99
assets("/", "welcome.html");
1010

11-
assets("/js/lib/*-*.js", "/resources/webjars/{0}/{1}/{0}.js");
11+
assets("/js/lib/*-*.js", "/META-INF/resources/webjars/{0}/{1}/{0}.js");
1212

13-
assets("/js/**", "/resources/webjars/{0}");
13+
assets("/js/**", "/META-INF/resources/webjars/{0}");
1414

1515
}
1616

@@ -34,15 +34,24 @@ public void webjars() throws Exception {
3434
request()
3535
.get("/js/jquery/2.1.3/jquery.js")
3636
.expect(200)
37-
.header("Content-Type", "application/javascript;charset=UTF-8");
37+
.header("Content-Type", "application/javascript;charset=UTF-8")
38+
.header("Content-Length", "247387");
39+
40+
request()
41+
.get("/js/jquery/2.1.3/jquery.min.js")
42+
.expect(200)
43+
.header("Content-Type", "application/javascript;charset=UTF-8")
44+
.header("Content-Length", "84355");
3845
}
3946

4047
@Test
4148
public void webjarsMapping() throws Exception {
4249
request()
4350
.get("/js/lib/jquery-2.1.3.js")
4451
.expect(200)
45-
.header("Content-Type", "application/javascript;charset=UTF-8");
52+
.header("Content-Type", "application/javascript;charset=UTF-8")
53+
.header("Content-Length", "247387");
54+
4655
}
4756

4857
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class AssetResolveNextFeature extends ServerFeature {
88
{
99
assets("/assets/**", "/");
1010

11-
assets("/assets/js/*-*.js", "/resources/webjars/{0}/{1}/{0}.js");
11+
assets("/assets/js/*-*.js", "/META-INF/resources/webjars/{0}/{1}/{0}.js");
1212
}
1313

1414
@Test
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.jooby;
2+
3+
import org.jooby.test.ServerFeature;
4+
import org.junit.Test;
5+
6+
public class WebJarFeature extends ServerFeature {
7+
8+
{
9+
assets("/webjars/**", "/META-INF/resources/webjars/{0}");
10+
11+
}
12+
13+
@Test
14+
public void jquery() throws Exception {
15+
request()
16+
.get("/webjars/jquery/2.1.3/jquery.js")
17+
.expect(200)
18+
.header("Content-Type", "application/javascript;charset=UTF-8")
19+
.header("Content-Length", 247387);
20+
21+
request()
22+
.get("/webjars/jquery/2.1.3/jquery.min.js")
23+
.expect(200)
24+
.header("Content-Type", "application/javascript;charset=UTF-8")
25+
.header("Content-Length", 84355);
26+
27+
request()
28+
.get("/webjars/jquery/2.1.3/jquery.min.map")
29+
.expect(200)
30+
.header("Content-Type", "text/plain;charset=UTF-8")
31+
.header("Content-Length", 127542);
32+
}
33+
34+
@Test
35+
public void bootstrap() throws Exception {
36+
request()
37+
.get("/webjars/bootstrap/3.3.4/js/bootstrap.js")
38+
.expect(200)
39+
.header("Content-Type", "application/javascript;charset=UTF-8")
40+
.header("Content-Length", 67546);
41+
42+
request()
43+
.get("/webjars/bootstrap/3.3.4/css/bootstrap.css")
44+
.expect(200)
45+
.header("Content-Type", "text/css;charset=UTF-8")
46+
.header("Content-Length", 141622);
47+
}
48+
}

coverage-report/src/test/resources/resources/webjars/jquery/2.1.3/jquery.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

jooby-netty/src/main/java/org/jooby/internal/netty/NettyHandler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
3030
import io.netty.handler.timeout.IdleStateEvent;
3131
import io.netty.util.Attribute;
32+
import io.netty.util.AttributeKey;
3233

3334
import org.jooby.spi.HttpHandler;
3435
import org.slf4j.Logger;
@@ -41,6 +42,9 @@ public class NettyHandler extends SimpleChannelInboundHandler<Object> {
4142
/** The logging system. */
4243
private final Logger log = LoggerFactory.getLogger(getClass());
4344

45+
public static final AttributeKey<String> PATH =
46+
new AttributeKey<String>(NettyHandler.class.getName());
47+
4448
private HttpHandler handler;
4549

4650
private String tmpdir;
@@ -66,10 +70,12 @@ public void channelReadComplete(final ChannelHandlerContext ctx) {
6670
public void channelRead0(final ChannelHandlerContext ctx, final Object msg) {
6771
if (msg instanceof FullHttpRequest) {
6872
FullHttpRequest req = (FullHttpRequest) msg;
73+
ctx.attr(PATH).set(req.getMethod().name() + " " + req.getUri());
6974

7075
if (HttpHeaders.is100ContinueExpected(req)) {
7176
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.CONTINUE));
7277
}
78+
7379
boolean keepAlive = HttpHeaders.isKeepAlive(req);
7480

7581
try {
@@ -91,7 +97,7 @@ public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cau
9197
if (ws != null && ws.get() != null) {
9298
ws.get().handle(cause);
9399
} else {
94-
log.error("execution of: " + ctx + " resulted in error", cause);
100+
log.error("execution of: " + ctx.attr(PATH).get() + " resulted in error", cause);
95101
}
96102
} finally {
97103
ctx.close();

jooby-netty/src/main/java/org/jooby/internal/netty/NettyOutputStream.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
*/
1919
package org.jooby.internal.netty;
2020

21+
import static io.netty.channel.ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE;
2122
import io.netty.buffer.ByteBuf;
23+
import io.netty.channel.ChannelFuture;
2224
import io.netty.channel.ChannelFutureListener;
2325
import io.netty.channel.ChannelHandlerContext;
2426
import io.netty.handler.codec.http.DefaultFullHttpResponse;
@@ -93,10 +95,15 @@ public void close() throws IOException {
9395
try {
9496
flush();
9597
} finally {
96-
if (!headers.contains(HttpHeaders.Names.CONTENT_LENGTH)) {
97-
// close chunked responses
98-
ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)
99-
.addListener(ChannelFutureListener.CLOSE);
98+
if (chunkState > 0) {
99+
ChannelFuture future = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)
100+
.addListener(FIRE_EXCEPTION_ON_FAILURE);
101+
/**
102+
* no Keep alive?
103+
*/
104+
if (!keepAlive || !headers.contains(HttpHeaders.Names.CONTENT_LENGTH)) {
105+
future.addListener(ChannelFutureListener.CLOSE);
106+
}
100107
}
101108
}
102109
}
@@ -150,11 +157,11 @@ public void flush() throws IOException {
150157
// send keep alive and don't close the channel
151158
headers.set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
152159
rsp.headers().set(headers);
153-
ctx.writeAndFlush(rsp);
160+
ctx.writeAndFlush(rsp).addListener(FIRE_EXCEPTION_ON_FAILURE);
154161
} else {
155162
// don't send keep alive and close the channel.
156163
rsp.headers().set(headers);
157-
ctx.writeAndFlush(rsp).addListener(ChannelFutureListener.CLOSE);
164+
ctx.writeAndFlush(rsp).addListener(FIRE_EXCEPTION_ON_FAILURE);
158165
}
159166
return;
160167
}
@@ -179,12 +186,13 @@ public void flush() throws IOException {
179186
// dump headers
180187
rsp.headers().set(headers);
181188
// send headers
182-
ctx.write(rsp);
189+
ctx.write(rsp).addListener(FIRE_EXCEPTION_ON_FAILURE);
183190
}
184191
/**
185192
* Write chunk and clear the buffer.
186193
*/
187-
ctx.writeAndFlush(new DefaultHttpContent(buffer.copy()));
194+
ctx.writeAndFlush(new DefaultHttpContent(buffer.copy()))
195+
.addListener(FIRE_EXCEPTION_ON_FAILURE);
188196
buffer.clear();
189197
}
190198

0 commit comments

Comments
 (0)