Skip to content

Commit 74100d2

Browse files
committed
test: 新增针对issue13的http反向代理的单元测试。http1.1与http2的content-length和chunked请求体
(cherry picked from commit 7810bf8)
1 parent eb94cf6 commit 74100d2

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package top.meethigher.proxy.http;
2+
3+
import io.vertx.core.Vertx;
4+
import io.vertx.core.http.*;
5+
import io.vertx.ext.web.Router;
6+
import org.junit.Test;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import java.util.ArrayList;
11+
import java.util.Arrays;
12+
import java.util.Collections;
13+
import java.util.concurrent.locks.LockSupport;
14+
15+
public class Issue13Test {
16+
17+
private static final Vertx vertx = Vertx.vertx();
18+
private static final Logger log = LoggerFactory.getLogger(Issue13Test.class);
19+
20+
@Test
21+
public void name() {
22+
23+
HttpServerOptions httpServerOptions = new HttpServerOptions()
24+
// 服务端支持与客户端进行协商,支持通过alpn用于协商客户端和服务端使用http1.1还是http2
25+
// 开启h2c,使其支持http2,默认情况下http2只在开启了tls使用。如果不开启tls还想使用http2,那么需要开启h2c
26+
// alpn基于tls,若未开启tls,则不支持alpn
27+
.setAlpnVersions(Collections.unmodifiableList(Arrays.asList(HttpVersion.HTTP_1_1, HttpVersion.HTTP_2)))
28+
.setUseAlpn(true)
29+
.setHttp2ClearTextEnabled(true);
30+
HttpServer server = vertx.createHttpServer(httpServerOptions);
31+
32+
HttpClientOptions httpClientOptions = new HttpClientOptions()
33+
// 设置客户端默认使用的HTTP协议版本是http1.1,并且开启alpn支持协商http1.1和http2
34+
// alpn基于tls,若对方没有开启tls,则不支持alpn
35+
.setProtocolVersion(HttpVersion.HTTP_1_1)
36+
.setUseAlpn(true)
37+
.setAlpnVersions(new ArrayList<HttpVersion>() {{
38+
add(HttpVersion.HTTP_1_1);
39+
add(HttpVersion.HTTP_2);
40+
}});
41+
HttpClient client = vertx.createHttpClient(httpClientOptions);
42+
43+
ReverseHttpProxy.create(Router.router(vertx), server, client)
44+
.port(18088)
45+
.addRoute(new ProxyRoute()
46+
.setName("proxy")
47+
.setTargetUrl("http://127.0.0.1:18080")
48+
.setSourceUrl("/*"))
49+
.start();
50+
51+
52+
RequestOptions requestOptions = new RequestOptions()
53+
.setAbsoluteURI("http://127.0.0.1:18088/test")
54+
.setMethod(HttpMethod.POST);
55+
56+
String body = "halo wode";
57+
58+
// 发送http1.1的content-length请求体
59+
vertx.setTimer(4000, id -> {
60+
HttpClient httpClient = vertx.createHttpClient(new HttpClientOptions().setProtocolVersion(HttpVersion.HTTP_1_1));
61+
httpClient.request(requestOptions).onSuccess(req -> {
62+
req.send(body).onSuccess(resp -> {
63+
resp.bodyHandler(buf -> {
64+
log.info("{} content-length received:\n{}", resp.version(), buf.toString());
65+
});
66+
});
67+
});
68+
});
69+
// 发送http1.1的transfer-encoding:chunked请求体
70+
vertx.setTimer(5000, id -> {
71+
HttpClient httpClient = vertx.createHttpClient(new HttpClientOptions().setProtocolVersion(HttpVersion.HTTP_1_1));
72+
httpClient.request(requestOptions).onSuccess(req -> {
73+
req.setChunked(true);
74+
req.send(body).onSuccess(resp -> {
75+
resp.bodyHandler(buf -> {
76+
log.info("{} transfer-encoding received:\n{}", resp.version(), buf.toString());
77+
});
78+
});
79+
});
80+
});
81+
82+
// 发送http2的content-length请求体
83+
vertx.setTimer(6000, id -> {
84+
HttpClient httpClient = vertx.createHttpClient(new HttpClientOptions().setProtocolVersion(HttpVersion.HTTP_2));
85+
httpClient.request(requestOptions).onSuccess(req -> {
86+
req.send(body).onSuccess(resp -> {
87+
resp.bodyHandler(buf -> {
88+
log.info("{} content-length received:\n{}", resp.version(), buf.toString());
89+
});
90+
});
91+
});
92+
});
93+
94+
//发送http2的transfer-encoding:chunked请求体
95+
vertx.setTimer(7000, id -> {
96+
HttpClient httpClient = vertx.createHttpClient(new HttpClientOptions().setProtocolVersion(HttpVersion.HTTP_2));
97+
httpClient.request(requestOptions).onSuccess(req -> {
98+
req.setChunked(true);
99+
req.send(body).onSuccess(resp -> {
100+
resp.bodyHandler(buf -> {
101+
log.info("{} transfer-encoding received:\n{}", resp.version(), buf.toString());
102+
});
103+
});
104+
});
105+
});
106+
107+
LockSupport.park();
108+
}
109+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package top.meethigher.proxy.http.issue13;
2+
3+
import io.vertx.core.Vertx;
4+
import io.vertx.core.http.HttpServer;
5+
import io.vertx.core.http.HttpServerOptions;
6+
import io.vertx.core.http.HttpVersion;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
10+
import java.util.Arrays;
11+
import java.util.Collections;
12+
import java.util.concurrent.locks.LockSupport;
13+
14+
public class Issue13SimpleHttpServer {
15+
private static final Logger log = LoggerFactory.getLogger(Issue13SimpleHttpServer.class);
16+
17+
public static void main(String[] args) {
18+
Vertx vertx = Vertx.vertx();
19+
20+
21+
HttpServerOptions httpServerOptions = new HttpServerOptions()
22+
// 服务端支持与客户端进行协商,支持通过alpn用于协商客户端和服务端使用http1.1还是http2
23+
// 开启h2c,使其支持http2,默认情况下http2只在开启了tls使用。如果不开启tls还想使用http2,那么需要开启h2c
24+
// alpn基于tls,若未开启tls,则不支持alpn
25+
.setAlpnVersions(Collections.unmodifiableList(Arrays.asList(HttpVersion.HTTP_1_1, HttpVersion.HTTP_2)))
26+
.setUseAlpn(true)
27+
.setHttp2ClearTextEnabled(true);
28+
29+
HttpServer httpServer = vertx.createHttpServer();
30+
httpServer.requestHandler(req -> {
31+
req.pause();
32+
long id = vertx.setTimer(5000, t -> {
33+
req.response().setStatusCode(400).end("body not exist");
34+
});
35+
req.response().setChunked(true);
36+
req.response().write("\nrequest headers:\n");
37+
for (String key : req.headers().names()) {
38+
req.response().write(key + ":" + req.headers().get(key) + "\n");
39+
}
40+
req.response().write("\nrequest body:\n");
41+
req.bodyHandler(buf -> {
42+
vertx.cancelTimer(id);
43+
log.info("received:\n{}", buf.toString());
44+
req.response().end(buf);
45+
});
46+
req.resume();
47+
});
48+
httpServer.listen(18080).onFailure(e -> {
49+
System.exit(1);
50+
});
51+
52+
LockSupport.park();
53+
}
54+
}

0 commit comments

Comments
 (0)