37
37
import org .opensearch .core .xcontent .NamedXContentRegistry ;
38
38
import org .opensearch .http .HttpChannel ;
39
39
import org .opensearch .http .HttpHandlingSettings ;
40
+ import org .opensearch .http .HttpServerTransport ;
40
41
import org .opensearch .http .netty4 .Netty4HttpChannel ;
41
42
import org .opensearch .http .netty4 .Netty4HttpServerTransport ;
42
- import org .opensearch .plugins .SecureTransportSettingsProvider ;
43
+ import org .opensearch .plugins .SecureHttpTransportSettingsProvider ;
44
+ import org .opensearch .plugins .TransportExceptionHandler ;
43
45
import org .opensearch .telemetry .tracing .Tracer ;
44
46
import org .opensearch .threadpool .ThreadPool ;
45
47
import org .opensearch .transport .SharedGroupFactory ;
48
+ import org .opensearch .transport .TransportAdapterProvider ;
46
49
import org .opensearch .transport .netty4 .ssl .SslUtils ;
47
50
48
51
import javax .net .ssl .SSLEngine ;
49
52
53
+ import java .util .List ;
54
+ import java .util .Optional ;
55
+ import java .util .stream .Collectors ;
56
+
50
57
import io .netty .channel .Channel ;
51
58
import io .netty .channel .ChannelHandler ;
52
59
import io .netty .channel .ChannelHandlerContext ;
60
+ import io .netty .channel .ChannelInboundHandlerAdapter ;
53
61
import io .netty .handler .codec .DecoderException ;
54
62
import io .netty .handler .ssl .ApplicationProtocolNames ;
55
63
import io .netty .handler .ssl .ApplicationProtocolNegotiationHandler ;
59
67
* @see <a href="https://github.com/opensearch-project/security/blob/d526c9f6c2a438c14db8b413148204510b9fe2e2/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java">SecuritySSLNettyHttpServerTransport</a>
60
68
*/
61
69
public class SecureNetty4HttpServerTransport extends Netty4HttpServerTransport {
70
+ public static final String REQUEST_HEADER_VERIFIER = "HeaderVerifier" ;
71
+ public static final String REQUEST_DECOMPRESSOR = "RequestDecompressor" ;
72
+
62
73
private static final Logger logger = LogManager .getLogger (SecureNetty4HttpServerTransport .class );
63
- private final SecureTransportSettingsProvider secureTransportSettingsProvider ;
64
- private final SecureTransportSettingsProvider .ServerExceptionHandler exceptionHandler ;
74
+ private final SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider ;
75
+ private final TransportExceptionHandler exceptionHandler ;
76
+ private final ChannelInboundHandlerAdapter headerVerifier ;
77
+ private final TransportAdapterProvider <HttpServerTransport > decompressorProvider ;
65
78
66
79
public SecureNetty4HttpServerTransport (
67
80
final Settings settings ,
@@ -72,7 +85,7 @@ public SecureNetty4HttpServerTransport(
72
85
final Dispatcher dispatcher ,
73
86
final ClusterSettings clusterSettings ,
74
87
final SharedGroupFactory sharedGroupFactory ,
75
- final SecureTransportSettingsProvider secureTransportSettingsProvider ,
88
+ final SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider ,
76
89
final Tracer tracer
77
90
) {
78
91
super (
@@ -86,9 +99,45 @@ public SecureNetty4HttpServerTransport(
86
99
sharedGroupFactory ,
87
100
tracer
88
101
);
89
- this .secureTransportSettingsProvider = secureTransportSettingsProvider ;
90
- this .exceptionHandler = secureTransportSettingsProvider .buildHttpServerExceptionHandler (settings , this )
91
- .orElse (SecureTransportSettingsProvider .ServerExceptionHandler .NOOP );
102
+
103
+ this .secureHttpTransportSettingsProvider = secureHttpTransportSettingsProvider ;
104
+ this .exceptionHandler = secureHttpTransportSettingsProvider .buildHttpServerExceptionHandler (settings , this )
105
+ .orElse (TransportExceptionHandler .NOOP );
106
+
107
+ final List <ChannelInboundHandlerAdapter > headerVerifiers = secureHttpTransportSettingsProvider .getHttpTransportAdapterProviders (
108
+ settings
109
+ )
110
+ .stream ()
111
+ .filter (p -> REQUEST_HEADER_VERIFIER .equalsIgnoreCase (p .name ()))
112
+ .map (p -> p .create (settings , this , ChannelInboundHandlerAdapter .class ))
113
+ .filter (Optional ::isPresent )
114
+ .map (Optional ::get )
115
+ .collect (Collectors .toList ());
116
+
117
+ if (headerVerifiers .size () > 1 ) {
118
+ throw new IllegalArgumentException ("Cannot have more than one header verifier configured, supplied " + headerVerifiers .size ());
119
+ }
120
+
121
+ final Optional <TransportAdapterProvider <HttpServerTransport >> decompressorProviderOpt = secureHttpTransportSettingsProvider
122
+ .getHttpTransportAdapterProviders (settings )
123
+ .stream ()
124
+ .filter (p -> REQUEST_DECOMPRESSOR .equalsIgnoreCase (p .name ()))
125
+ .findFirst ();
126
+ // There could be multiple request decompressor providers configured, using the first one
127
+ decompressorProviderOpt .ifPresent (p -> logger .debug ("Using request decompressor provider: {}" , p ));
128
+
129
+ this .headerVerifier = headerVerifiers .isEmpty () ? null : headerVerifiers .get (0 );
130
+ this .decompressorProvider = decompressorProviderOpt .orElseGet (() -> new TransportAdapterProvider <HttpServerTransport >() {
131
+ @ Override
132
+ public String name () {
133
+ return REQUEST_DECOMPRESSOR ;
134
+ }
135
+
136
+ @ Override
137
+ public <C > Optional <C > create (Settings settings , HttpServerTransport transport , Class <C > adapterClass ) {
138
+ return Optional .empty ();
139
+ }
140
+ });
92
141
}
93
142
94
143
@ Override
@@ -152,7 +201,7 @@ protected SslHttpChannelHandler(final Netty4HttpServerTransport transport, final
152
201
protected void initChannel (Channel ch ) throws Exception {
153
202
super .initChannel (ch );
154
203
155
- final SSLEngine sslEngine = secureTransportSettingsProvider .buildSecureHttpServerEngine (
204
+ final SSLEngine sslEngine = secureHttpTransportSettingsProvider .buildSecureHttpServerEngine (
156
205
settings ,
157
206
SecureNetty4HttpServerTransport .this
158
207
).orElseGet (SslUtils ::createDefaultServerSSLEngine );
@@ -166,4 +215,17 @@ protected void configurePipeline(Channel ch) {
166
215
ch .pipeline ().addLast (new Http2OrHttpHandler ());
167
216
}
168
217
}
218
+
219
+ protected ChannelInboundHandlerAdapter createHeaderVerifier () {
220
+ if (headerVerifier != null ) {
221
+ return headerVerifier ;
222
+ } else {
223
+ return super .createHeaderVerifier ();
224
+ }
225
+ }
226
+
227
+ @ Override
228
+ protected ChannelInboundHandlerAdapter createDecompressor () {
229
+ return decompressorProvider .create (settings , this , ChannelInboundHandlerAdapter .class ).orElseGet (super ::createDecompressor );
230
+ }
169
231
}
0 commit comments