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.ClientOptionsBase;
13 
14 import hunt.net.ClientAuth;
15 import hunt.net.OpenSSLEngineOptions;
16 import hunt.net.ProxyOptions;
17 import hunt.net.TcpSslOptions;
18 
19 import hunt.Exceptions;
20 
21 import core.time;
22 
23 /**
24  * Base class for Client options
25  *
26  * @author <a href="http://tfox.org">Tim Fox</a>
27  */
28 abstract class ClientOptionsBase : TcpSslOptions {
29 
30     /**
31      * The default value of connect timeout = 60000 ms
32      */
33     enum int DEFAULT_CONNECT_TIMEOUT = 60000;
34 
35     /**
36      * The default value of whether all servers (SSL/TLS) should be trusted = false
37      */
38     enum bool DEFAULT_TRUST_ALL = false;
39 
40     /**
41      * The default value of the client metrics = "":
42      */
43     enum string DEFAULT_METRICS_NAME = "";
44 
45     private Duration connectTimeout;
46     private bool trustAll;
47     private string metricsName;
48     private ProxyOptions proxyOptions;
49     private string localAddress;
50 
51     /**
52      * 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(ClientOptionsBase other) {
65         super(other);
66         this.connectTimeout = other.getConnectTimeout();
67         this.trustAll = other.isTrustAll();
68         this.metricsName = other.metricsName;
69         this.proxyOptions = other.proxyOptions !is null ? new ProxyOptions(other.proxyOptions) : null;
70         this.localAddress = other.localAddress;
71     }
72 
73     private void init() {
74         this.connectTimeout = DEFAULT_CONNECT_TIMEOUT.msecs;
75         this.trustAll = DEFAULT_TRUST_ALL;
76         this.metricsName = DEFAULT_METRICS_NAME;
77         this.proxyOptions = null;
78         this.localAddress = null;
79     }
80 
81     /**
82      *
83      * @return true if all server certificates should be trusted
84      */
85     bool isTrustAll() {
86         return trustAll;
87     }
88 
89     /**
90      * Set whether all server certificates should be trusted
91      *
92      * @param trustAll true if all should be trusted
93      * @return a reference to this, so the API can be used fluently
94      */
95     ClientOptionsBase setTrustAll(bool trustAll) {
96         this.trustAll = trustAll;
97         return this;
98     }
99 
100     /**
101      * @return the value of connect timeout
102      */
103     Duration getConnectTimeout() {
104         return connectTimeout;
105     }
106 
107     /**
108      * Set the connect timeout
109      *
110      * @param connectTimeout  connect timeout, in ms
111      * @return a reference to this, so the API can be used fluently
112      */
113     ClientOptionsBase setConnectTimeout(Duration connectTimeout) {
114         if (connectTimeout < Duration.zero) {
115             throw new IllegalArgumentException("connectTimeout must be >= 0");
116         }
117         this.connectTimeout = connectTimeout;
118         return this;
119     }
120 
121     /**
122      * @return the metrics name identifying the reported metrics.
123      */
124     string getMetricsName() {
125         return metricsName;
126     }
127 
128     /**
129      * Set the metrics name identifying the reported metrics, useful for grouping metrics
130      * with the same name.
131      *
132      * @param metricsName the metrics name
133      * @return a reference to this, so the API can be used fluently
134      */
135     ClientOptionsBase setMetricsName(string metricsName) {
136         this.metricsName = metricsName;
137         return this;
138     }
139 
140     /**
141      * Set proxy options for connections via CONNECT proxy (e.g. Squid) or a SOCKS proxy.
142      *
143      * @param proxyOptions proxy options object
144      * @return a reference to this, so the API can be used fluently
145      */
146     ClientOptionsBase setProxyOptions(ProxyOptions proxyOptions) {
147         this.proxyOptions = proxyOptions;
148         return this;
149     }
150 
151     /**
152      * Get proxy options for connections
153      *
154      * @return proxy options
155      */
156     ProxyOptions getProxyOptions() {
157         return proxyOptions;
158     }
159 
160     /**
161      * @return the local interface to bind for network connections.
162      */
163     string getLocalAddress() {
164         return localAddress;
165     }
166 
167     /**
168      * Set the local interface to bind for network connections. When the local address is null,
169      * it will pick any local address, the default local address is null.
170      *
171      * @param localAddress the local address
172      * @return a reference to this, so the API can be used fluently
173      */
174     ClientOptionsBase setLocalAddress(string localAddress) {
175         this.localAddress = localAddress;
176         return this;
177     }
178 
179     override
180     ClientOptionsBase setLogActivity(bool logEnabled) {
181         return cast(ClientOptionsBase) super.setLogActivity(logEnabled);
182     }
183 
184     override
185     ClientOptionsBase setTcpNoDelay(bool tcpNoDelay) {
186         return cast(ClientOptionsBase) super.setTcpNoDelay(tcpNoDelay);
187     }
188 
189     override
190     ClientOptionsBase setTcpKeepAlive(bool tcpKeepAlive) {
191         return cast(ClientOptionsBase) super.setTcpKeepAlive(tcpKeepAlive);
192     }
193 
194     override
195     ClientOptionsBase setSoLinger(int soLinger) {
196         return cast(ClientOptionsBase) super.setSoLinger(soLinger);
197     }
198 
199     // override
200     // ClientOptionsBase setUsePooledBuffers(bool usePooledBuffers) {
201     //     return cast(ClientOptionsBase) super.setUsePooledBuffers(usePooledBuffers);
202     // }
203 
204     override
205     ClientOptionsBase setIdleTimeout(Duration idleTimeout) {
206         return cast(ClientOptionsBase) super.setIdleTimeout(idleTimeout);
207     }
208 
209     // override
210     // ClientOptionsBase setIdleTimeoutUnit(TimeUnit idleTimeoutUnit) {
211     //     return cast(ClientOptionsBase) super.setIdleTimeoutUnit(idleTimeoutUnit);
212     // }
213 
214     override
215     ClientOptionsBase setSsl(bool ssl) {
216         return cast(ClientOptionsBase) super.setSsl(ssl);
217     }
218 
219     // override
220     // ClientOptionsBase setKeyCertOptions(KeyCertOptions options) {
221     //     return cast(ClientOptionsBase) super.setKeyCertOptions(options);
222     // }
223 
224     // override
225     // ClientOptionsBase setKeyStoreOptions(JksOptions options) {
226     //     return cast(ClientOptionsBase) super.setKeyStoreOptions(options);
227     // }
228 
229     // override
230     // ClientOptionsBase setPfxKeyCertOptions(PfxOptions options) {
231     //     return cast(ClientOptionsBase) super.setPfxKeyCertOptions(options);
232     // }
233 
234     // override
235     // ClientOptionsBase setPemKeyCertOptions(PemKeyCertOptions options) {
236     //     return cast(ClientOptionsBase) super.setPemKeyCertOptions(options);
237     // }
238 
239     // override
240     // ClientOptionsBase setTrustOptions(TrustOptions options) {
241     //     return cast(ClientOptionsBase) super.setTrustOptions(options);
242     // }
243 
244     // override
245     // ClientOptionsBase setTrustStoreOptions(JksOptions options) {
246     //     return cast(ClientOptionsBase) super.setTrustStoreOptions(options);
247     // }
248 
249     // override
250     // ClientOptionsBase setPfxTrustOptions(PfxOptions options) {
251     //     return cast(ClientOptionsBase) super.setPfxTrustOptions(options);
252     // }
253 
254     // override
255     // ClientOptionsBase setPemTrustOptions(PemTrustOptions options) {
256     //     return cast(ClientOptionsBase) super.setPemTrustOptions(options);
257     // }
258 
259     override
260     ClientOptionsBase setUseAlpn(bool useAlpn) {
261         return cast(ClientOptionsBase) super.setUseAlpn(useAlpn);
262     }
263 
264     // override
265     // ClientOptionsBase setSslEngineOptions(SSLEngineOptions sslEngineOptions) {
266     //     return cast(ClientOptionsBase) super.setSslEngineOptions(sslEngineOptions);
267     // }
268 
269     // override
270     // ClientOptionsBase setJdkSslEngineOptions(JdkSSLEngineOptions sslEngineOptions) {
271     //     return cast(ClientOptionsBase) super.setJdkSslEngineOptions(sslEngineOptions);
272     // }
273 
274     override
275     ClientOptionsBase setOpenSslEngineOptions(OpenSSLEngineOptions sslEngineOptions) {
276         return cast(ClientOptionsBase) super.setOpenSslEngineOptions(sslEngineOptions);
277     }
278 
279     override
280     ClientOptionsBase setSendBufferSize(int sendBufferSize) {
281         return cast(ClientOptionsBase) super.setSendBufferSize(sendBufferSize);
282     }
283 
284     override
285     ClientOptionsBase setReceiveBufferSize(int receiveBufferSize) {
286         return cast(ClientOptionsBase) super.setReceiveBufferSize(receiveBufferSize);
287     }
288 
289     override
290     ClientOptionsBase setReuseAddress(bool reuseAddress) {
291         return cast(ClientOptionsBase) super.setReuseAddress(reuseAddress);
292     }
293 
294     override
295     ClientOptionsBase setReusePort(bool reusePort) {
296         return cast(ClientOptionsBase) super.setReusePort(reusePort);
297     }
298 
299     override
300     ClientOptionsBase setTrafficClass(int trafficClass) {
301         return cast(ClientOptionsBase) super.setTrafficClass(trafficClass);
302     }
303 
304     // override
305     // ClientOptionsBase addEnabledCipherSuite(string suite) {
306     //     return cast(ClientOptionsBase) super.addEnabledCipherSuite(suite);
307     // }
308 
309     // override
310     // ClientOptionsBase addCrlPath(string crlPath) {
311     //     return cast(ClientOptionsBase) super.addCrlPath(crlPath);
312     // }
313 
314     // override
315     // ClientOptionsBase addCrlValue(Buffer crlValue) {
316     //     return cast(ClientOptionsBase) super.addCrlValue(crlValue);
317     // }
318 
319     // override
320     // ClientOptionsBase addEnabledSecureTransportProtocol(string protocol) {
321     //     return cast(ClientOptionsBase) super.addEnabledSecureTransportProtocol(protocol);
322     // }
323 
324     // override
325     // ClientOptionsBase removeEnabledSecureTransportProtocol(string protocol) {
326     //     return cast(ClientOptionsBase) super.removeEnabledSecureTransportProtocol(protocol);
327     // }
328 
329     override
330     ClientOptionsBase setTcpFastOpen(bool tcpFastOpen) {
331         return cast(ClientOptionsBase) super.setTcpFastOpen(tcpFastOpen);
332     }
333 
334     override
335     ClientOptionsBase setTcpCork(bool tcpCork) {
336         return cast(ClientOptionsBase) super.setTcpCork(tcpCork);
337     }
338 
339     override
340     ClientOptionsBase setTcpQuickAck(bool tcpQuickAck) {
341         return cast(ClientOptionsBase) super.setTcpQuickAck(tcpQuickAck);
342     }
343 
344     override
345     bool opEquals(Object o) {
346         if (this is o) return true;
347         if (!super.opEquals(o)) return false;
348 
349         ClientOptionsBase that = cast(ClientOptionsBase) o;
350         if(that is null)
351             return false;
352 
353         if (connectTimeout != that.connectTimeout) return false;
354         if (trustAll != that.trustAll) return false;
355         if (metricsName != that.metricsName) return false;
356         if (proxyOptions != that.proxyOptions) return false;
357         if (localAddress != that.localAddress) return false;
358 
359         return true;
360     }
361 
362     override
363     size_t toHash() @trusted nothrow {
364         size_t result = super.toHash();
365         result = 31 * result + cast(size_t)connectTimeout.total!("msecs")();
366         result = 31 * result + (trustAll ? 1 : 0);
367         result = 31 * result + metricsName.hashOf();
368         result = 31 * result + proxyOptions.hashOf();
369         result = 31 * result + localAddress.hashOf();
370         return result;
371     }
372 }