Skip to content

Commit 532e428

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
1 parent a26712b commit 532e428

File tree

7 files changed

+68
-40
lines changed

7 files changed

+68
-40
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/http2/Http2HeadersMultiMap.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ private Http2HeadersMultiMap(boolean mutable, Headers<CharSequence, CharSequence
5757

5858
private Integer status;
5959
private HttpMethod method;
60-
private HostAndPort authority;
60+
private HostAndPort computedAuthority;
61+
private HostAndPort realAuthority;
6162
private String uri;
6263
private String scheme;
6364

@@ -75,24 +76,25 @@ public boolean validate(boolean isRequest) {
7576
CharSequence pathHeader = headers.get(HttpHeaders.PSEUDO_PATH);
7677
String uri = pathHeader != null ? pathHeader.toString() : null;
7778

78-
HostAndPort authority = null;
79+
HostAndPort currentAuthority = null;
7980
String authorityHeaderAsString;
8081
CharSequence authorityHeader = headers.get(HttpHeaders.PSEUDO_AUTHORITY);
8182
if (authorityHeader != null) {
8283
authorityHeaderAsString = authorityHeader.toString();
83-
authority = HostAndPort.parseAuthority(authorityHeaderAsString, -1);
84+
this.realAuthority = HostAndPort.parseAuthority(authorityHeaderAsString, -1);
85+
currentAuthority = this.realAuthority;
8486
}
8587

8688
CharSequence hostHeader = headers.get(HttpHeaders.HOST);
87-
if (authority == null) {
89+
if (currentAuthority == null) {
8890
headers.remove(HttpHeaders.HOST);
8991
if (hostHeader != null) {
90-
authority = HostAndPort.parseAuthority(hostHeader.toString(), -1);
92+
currentAuthority = HostAndPort.parseAuthority(hostHeader.toString(), -1);
9193
}
9294
}
9395

9496
if (method == HttpMethod.CONNECT) {
95-
if (scheme != null || uri != null || authority == null) {
97+
if (scheme != null || uri != null || currentAuthority == null) {
9698
return false;
9799
}
98100
} else {
@@ -103,20 +105,20 @@ public boolean validate(boolean isRequest) {
103105

104106
boolean hasAuthority = authorityHeader != null || hostHeader != null;
105107
if (hasAuthority) {
106-
if (authority == null) {
108+
if (currentAuthority == null) {
107109
return false;
108110
}
109111
if (hostHeader != null) {
110112
HostAndPort host = HostAndPort.parseAuthority(hostHeader.toString(), -1);
111-
if (host == null || (!authority.host().equals(host.host()) || authority.port() != host.port())) {
113+
if (host == null || (!currentAuthority.host().equals(host.host()) || currentAuthority.port() != host.port())) {
112114
return false;
113115
}
114116
}
115117
}
116118

117119
this.method = method;
118120
this.uri = uri;
119-
this.authority = authority;
121+
this.computedAuthority = currentAuthority;
120122
this.scheme = scheme;
121123

122124
return true;
@@ -156,8 +158,8 @@ public Http2HeadersMultiMap prepare() {
156158
if (scheme != null) {
157159
headers.set(HttpHeaders.PSEUDO_SCHEME, scheme);
158160
}
159-
if (authority != null) {
160-
headers.set(HttpHeaders.PSEUDO_AUTHORITY, authority.toString(ssl));
161+
if (computedAuthority != null) {
162+
headers.set(HttpHeaders.PSEUDO_AUTHORITY, computedAuthority.toString(ssl));
161163
}
162164
if (scheme != null) {
163165
headers.set(HttpHeaders.PSEUDO_SCHEME, scheme);
@@ -205,12 +207,16 @@ public HttpMethod method() {
205207
}
206208

207209
public Http2HeadersMultiMap authority(HostAndPort authority) {
208-
this.authority = authority;
210+
this.computedAuthority = authority;
209211
return this;
210212
}
211213

212214
public HostAndPort authority() {
213-
return authority;
215+
return computedAuthority;
216+
}
217+
218+
public HostAndPort authority(boolean real) {
219+
return real ? realAuthority : computedAuthority;
214220
}
215221

216222
public String scheme() {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ public String scheme() {
348348
return stream.authority();
349349
}
350350

351+
@Override
352+
public @Nullable HostAndPort authority(boolean real) {
353+
return stream.authority(real);
354+
}
355+
351356
@Override
352357
public long bytesRead() {
353358
return stream.bytesRead();

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public class Http2ServerStream extends Http2StreamBase {
3939
private String scheme;
4040
private HttpMethod method;
4141
private String uri;
42-
private HostAndPort authority;
4342
private Http2ServerStreamHandler handler;
4443

4544
// Observability
@@ -67,7 +66,6 @@ public Http2ServerStream(Http2ServerConnection connection,
6766
this.method = method;
6867
this.uri = uri;
6968
this.scheme = null;
70-
this.authority = null;
7169
this.tracingPolicy = tracingPolicy;
7270
this.serverMetrics = serverMetrics;
7371
this.socketMetric = socketMetric;
@@ -88,7 +86,7 @@ public Http2ServerStream(Http2ServerConnection connection,
8886

8987
private HttpRequest observableRequest() {
9088
if (observableRequest == null) {
91-
observableRequest = new HttpRequestHead(method, uri, requestHeaders, authority, null, null);
89+
observableRequest = new HttpRequestHead(method, uri, requestHeaders, requestHeaders.authority(), null, null);
9290
}
9391
return observableRequest;
9492
}
@@ -127,7 +125,11 @@ public String scheme() {
127125
}
128126

129127
public HostAndPort authority() {
130-
return authority;
128+
return requestHeaders.authority(false);
129+
}
130+
131+
public HostAndPort authority(boolean real) {
132+
return requestHeaders.authority(real);
131133
}
132134

133135
public Object metric() {
@@ -143,7 +145,6 @@ public void onHeaders(Http2HeadersMultiMap headers) {
143145

144146
this.method = headers.method();
145147
this.uri = headers.path();
146-
this.authority = headers.authority();
147148
this.scheme = headers.scheme();
148149
this.requestHeaders = headers;
149150

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
@@ -366,6 +366,7 @@ public void testOverrideAuthority() throws Exception {
366366
server.requestHandler(req -> {
367367
assertEquals("localhost", req.authority().host());
368368
assertEquals(4444, req.authority().port());
369+
assertEquals(req.authority(), req.authority(true));
369370
req.response().end();
370371
});
371372
startServer(testAddress);
@@ -380,26 +381,19 @@ public void testOverrideAuthority() throws Exception {
380381

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

0 commit comments

Comments
 (0)