Skip to content

Commit 456feea

Browse files
committed
minimal impl
1 parent 5567e0d commit 456feea

44 files changed

Lines changed: 3073 additions & 219 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2025 LINE Corporation
3+
*
4+
* LINE Corporation 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+
17+
package com.linecorp.armeria.server;
18+
19+
import com.linecorp.armeria.common.annotation.Nullable;
20+
import com.linecorp.armeria.common.annotation.UnstableApi;
21+
22+
@UnstableApi
23+
interface ConnectionLevelSetters {
24+
25+
@Nullable
26+
ConnectionAcceptor connectionAcceptor();
27+
28+
ConnectionLevelSetters connectionAcceptor(ConnectionAcceptor connectionAcceptor);
29+
30+
@Nullable
31+
ServerTlsProvider tlsProvider();
32+
33+
ConnectionLevelSetters tlsProvider(ServerTlsProvider serverTlsProvider);
34+
}

core/src/main/java/com/linecorp/armeria/server/ServerBuilder.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@
172172
*
173173
* @see VirtualHostBuilder
174174
*/
175-
public final class ServerBuilder implements TlsSetters, ServiceConfigsBuilder<ServerBuilder> {
175+
public final class ServerBuilder implements ConnectionLevelSetters, TlsSetters,
176+
ServiceConfigsBuilder<ServerBuilder> {
176177
private static final Logger logger = LoggerFactory.getLogger(ServerBuilder.class);
177178

178179
// Defaults to no graceful shutdown.
@@ -531,12 +532,22 @@ public ServerBuilder childChannelPipelineCustomizer(
531532
* Sets the {@link ConnectionAcceptor} that is called once per connection, before TLS
532533
* negotiation, to decide whether to accept the connection.
533534
*/
535+
@Override
534536
@UnstableApi
535537
public ServerBuilder connectionAcceptor(ConnectionAcceptor connectionAcceptor) {
536538
this.connectionAcceptor = requireNonNull(connectionAcceptor, "connectionAcceptor");
537539
return this;
538540
}
539541

542+
/**
543+
* Returns the {@link ConnectionAcceptor} configured so far.
544+
*/
545+
@Override
546+
@UnstableApi
547+
public ConnectionAcceptor connectionAcceptor() {
548+
return connectionAcceptor;
549+
}
550+
540551
/**
541552
* Adds a {@link ServerPlugin} that will be installed during {@link Server} construction
542553
* and during {@link Server#reconfigure(ServerConfigurator)}.
@@ -1243,6 +1254,16 @@ public ServerBuilder tls(KeyManagerFactory keyManagerFactory) {
12431254
return this;
12441255
}
12451256

1257+
/**
1258+
* Returns the {@link ServerTlsProvider} configured so far, or {@code null} if not set.
1259+
*/
1260+
@Override
1261+
@UnstableApi
1262+
@Nullable
1263+
public ServerTlsProvider tlsProvider() {
1264+
return serverTlsProviderBuilder.serverTlsProvider;
1265+
}
1266+
12461267
/**
12471268
* Sets the specified {@link TlsProvider} which will be used for building an {@link SslContext} of
12481269
* a hostname.
@@ -1322,6 +1343,7 @@ public ServerBuilder tlsProvider(TlsProvider tlsProvider, ServerTlsConfig tlsCon
13221343
* the {@code tlsProvider} takes priority. The static TLS settings are used as a fallback
13231344
* when the provider returns {@code null}.
13241345
*/
1346+
@Override
13251347
@UnstableApi
13261348
public ServerBuilder tlsProvider(ServerTlsProvider serverTlsProvider) {
13271349
requireNonNull(serverTlsProvider, "serverTlsProvider");

core/src/main/java/com/linecorp/armeria/server/ServerTlsProvider.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,17 @@ static ServerTlsProvider of(Function<? super ConnectionContext, @Nullable Server
5656
}
5757

5858
/**
59-
* Returns a {@link ServerTlsSpec} for the given {@link ConnectionContext}, or {@code null}
60-
* if this provider cannot handle the connection. When {@code null} is returned,
61-
* the server falls back to per-VirtualHost TLS settings.
59+
* Returns a {@link CompletableFuture} that completes with a {@link ServerTlsSpec} for the
60+
* given {@link ConnectionContext}, or with {@code null} if this provider cannot handle the
61+
* connection. When the future completes with {@code null}, the server falls back to
62+
* per-VirtualHost TLS settings.
6263
*
6364
* <p>This method is called by the server pipeline for each new TLS connection.
6465
* Implementations can inspect connection properties such as SNI hostname, ALPN protocols,
6566
* and custom attributes to determine the appropriate TLS configuration.
67+
*
68+
* @return a non-null {@link CompletableFuture} that may complete with a {@code null}
69+
* {@link ServerTlsSpec}
6670
*/
6771
CompletableFuture<@Nullable ServerTlsSpec> serverTlsSpec(ConnectionContext ctx);
6872
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright 2026 LY Corporation
3+
*
4+
* LY Corporation 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+
17+
package com.linecorp.armeria.xds.it;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
21+
import org.junit.jupiter.api.Test;
22+
23+
import com.linecorp.armeria.client.BlockingWebClient;
24+
import com.linecorp.armeria.client.WebClient;
25+
import com.linecorp.armeria.common.AggregatedHttpResponse;
26+
import com.linecorp.armeria.common.HttpStatus;
27+
import com.linecorp.armeria.xds.XdsBootstrap;
28+
import com.linecorp.armeria.xds.client.endpoint.XdsHttpPreprocessor;
29+
30+
import io.envoyproxy.envoy.config.bootstrap.v3.Bootstrap;
31+
32+
class DirectResponseTest {
33+
34+
@Test
35+
void directResponseReturnsStatus() {
36+
//language=YAML
37+
final String bootstrapYaml =
38+
"""
39+
static_resources:
40+
listeners:
41+
- name: listener
42+
api_listener:
43+
api_listener:
44+
"@type": type.googleapis.com/envoy.extensions.filters\
45+
.network.http_connection_manager.v3.HttpConnectionManager
46+
stat_prefix: ingress_http
47+
route_config:
48+
name: local_route
49+
virtual_hosts:
50+
- name: local_service
51+
domains: ["*"]
52+
routes:
53+
- match:
54+
prefix: "/"
55+
direct_response:
56+
status: 200
57+
http_filters:
58+
- name: envoy.filters.http.router
59+
""";
60+
61+
try (XdsBootstrap bootstrap =
62+
XdsBootstrap.of(XdsResourceReader.fromYaml(bootstrapYaml, Bootstrap.class));
63+
XdsHttpPreprocessor preprocessor =
64+
XdsHttpPreprocessor.ofListener("listener", bootstrap)) {
65+
final BlockingWebClient client = WebClient.builder(preprocessor).build().blocking();
66+
final AggregatedHttpResponse res = client.get("/hello");
67+
assertThat(res.status()).isEqualTo(HttpStatus.OK);
68+
}
69+
}
70+
71+
@Test
72+
void directResponseReturnsCustomStatus() {
73+
//language=YAML
74+
final String bootstrapYaml =
75+
"""
76+
static_resources:
77+
listeners:
78+
- name: listener
79+
api_listener:
80+
api_listener:
81+
"@type": type.googleapis.com/envoy.extensions.filters\
82+
.network.http_connection_manager.v3.HttpConnectionManager
83+
stat_prefix: ingress_http
84+
route_config:
85+
name: local_route
86+
virtual_hosts:
87+
- name: local_service
88+
domains: ["*"]
89+
routes:
90+
- match:
91+
prefix: "/"
92+
direct_response:
93+
status: 403
94+
http_filters:
95+
- name: envoy.filters.http.router
96+
""";
97+
98+
try (XdsBootstrap bootstrap =
99+
XdsBootstrap.of(XdsResourceReader.fromYaml(bootstrapYaml, Bootstrap.class));
100+
XdsHttpPreprocessor preprocessor =
101+
XdsHttpPreprocessor.ofListener("listener", bootstrap)) {
102+
final BlockingWebClient client = WebClient.builder(preprocessor).build().blocking();
103+
final AggregatedHttpResponse res = client.get("/hello");
104+
assertThat(res.status()).isEqualTo(HttpStatus.FORBIDDEN);
105+
}
106+
}
107+
}

it/xds-client/src/test/java/com/linecorp/armeria/xds/it/XdsCertificateExtension.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@
5252
* new XdsCertificateExtension(new SelfSignedCertificateExtension("localhost"));
5353
* }</pre>
5454
*/
55-
final class XdsCertificateExtension extends AbstractAllOrEachExtension {
55+
public final class XdsCertificateExtension extends AbstractAllOrEachExtension {
5656

5757
private final SelfSignedCertificateExtension delegate;
5858
private Path tempDir;
5959
private File certificateFile;
6060
private File privateKeyFile;
6161

62-
XdsCertificateExtension(SelfSignedCertificateExtension delegate) {
62+
public XdsCertificateExtension(SelfSignedCertificateExtension delegate) {
6363
this.delegate = delegate;
6464
}
6565

@@ -79,23 +79,23 @@ protected void after(ExtensionContext context) throws Exception {
7979
}
8080
}
8181

82-
File certificateFile() {
82+
public File certificateFile() {
8383
return certificateFile;
8484
}
8585

86-
File privateKeyFile() {
86+
public File privateKeyFile() {
8787
return privateKeyFile;
8888
}
8989

90-
X509Certificate certificate() {
90+
public X509Certificate certificate() {
9191
return delegate.certificate();
9292
}
9393

94-
PrivateKey privateKey() {
94+
public PrivateKey privateKey() {
9595
return delegate.privateKey();
9696
}
9797

98-
TlsKeyPair tlsKeyPair() {
98+
public TlsKeyPair tlsKeyPair() {
9999
return delegate.tlsKeyPair();
100100
}
101101

0 commit comments

Comments
 (0)