88
99package org .opensearch .http .reactor .netty4 ;
1010
11+ import org .opensearch .OpenSearchException ;
1112import org .opensearch .common .Nullable ;
1213import org .opensearch .common .network .NetworkService ;
1314import org .opensearch .common .settings .ClusterSettings ;
2728import org .opensearch .http .HttpServerChannel ;
2829import org .opensearch .http .reactor .netty4 .ssl .SslUtils ;
2930import org .opensearch .plugins .SecureHttpTransportSettingsProvider ;
31+ import org .opensearch .plugins .SecureHttpTransportSettingsProvider .SecureHttpTransportParameters ;
3032import org .opensearch .rest .RestHandler ;
3133import org .opensearch .rest .RestRequest .Method ;
3234import org .opensearch .telemetry .tracing .Tracer ;
3335import org .opensearch .threadpool .ThreadPool ;
3436import org .opensearch .transport .reactor .SharedGroupFactory ;
3537import org .opensearch .transport .reactor .netty4 .Netty4Utils ;
3638
37- import javax .net .ssl .SSLEngine ;
38- import javax .net .ssl .SSLException ;
39- import javax .net .ssl .SSLSessionContext ;
39+ import javax .net .ssl .KeyManagerFactory ;
4040
4141import java .net .InetSocketAddress ;
4242import java .net .SocketOption ;
4343import java .time .Duration ;
4444import java .util .Arrays ;
45- import java .util .List ;
4645import java .util .Optional ;
4746
4847import io .netty .buffer .ByteBuf ;
49- import io .netty .buffer .ByteBufAllocator ;
5048import io .netty .channel .ChannelOption ;
5149import io .netty .channel .socket .nio .NioChannelOption ;
5250import io .netty .handler .codec .http .DefaultLastHttpContent ;
5351import io .netty .handler .codec .http .FullHttpResponse ;
5452import io .netty .handler .codec .http .HttpContent ;
55- import io .netty .handler .ssl .ApplicationProtocolNegotiator ;
53+ import io .netty .handler .codec .http .HttpResponseStatus ;
54+ import io .netty .handler .ssl .ApplicationProtocolConfig ;
55+ import io .netty .handler .ssl .ApplicationProtocolNames ;
5656import io .netty .handler .ssl .SslContext ;
57+ import io .netty .handler .ssl .SslContextBuilder ;
58+ import io .netty .handler .ssl .SupportedCipherSuiteFilter ;
5759import io .netty .handler .timeout .ReadTimeoutException ;
58- import io .netty .util .ReferenceCountUtil ;
5960import org .reactivestreams .Publisher ;
6061import reactor .core .publisher .Mono ;
6162import reactor .core .scheduler .Scheduler ;
@@ -306,59 +307,33 @@ private HttpServer configure(final HttpServer server) throws Exception {
306307
307308 // Configure SSL context if available
308309 if (secureHttpTransportSettingsProvider != null ) {
309- final SSLEngine engine = secureHttpTransportSettingsProvider .buildSecureHttpServerEngine (settings , this )
310- .orElseGet (SslUtils ::createDefaultServerSSLEngine );
311-
312- try {
313- final List <String > cipherSuites = Arrays .asList (engine .getEnabledCipherSuites ());
314- final List <String > applicationProtocols = Arrays .asList (engine .getSSLParameters ().getApplicationProtocols ());
315-
316- configured = configured .secure (spec -> spec .sslContext (new SslContext () {
317- @ Override
318- public SSLSessionContext sessionContext () {
319- throw new UnsupportedOperationException (); /* server only, should never be called */
320- }
321-
322- @ Override
323- public SSLEngine newEngine (ByteBufAllocator alloc , String peerHost , int peerPort ) {
324- throw new UnsupportedOperationException (); /* server only, should never be called */
325- }
326-
327- @ Override
328- public SSLEngine newEngine (ByteBufAllocator alloc ) {
329- try {
330- return secureHttpTransportSettingsProvider .buildSecureHttpServerEngine (
331- settings ,
332- ReactorNetty4HttpServerTransport .this
333- ).orElseGet (SslUtils ::createDefaultServerSSLEngine );
334- } catch (final SSLException ex ) {
335- throw new UnsupportedOperationException ("Unable to create SSLEngine" , ex );
336- }
337- }
338-
339- @ Override
340- public boolean isClient () {
341- return false ; /* server only */
342- }
343-
344- @ Override
345- public List <String > cipherSuites () {
346- return cipherSuites ;
347- }
310+ final Optional <SecureHttpTransportParameters > parameters = secureHttpTransportSettingsProvider .parameters (settings );
311+
312+ final KeyManagerFactory keyManagerFactory = parameters .flatMap (SecureHttpTransportParameters ::keyManagerFactory )
313+ .orElseThrow (() -> new OpenSearchException ("The KeyManagerFactory instance is not provided" ));
314+
315+ final SslContextBuilder sslContextBuilder = SslContextBuilder .forServer (keyManagerFactory );
316+ parameters .flatMap (SecureHttpTransportParameters ::trustManagerFactory ).ifPresent (sslContextBuilder ::trustManager );
317+ parameters .map (SecureHttpTransportParameters ::cipherSuites )
318+ .ifPresent (ciphers -> sslContextBuilder .ciphers (ciphers , SupportedCipherSuiteFilter .INSTANCE ));
319+
320+ final SslContext sslContext = sslContextBuilder .protocols (
321+ parameters .map (SecureHttpTransportParameters ::protocols ).orElseGet (() -> Arrays .asList (SslUtils .DEFAULT_SSL_PROTOCOLS ))
322+ )
323+ .applicationProtocolConfig (
324+ new ApplicationProtocolConfig (
325+ ApplicationProtocolConfig .Protocol .ALPN ,
326+ // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers.
327+ ApplicationProtocolConfig .SelectorFailureBehavior .NO_ADVERTISE ,
328+ // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers.
329+ ApplicationProtocolConfig .SelectedListenerFailureBehavior .ACCEPT ,
330+ ApplicationProtocolNames .HTTP_2 ,
331+ ApplicationProtocolNames .HTTP_1_1
332+ )
333+ )
334+ .build ();
348335
349- @ Override
350- public ApplicationProtocolNegotiator applicationProtocolNegotiator () {
351- return new ApplicationProtocolNegotiator () {
352- @ Override
353- public List <String > protocols () {
354- return applicationProtocols ;
355- }
356- };
357- }
358- }).build ()).protocol (HttpProtocol .HTTP11 , HttpProtocol .H2 );
359- } finally {
360- ReferenceCountUtil .release (engine );
361- }
336+ configured = configured .secure (spec -> spec .sslContext (sslContext )).protocol (HttpProtocol .HTTP11 , HttpProtocol .H2 );
362337 } else {
363338 configured = configured .protocol (HttpProtocol .HTTP11 , HttpProtocol .H2C );
364339 }
@@ -373,6 +348,12 @@ public List<String> protocols() {
373348 * @return response publisher
374349 */
375350 protected Publisher <Void > incomingRequest (HttpServerRequest request , HttpServerResponse response ) {
351+ // At least now, Reactor Netty does not respect maxInitialLineLength setting for HTTP/2 (but
352+ // does respect it for H2C and HTTP/1.1)
353+ if (request .uri ().length () > maxInitialLineLength .bytesAsInt ()) {
354+ return response .status (HttpResponseStatus .REQUEST_URI_TOO_LONG ).send ();
355+ }
356+
376357 final Method method = HttpConversionUtil .convertMethod (request .method ());
377358 final Optional <RestHandler > dispatchHandlerOpt = dispatcher .dispatchHandler (
378359 request .uri (),
0 commit comments