Skip to content
This repository was archived by the owner on Dec 12, 2022. It is now read-only.

Commit 8d31917

Browse files
committed
The HttpUpload example *almost* works
There are some weird off-by-one artefacts where ASCII period and newline character bytes switch places. This needs more investigation.
1 parent 6023897 commit 8d31917

File tree

6 files changed

+1610
-0
lines changed

6 files changed

+1610
-0
lines changed

src/test/java/io/netty/buffer/api/examples/http/upload/HttpUploadClient.java

Lines changed: 904 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2021 The Netty Project
3+
*
4+
* The Netty Project licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
package io.netty.buffer.api.examples.http.upload;
17+
18+
import io.netty.channel.ChannelHandlerContext;
19+
import io.netty.channel.SimpleChannelInboundHandler;
20+
import io.netty.handler.codec.http.HttpContent;
21+
import io.netty.handler.codec.http.HttpObject;
22+
import io.netty.handler.codec.http.HttpResponse;
23+
import io.netty.handler.codec.http.HttpUtil;
24+
import io.netty.handler.codec.http.LastHttpContent;
25+
import io.netty.util.CharsetUtil;
26+
27+
/**
28+
* Handler that just dumps the contents of the response from the server
29+
*/
30+
public class HttpUploadClientHandler extends SimpleChannelInboundHandler<HttpObject> {
31+
32+
private boolean readingChunks;
33+
34+
@Override
35+
public void messageReceived(ChannelHandlerContext ctx, HttpObject msg) {
36+
if (msg instanceof HttpResponse) {
37+
HttpResponse response = (HttpResponse) msg;
38+
39+
System.err.println("STATUS: " + response.status());
40+
System.err.println("VERSION: " + response.protocolVersion());
41+
42+
if (!response.headers().isEmpty()) {
43+
for (CharSequence name : response.headers().names()) {
44+
for (CharSequence value : response.headers().getAll(name)) {
45+
System.err.println("HEADER: " + name + " = " + value);
46+
}
47+
}
48+
}
49+
50+
if (response.status().code() == 200 && HttpUtil.isTransferEncodingChunked(response)) {
51+
readingChunks = true;
52+
System.err.println("CHUNKED CONTENT {");
53+
} else {
54+
System.err.println("CONTENT {");
55+
}
56+
}
57+
if (msg instanceof HttpContent) {
58+
HttpContent chunk = (HttpContent) msg;
59+
System.err.println(chunk.content().toString(CharsetUtil.UTF_8));
60+
61+
if (chunk instanceof LastHttpContent) {
62+
if (readingChunks) {
63+
System.err.println("} END OF CHUNKED CONTENT");
64+
} else {
65+
System.err.println("} END OF CONTENT");
66+
}
67+
readingChunks = false;
68+
} else {
69+
System.err.println(chunk.content().toString(CharsetUtil.UTF_8));
70+
}
71+
}
72+
}
73+
74+
@Override
75+
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
76+
cause.printStackTrace();
77+
ctx.channel().close();
78+
}
79+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2021 The Netty Project
3+
*
4+
* The Netty Project licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
package io.netty.buffer.api.examples.http.upload;
17+
18+
import io.netty.channel.ChannelInitializer;
19+
import io.netty.channel.ChannelPipeline;
20+
import io.netty.channel.socket.SocketChannel;
21+
import io.netty.handler.codec.http.HttpClientCodec;
22+
import io.netty.handler.codec.http.HttpContentDecompressor;
23+
import io.netty.handler.ssl.SslContext;
24+
import io.netty.handler.stream.ChunkedWriteHandler;
25+
26+
public class HttpUploadClientInitializer extends ChannelInitializer<SocketChannel> {
27+
28+
private final SslContext sslCtx;
29+
30+
public HttpUploadClientInitializer(SslContext sslCtx) {
31+
this.sslCtx = sslCtx;
32+
}
33+
34+
@Override
35+
public void initChannel(SocketChannel ch) {
36+
ChannelPipeline pipeline = ch.pipeline();
37+
38+
if (sslCtx != null) {
39+
pipeline.addLast("ssl", sslCtx.newHandler(ch.alloc()));
40+
}
41+
42+
pipeline.addLast("codec", new HttpClientCodec());
43+
44+
// Remove the following line if you don't want automatic content decompression.
45+
pipeline.addLast("inflater", new HttpContentDecompressor());
46+
47+
// to be used since huge file transfer
48+
pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
49+
50+
pipeline.addLast("handler", new HttpUploadClientHandler());
51+
}
52+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2021 The Netty Project
3+
*
4+
* The Netty Project licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
package io.netty.buffer.api.examples.http.upload;
17+
18+
import io.netty.bootstrap.ServerBootstrap;
19+
import io.netty.buffer.api.adaptor.ByteBufAllocatorAdaptor;
20+
import io.netty.channel.Channel;
21+
import io.netty.channel.ChannelOption;
22+
import io.netty.channel.EventLoopGroup;
23+
import io.netty.channel.MultithreadEventLoopGroup;
24+
import io.netty.channel.nio.NioHandler;
25+
import io.netty.channel.socket.nio.NioServerSocketChannel;
26+
import io.netty.handler.logging.LogLevel;
27+
import io.netty.handler.logging.LoggingHandler;
28+
import io.netty.handler.ssl.SslContext;
29+
import io.netty.handler.ssl.SslContextBuilder;
30+
import io.netty.handler.ssl.util.SelfSignedCertificate;
31+
32+
/**
33+
* An HTTP server showing how to use the HTTP multipart package for file uploads and decoding post data.
34+
*/
35+
public final class HttpUploadServer {
36+
37+
static final boolean SSL = System.getProperty("ssl") != null;
38+
static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8443" : "8080"));
39+
40+
public static void main(String[] args) throws Exception {
41+
// Configure SSL.
42+
final SslContext sslCtx;
43+
if (SSL) {
44+
SelfSignedCertificate ssc = new SelfSignedCertificate();
45+
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
46+
} else {
47+
sslCtx = null;
48+
}
49+
50+
ByteBufAllocatorAdaptor allocator = new ByteBufAllocatorAdaptor();
51+
EventLoopGroup bossGroup = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
52+
EventLoopGroup workerGroup = new MultithreadEventLoopGroup(NioHandler.newFactory());
53+
try {
54+
ServerBootstrap b = new ServerBootstrap();
55+
b.group(bossGroup, workerGroup);
56+
b.channel(NioServerSocketChannel.class);
57+
b.childOption(ChannelOption.ALLOCATOR, allocator);
58+
b.handler(new LoggingHandler(LogLevel.INFO));
59+
b.childHandler(new HttpUploadServerInitializer(sslCtx));
60+
61+
Channel ch = b.bind(PORT).sync().channel();
62+
63+
System.err.println("Open your web browser and navigate to " +
64+
(SSL? "https" : "http") + "://127.0.0.1:" + PORT + '/');
65+
66+
ch.closeFuture().sync();
67+
} finally {
68+
bossGroup.shutdownGracefully();
69+
workerGroup.shutdownGracefully();
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)