1 /*
2  * Copyright (c) 2011-2017 Contributors to the Eclipse Foundation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License 2.0 which is available at
6  * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7  * which is available at https://www.apache.org/licenses/LICENSE-2.0.
8  *
9  * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10  */
11 
12 module hunt.net.NetClientOptions;
13 
14 import hunt.net.ClientOptionsBase;
15 import hunt.net.OpenSSLEngineOptions;
16 import hunt.net.ProxyOptions;
17 
18 import hunt.Exceptions;
19 import hunt.io.TcpStreamOptions;
20 
21 import core.time;
22 import std.array;
23 
24 /**
25  * Options for configuring a {@link hunt.net.NetClient}.
26  *
27  * @author <a href="http://tfox.org">Tim Fox</a>
28  */
29 class NetClientOptions : ClientOptionsBase {
30 
31     /**
32      * The default value for reconnect attempts = 0
33      */
34     enum int DEFAULT_RECONNECT_ATTEMPTS = 0;  // 5
35 
36     /**
37      * The default value for reconnect interval = 1000 ms
38      */
39     enum Duration DEFAULT_RECONNECT_INTERVAL = 1.seconds;
40 
41     /**
42      * Default value to determine hostname verification algorithm hostname verification (for SSL/TLS) = ""
43      */
44     enum string DEFAULT_HOSTNAME_VERIFICATION_ALGORITHM = "";
45 
46 
47     private int reconnectAttempts;
48     private Duration reconnectInterval;
49     private string hostnameVerificationAlgorithm;
50 
51         /**
52      * The default constructor
53      */
54     this() {
55         super();
56         init();
57     }
58 
59     /**
60      * Copy constructor
61      *
62      * @param other  the options to copy
63      */
64     this(NetClientOptions other) {
65         super(other);
66         this.reconnectAttempts = other.getReconnectAttempts();
67         this.reconnectInterval = other.getReconnectInterval();
68         this.hostnameVerificationAlgorithm = other.getHostnameVerificationAlgorithm();
69     }
70 
71     private void init() {
72         this.reconnectAttempts = DEFAULT_RECONNECT_ATTEMPTS;
73         this.reconnectInterval = DEFAULT_RECONNECT_INTERVAL;
74         this.hostnameVerificationAlgorithm = DEFAULT_HOSTNAME_VERIFICATION_ALGORITHM;
75     }
76 
77     override
78     NetClientOptions setSendBufferSize(int sendBufferSize) {
79         super.setSendBufferSize(sendBufferSize);
80         return this;
81     }
82 
83     override
84     NetClientOptions setReceiveBufferSize(int receiveBufferSize) {
85         super.setReceiveBufferSize(receiveBufferSize);
86         return this;
87     }
88 
89     override
90     NetClientOptions setReuseAddress(bool reuseAddress) {
91         super.setReuseAddress(reuseAddress);
92         return this;
93     }
94 
95     override
96     NetClientOptions setReusePort(bool reusePort) {
97         super.setReusePort(reusePort);
98         return this;
99     }
100 
101     override
102     NetClientOptions setTrafficClass(int trafficClass) {
103         super.setTrafficClass(trafficClass);
104         return this;
105     }
106 
107     override
108     NetClientOptions setTcpNoDelay(bool tcpNoDelay) {
109         super.setTcpNoDelay(tcpNoDelay);
110         return this;
111     }
112 
113     override
114     NetClientOptions setTcpKeepAlive(bool tcpKeepAlive) {
115         super.setTcpKeepAlive(tcpKeepAlive);
116         return this;
117     }
118 
119     override
120     NetClientOptions setSoLinger(int soLinger) {
121         super.setSoLinger(soLinger);
122         return this;
123     }
124 
125     // override
126     // NetClientOptions setUsePooledBuffers(bool usePooledBuffers) {
127     //     super.setUsePooledBuffers(usePooledBuffers);
128     //     return this;
129     // }
130 
131     override
132     NetClientOptions setIdleTimeout(Duration idleTimeout) {
133         super.setIdleTimeout(idleTimeout);
134         return this;
135     }
136 
137     override
138     NetClientOptions setSsl(bool ssl) {
139         super.setSsl(ssl);
140         return this;
141     }
142 
143     // override
144     // NetClientOptions setKeyCertOptions(KeyCertOptions options) {
145     //     super.setKeyCertOptions(options);
146     //     return this;
147     // }
148 
149     // override
150     // NetClientOptions setKeyStoreOptions(JksOptions options) {
151     //     super.setKeyStoreOptions(options);
152     //     return this;
153     // }
154 
155     // override
156     // NetClientOptions setPfxKeyCertOptions(PfxOptions options) {
157     //     return cast(NetClientOptions) super.setPfxKeyCertOptions(options);
158     // }
159 
160     // override
161     // NetClientOptions setPemKeyCertOptions(PemKeyCertOptions options) {
162     //     return cast(NetClientOptions) super.setPemKeyCertOptions(options);
163     // }
164 
165     // override
166     // NetClientOptions setTrustOptions(TrustOptions options) {
167     //     super.setTrustOptions(options);
168     //     return this;
169     // }
170 
171     // override
172     // NetClientOptions setTrustStoreOptions(JksOptions options) {
173     //     super.setTrustStoreOptions(options);
174     //     return this;
175     // }
176 
177     // override
178     // NetClientOptions setPemTrustOptions(PemTrustOptions options) {
179     //     return cast(NetClientOptions) super.setPemTrustOptions(options);
180     // }
181 
182     // override
183     // NetClientOptions setPfxTrustOptions(PfxOptions options) {
184     //     return cast(NetClientOptions) super.setPfxTrustOptions(options);
185     // }
186 
187     // override
188     // NetClientOptions addEnabledCipherSuite(string suite) {
189     //     super.addEnabledCipherSuite(suite);
190     //     return this;
191     // }
192 
193     // override
194     // NetClientOptions addEnabledSecureTransportProtocol(string protocol) {
195     //     super.addEnabledSecureTransportProtocol(protocol);
196     //     return this;
197     // }
198 
199     // override
200     // NetClientOptions removeEnabledSecureTransportProtocol(string protocol) {
201     //     return cast(NetClientOptions) super.removeEnabledSecureTransportProtocol(protocol);
202     // }
203 
204     override
205     NetClientOptions setUseAlpn(bool useAlpn) {
206         return cast(NetClientOptions) super.setUseAlpn(useAlpn);
207     }
208 
209     // override
210     // NetClientOptions setSslEngineOptions(SSLEngineOptions sslEngineOptions) {
211     //     return cast(NetClientOptions) super.setSslEngineOptions(sslEngineOptions);
212     // }
213 
214     // override
215     // NetClientOptions setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) {
216     //     return cast(NetClientOptions) super.setJdkSslEngineOptions(sslEngineOptions);
217     // }
218 
219     override
220     NetClientOptions setTcpFastOpen(bool tcpFastOpen) {
221         return cast(NetClientOptions) super.setTcpFastOpen(tcpFastOpen);
222     }
223 
224     override
225     NetClientOptions setTcpCork(bool tcpCork) {
226         return cast(NetClientOptions) super.setTcpCork(tcpCork);
227     }
228 
229     override
230     NetClientOptions setTcpQuickAck(bool tcpQuickAck) {
231         return cast(NetClientOptions) super.setTcpQuickAck(tcpQuickAck);
232     }
233 
234     override
235     ClientOptionsBase setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) {
236         return super.setOpenSslEngineOptions(sslEngineOptions);
237     }
238 
239     // override
240     // NetClientOptions addCrlPath(string crlPath) {
241     //     return cast(NetClientOptions) super.addCrlPath(crlPath);
242     // }
243 
244     // override
245     // NetClientOptions addCrlValue(Buffer crlValue) {
246     //     return cast(NetClientOptions) super.addCrlValue(crlValue);
247     // }
248 
249     override
250     NetClientOptions setTrustAll(bool trustAll) {
251         super.setTrustAll(trustAll);
252         return this;
253     }
254 
255     override
256     NetClientOptions setConnectTimeout(Duration connectTimeout) {
257         super.setConnectTimeout(connectTimeout);
258         return this;
259     }
260 
261     override
262     NetClientOptions setMetricsName(string metricsName) {
263         return cast(NetClientOptions) super.setMetricsName(metricsName);
264     }
265 
266     /**
267      * @return  the value of reconnect attempts
268      */
269     int getReconnectAttempts() {
270         return reconnectAttempts;
271     }
272 
273     /**
274      * Set the value of reconnect attempts
275      *
276      * @param attempts  the maximum number of reconnect attempts
277      * @return a reference to this, so the API can be used fluently
278      */
279     NetClientOptions setReconnectAttempts(int attempts) {
280         if (attempts < -1) {
281             throw new IllegalArgumentException("reconnect attempts must be >= -1");
282         }
283         this.reconnectAttempts = attempts;
284         return this;
285     }
286 
287     /**
288      * @return  the value of reconnect interval
289      */
290     Duration getReconnectInterval() {
291         return reconnectInterval;
292     }
293 
294     /**
295      * Set the reconnect interval
296      *
297      * @param interval  the reconnect interval in ms
298      * @return a reference to this, so the API can be used fluently
299      */
300     NetClientOptions setReconnectInterval(Duration interval) {
301         if (interval <= Duration.zero) {
302             throw new IllegalArgumentException("reconnect interval must be >= 1");
303         }
304         this.reconnectInterval = interval;
305         return this;
306     }
307 
308     /**
309      * @return  the value of the hostname verification algorithm
310      */
311 
312     string getHostnameVerificationAlgorithm() {
313         return hostnameVerificationAlgorithm;
314     }
315 
316     /**
317      * Set the hostname verification algorithm interval
318      * To disable hostname verification, set hostnameVerificationAlgorithm to an empty string
319      *
320      * @param hostnameVerificationAlgorithm should be HTTPS, LDAPS or an empty string
321      * @return a reference to this, so the API can be used fluently
322      */
323 
324     NetClientOptions setHostnameVerificationAlgorithm(string hostnameVerificationAlgorithm) {
325         assert(!hostnameVerificationAlgorithm.empty, "hostnameVerificationAlgorithm can not be null!");
326         this.hostnameVerificationAlgorithm = hostnameVerificationAlgorithm;
327         return this;
328     }
329 
330     /**
331      * @return  the value of reconnect interval
332      */
333     //long getReconnectInterval() {
334     //    return reconnectInterval;
335     //}
336 
337     override
338     NetClientOptions setLogActivity(bool logEnabled) {
339         return cast(NetClientOptions) super.setLogActivity(logEnabled);
340     }
341 
342     override NetClientOptions setProxyOptions(ProxyOptions proxyOptions) {
343         return cast(NetClientOptions) super.setProxyOptions(proxyOptions);
344     }
345 
346     override
347     NetClientOptions setLocalAddress(string localAddress) {
348         return cast(NetClientOptions) super.setLocalAddress(localAddress);
349     }
350 
351     // override
352     // NetClientOptions setEnabledSecureTransportProtocols(Set!(string) enabledSecureTransportProtocols) {
353     //     return cast(NetClientOptions) super.setEnabledSecureTransportProtocols(enabledSecureTransportProtocols);
354     // }
355 
356     override NetClientOptions setSslHandshakeTimeout(Duration sslHandshakeTimeout) {
357         return cast(NetClientOptions) super.setSslHandshakeTimeout(sslHandshakeTimeout);
358     }
359 
360     override TcpStreamOptions toStreamOptions() {
361         TcpStreamOptions options = super.toStreamOptions();
362         options.retryTimes = reconnectAttempts;
363         options.retryInterval = reconnectInterval;
364         return options;
365     }
366 
367     override
368     bool opEquals(Object o) {
369         if (this is o) return true;
370         if (!super.opEquals(o)) return false;
371 
372         NetClientOptions that = cast(NetClientOptions) o;
373         if(that is null) return false;
374 
375         if (reconnectAttempts != that.reconnectAttempts) return false;
376         if (reconnectInterval != that.reconnectInterval) return false;
377         if (hostnameVerificationAlgorithm != that.hostnameVerificationAlgorithm) return false;
378 
379         return true;
380     }
381 
382     override
383     size_t toHash() @trusted nothrow {
384         ulong interval = cast(size_t)reconnectInterval.total!"msecs"();
385         size_t result = super.toHash();
386         result = 31 * result + reconnectAttempts;
387         result = 31 * result + cast(size_t) (interval ^ (interval >>> 32));
388         result = 31 * result + hostnameVerificationAlgorithm.hashOf();
389         return result;
390     }
391 
392 }