Skip to content

Commit 1b64e92

Browse files
NilsRenaudvietj
authored andcommitted
5553 permits access to :authority HTTP/2 pseudo header value
And fix the `HttpServerRequest#autority()` javadoc, which was incorrect. And have a single source of authority truth between the Http2ServerStream and Http2ServerRequest (cherry picked from commit 532e428)
1 parent fb7797d commit 1b64e92

File tree

8 files changed

+72
-36
lines changed

8 files changed

+72
-36
lines changed

vertx-core/src/main/java/io/vertx/core/http/HttpServerRequest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,26 @@ default boolean isSSL() {
117117
String scheme();
118118

119119
/**
120-
* @return the request authority. For HTTP/2 the {@literal :authority} pseudo header is returned, for HTTP/1.x the
121-
* {@literal Host} header is returned or {@code null} when no such header is present. When the authority
122-
* string does not carry a port, the {@link HostAndPort#port()} returns {@code -1} to indicate the
123-
* scheme port is prevalent.
120+
* @return the request authority.
121+
* <ul>
122+
* <li>HTTP/2: the {@literal :authority} pseudo header is returned if present, otherwise the {@literal Host}
123+
* header value is returned.
124+
* <li>HTTP/1.x: the {@literal Host} header is returned
125+
* <li>or {@code null} when no such header is present
126+
* </ul>
127+
* When the authority string does not carry a port, the {@link HostAndPort#port()} returns {@code -1} to
128+
* indicate the scheme port is prevalent.
124129
*/
125130
@Nullable
126131
HostAndPort authority();
127132

133+
/**
134+
* @param real whether to return the value of the real HTTP/2 {@literal :authority} header, or the computed one.
135+
* @return the authority, either computed or real. May be null when {@literal real} is {@code true}.
136+
*/
137+
@Nullable
138+
HostAndPort authority(boolean real);
139+
128140
/**
129141
* @return the total number of bytes read for the body of the request.
130142
*/

vertx-core/src/main/java/io/vertx/core/http/impl/Http1xServerRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,11 @@ public HostAndPort authority() {
282282
return authority;
283283
}
284284

285+
@Override
286+
public HostAndPort authority(boolean real) {
287+
return real ? null : authority();
288+
}
289+
285290
@Override
286291
public long bytesRead() {
287292
synchronized (conn) {

vertx-core/src/main/java/io/vertx/core/http/impl/Http2ServerConnection.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ private static boolean isMalformedRequest(Http2ServerStream request) {
8484
}
8585

8686
if (request.method == HttpMethod.CONNECT) {
87-
if (request.scheme != null || request.uri != null || request.authority == null) {
87+
if (request.scheme != null || request.uri != null || request.authority() == null) {
8888
return true;
8989
}
9090
} else {
@@ -93,13 +93,13 @@ private static boolean isMalformedRequest(Http2ServerStream request) {
9393
}
9494
}
9595
if (request.hasAuthority) {
96-
if (request.authority == null) {
96+
if (request.authority() == null) {
9797
return true;
9898
}
9999
CharSequence hostHeader = request.headers.get(HttpHeaders.HOST);
100100
if (hostHeader != null) {
101101
HostAndPort host = HostAndPort.parseAuthority(hostHeader.toString(), -1);
102-
return host == null || (!request.authority.host().equals(host.host()) || request.authority.port() != host.port());
102+
return host == null || (!request.authority().host().equals(host.host()) || request.authority().port() != host.port());
103103
}
104104
}
105105
return false;
@@ -128,18 +128,20 @@ String determineContentEncoding(Http2Headers headers) {
128128

129129
private Http2ServerStream createStream(Http2Headers headers, boolean streamEnded) {
130130
CharSequence schemeHeader = headers.getAndRemove(HttpHeaders.PSEUDO_SCHEME);
131-
HostAndPort authority = null;
131+
HostAndPort realAuthority = null;
132+
HostAndPort computedAuthority = null;
132133
String authorityHeaderAsString;
133134
CharSequence authorityHeader = headers.getAndRemove(HttpHeaders.PSEUDO_AUTHORITY);
134135
if (authorityHeader != null) {
135136
authorityHeaderAsString = authorityHeader.toString();
136-
authority = HostAndPort.parseAuthority(authorityHeaderAsString, -1);
137+
realAuthority = HostAndPort.parseAuthority(authorityHeaderAsString, -1);
138+
computedAuthority = realAuthority;
137139
}
138140
CharSequence hostHeader = null;
139-
if (authority == null) {
141+
if (computedAuthority == null) {
140142
hostHeader = headers.getAndRemove(HttpHeaders.HOST);
141143
if (hostHeader != null) {
142-
authority = HostAndPort.parseAuthority(hostHeader.toString(), -1);
144+
computedAuthority = HostAndPort.parseAuthority(hostHeader.toString(), -1);
143145
}
144146
}
145147
CharSequence pathHeader = headers.getAndRemove(HttpHeaders.PSEUDO_PATH);
@@ -150,7 +152,8 @@ private Http2ServerStream createStream(Http2Headers headers, boolean streamEnded
150152
headers,
151153
schemeHeader != null ? schemeHeader.toString() : null,
152154
authorityHeader != null || hostHeader != null,
153-
authority,
155+
realAuthority,
156+
computedAuthority,
154157
methodHeader != null ? HttpMethod.valueOf(methodHeader.toString()) : null,
155158
pathHeader != null ? pathHeader.toString() : null,
156159
options.getTracingPolicy(), streamEnded);

vertx-core/src/main/java/io/vertx/core/http/impl/Http2ServerRequest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,12 @@ public String scheme() {
321321

322322
@Override
323323
public @Nullable HostAndPort authority() {
324-
return stream.authority;
324+
return stream.authority();
325+
}
326+
327+
@Override
328+
public @Nullable HostAndPort authority(boolean real) {
329+
return stream.authority(real);
325330
}
326331

327332
@Override

vertx-core/src/main/java/io/vertx/core/http/impl/Http2ServerResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ public Future<HttpServerResponse> push(HttpMethod method, HostAndPort authority,
639639
throw new IllegalStateException("A push response cannot promise another push");
640640
}
641641
if (authority == null) {
642-
authority = stream.authority;
642+
authority = stream.authority();
643643
}
644644
synchronized (conn) {
645645
checkValid();

vertx-core/src/main/java/io/vertx/core/http/impl/Http2ServerStream.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class Http2ServerStream extends VertxHttp2Stream<Http2ServerConnection> {
3939
protected final HttpMethod method;
4040
protected final String uri;
4141
protected final boolean hasAuthority;
42-
protected final HostAndPort authority;
42+
private final HostAndPort computedAuthority;
43+
private final HostAndPort realAuthority;
4344
private final TracingPolicy tracingPolicy;
4445
private Object metric;
4546
private Object trace;
@@ -62,7 +63,8 @@ class Http2ServerStream extends VertxHttp2Stream<Http2ServerConnection> {
6263
this.uri = uri;
6364
this.scheme = null;
6465
this.hasAuthority = false;
65-
this.authority = null;
66+
this.computedAuthority = null;
67+
this.realAuthority = null;
6668
this.tracingPolicy = tracingPolicy;
6769
this.halfClosedRemote = halfClosedRemote;
6870
}
@@ -72,7 +74,8 @@ class Http2ServerStream extends VertxHttp2Stream<Http2ServerConnection> {
7274
Http2Headers headers,
7375
String scheme,
7476
boolean hasAuthority,
75-
HostAndPort authority,
77+
HostAndPort realAuthority,
78+
HostAndPort computedAuthority,
7679
HttpMethod method,
7780
String uri,
7881
TracingPolicy tracingPolicy,
@@ -82,7 +85,8 @@ class Http2ServerStream extends VertxHttp2Stream<Http2ServerConnection> {
8285
this.scheme = scheme;
8386
this.headers = headers;
8487
this.hasAuthority = hasAuthority;
85-
this.authority = authority;
88+
this.realAuthority = realAuthority;
89+
this.computedAuthority = computedAuthority;
8690
this.uri = uri;
8791
this.method = method;
8892
this.tracingPolicy = tracingPolicy;
@@ -102,6 +106,14 @@ void registerMetrics() {
102106
}
103107
}
104108

109+
public HostAndPort authority() {
110+
return computedAuthority;
111+
}
112+
113+
public HostAndPort authority(boolean real) {
114+
return real ? realAuthority : computedAuthority;
115+
}
116+
105117
@Override
106118
void onHeaders(Http2Headers headers, StreamPriority streamPriority) {
107119
if (streamPriority != null) {

vertx-core/src/main/java/io/vertx/core/internal/http/HttpServerRequestWrapper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ public HostAndPort authority() {
101101
return delegate.authority();
102102
}
103103

104+
@Override
105+
public @Nullable HostAndPort authority(boolean real) {
106+
return delegate.authority(real);
107+
}
108+
104109
@Override
105110
public boolean isValidAuthority() {
106111
return delegate.isValidAuthority();

vertx-core/src/test/java/io/vertx/tests/http/Http2ClientTest.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ public void testOverrideAuthority() throws Exception {
365365
server.requestHandler(req -> {
366366
assertEquals("localhost", req.authority().host());
367367
assertEquals(4444, req.authority().port());
368+
assertEquals(req.authority(), req.authority(true));
368369
req.response().end();
369370
});
370371
startServer(testAddress);
@@ -379,26 +380,19 @@ public void testOverrideAuthority() throws Exception {
379380

380381
@Test
381382
public void testNoAuthority() throws Exception {
382-
ServerBootstrap bootstrap = createH2Server((decoder, encoder) -> new Http2EventAdapter() {
383-
@Override
384-
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency, short weight, boolean exclusive, int padding, boolean endStream) throws Http2Exception {
385-
vertx.runOnContext(v -> {
386-
assertNull(headers.authority());
387-
encoder.writeHeaders(ctx, streamId, new DefaultHttp2Headers().status("200"), 0, true, ctx.newPromise());
388-
ctx.flush();
389-
});
390-
}
383+
server.requestHandler(req -> {
384+
assertEquals("fromHost", req.authority().host());
385+
assertEquals(1234, req.authority().port());
386+
assertNull(req.authority(true));
387+
req.response().end();
391388
});
392-
ChannelFuture s = bootstrap.bind(DEFAULT_HTTPS_HOST, DEFAULT_HTTPS_PORT).sync();
389+
startServer(testAddress);
393390
client.request(new RequestOptions().setServer(testAddress)
394-
.setPort(4444)
395-
.setHost("localhost")
396-
)
397-
.compose(request -> {
398-
request.authority(null);
399-
return request.send();
400-
})
401-
.onComplete(onSuccess(resp -> testComplete()));
391+
.addHeader("Host", "fromHost:1234")
392+
)
393+
.onSuccess(req -> req.authority(null))
394+
.compose(HttpClientRequest::send)
395+
.onComplete(onSuccess(resp -> testComplete()));
402396
await();
403397
}
404398

0 commit comments

Comments
 (0)