View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http.config;
29  
30  import java.util.concurrent.TimeUnit;
31  
32  import org.apache.hc.core5.annotation.Contract;
33  import org.apache.hc.core5.annotation.ThreadingBehavior;
34  import org.apache.hc.core5.util.Args;
35  import org.apache.hc.core5.util.TimeValue;
36  import org.apache.hc.core5.util.Timeout;
37  
38  /**
39   * Socket configuration.
40   *
41   * @since 4.3
42   */
43  @Contract(threading = ThreadingBehavior.IMMUTABLE)
44  public class SocketConfig {
45  
46      public static final SocketConfig DEFAULT = new Builder().build();
47  
48      private final Timeout soTimeout;
49      private final boolean soReuseAddress;
50      private final TimeValue soLinger;
51      private final boolean soKeepAlive;
52      private final boolean tcpNoDelay;
53      private final int sndBufSize;
54      private final int rcvBufSize;
55      private final int backlogSize;
56  
57      SocketConfig(
58              final Timeout soTimeout,
59              final boolean soReuseAddress,
60              final TimeValue soLinger,
61              final boolean soKeepAlive,
62              final boolean tcpNoDelay,
63              final int sndBufSize,
64              final int rcvBufSize,
65              final int backlogSize) {
66          super();
67          this.soTimeout = soTimeout;
68          this.soReuseAddress = soReuseAddress;
69          this.soLinger = soLinger;
70          this.soKeepAlive = soKeepAlive;
71          this.tcpNoDelay = tcpNoDelay;
72          this.sndBufSize = sndBufSize;
73          this.rcvBufSize = rcvBufSize;
74          this.backlogSize = backlogSize;
75      }
76  
77      /**
78       * Determines the default socket timeout value for blocking I/O operations.
79       * <p>
80       * Default: {@code 0} (no timeout)
81       * </p>
82       *
83       * @return the default socket timeout value for blocking I/O operations.
84       * @see java.net.SocketOptions#SO_TIMEOUT
85       */
86      public Timeout getSoTimeout() {
87          return soTimeout;
88      }
89  
90      /**
91       * Determines the default value of the {@link java.net.SocketOptions#SO_REUSEADDR} parameter
92       * for newly created sockets.
93       * <p>
94       * Default: {@code false}
95       * </p>
96       *
97       * @return the default value of the {@link java.net.SocketOptions#SO_REUSEADDR} parameter.
98       * @see java.net.SocketOptions#SO_REUSEADDR
99       */
100     public boolean isSoReuseAddress() {
101         return soReuseAddress;
102     }
103 
104     /**
105      * Determines the default value of the {@link java.net.SocketOptions#SO_LINGER} parameter
106      * for newly created sockets.
107      * <p>
108      * Default: {@code -1}
109      * </p>
110      *
111      * @return the default value of the {@link java.net.SocketOptions#SO_LINGER} parameter.
112      * @see java.net.SocketOptions#SO_LINGER
113      */
114     public TimeValue getSoLinger() {
115         return soLinger;
116     }
117 
118     /**
119      * Determines the default value of the {@link java.net.SocketOptions#SO_KEEPALIVE} parameter
120      * for newly created sockets.
121      * <p>
122      * Default: {@code false}
123      * </p>
124      *
125      * @return the default value of the {@link java.net.SocketOptions#SO_KEEPALIVE} parameter.
126      * @see java.net.SocketOptions#SO_KEEPALIVE
127      */
128     public boolean isSoKeepAlive() {
129         return soKeepAlive;
130     }
131 
132     /**
133      * Determines the default value of the {@link java.net.SocketOptions#TCP_NODELAY} parameter
134      * for newly created sockets.
135      * <p>
136      * Default: {@code false}
137      * </p>
138      *
139      * @return the default value of the {@link java.net.SocketOptions#TCP_NODELAY} parameter.
140      * @see java.net.SocketOptions#TCP_NODELAY
141      */
142     public boolean isTcpNoDelay() {
143         return tcpNoDelay;
144     }
145 
146     /**
147      * Determines the default value of the {@link java.net.SocketOptions#SO_SNDBUF} parameter
148      * for newly created sockets.
149      * <p>
150      * Default: {@code 0} (system default)
151      * </p>
152      *
153      * @return the default value of the {@link java.net.SocketOptions#SO_SNDBUF} parameter.
154      * @see java.net.SocketOptions#SO_SNDBUF
155      * @since 4.4
156      */
157     public int getSndBufSize() {
158         return sndBufSize;
159     }
160 
161     /**
162      * Determines the default value of the {@link java.net.SocketOptions#SO_RCVBUF} parameter
163      * for newly created sockets.
164      * <p>
165      * Default: {@code 0} (system default)
166      * </p>
167      *
168      * @return the default value of the {@link java.net.SocketOptions#SO_RCVBUF} parameter.
169      * @see java.net.SocketOptions#SO_RCVBUF
170      * @since 4.4
171      */
172     public int getRcvBufSize() {
173         return rcvBufSize;
174     }
175 
176     /**
177      * Determines the maximum queue length for incoming connection indications
178      * (a request to connect) also known as server socket backlog.
179      * <p>
180      * Default: {@code 0} (system default)
181      * </p>
182      * @return the maximum queue length for incoming connection indications
183      * @since 4.4
184      */
185     public int getBacklogSize() {
186         return backlogSize;
187     }
188 
189     @Override
190     public String toString() {
191         final StringBuilder builder = new StringBuilder();
192         builder.append("[soTimeout=").append(this.soTimeout)
193                 .append(", soReuseAddress=").append(this.soReuseAddress)
194                 .append(", soLinger=").append(this.soLinger)
195                 .append(", soKeepAlive=").append(this.soKeepAlive)
196                 .append(", tcpNoDelay=").append(this.tcpNoDelay)
197                 .append(", sndBufSize=").append(this.sndBufSize)
198                 .append(", rcvBufSize=").append(this.rcvBufSize)
199                 .append(", backlogSize=").append(this.backlogSize)
200                 .append("]");
201         return builder.toString();
202     }
203 
204     public static SocketConfig.Builder custom() {
205         return new Builder();
206     }
207 
208     public static SocketConfig.Builder copy(final SocketConfig config) {
209         Args.notNull(config, "Socket config");
210         return new Builder()
211             .setSoTimeout(config.getSoTimeout())
212             .setSoReuseAddress(config.isSoReuseAddress())
213             .setSoLinger(config.getSoLinger())
214             .setSoKeepAlive(config.isSoKeepAlive())
215             .setTcpNoDelay(config.isTcpNoDelay())
216             .setSndBufSize(config.getSndBufSize())
217             .setRcvBufSize(config.getRcvBufSize())
218             .setBacklogSize(config.getBacklogSize());
219     }
220 
221     public static class Builder {
222 
223         private Timeout soTimeout;
224         private boolean soReuseAddress;
225         private TimeValue soLinger;
226         private boolean soKeepAlive;
227         private boolean tcpNoDelay;
228         private int sndBufSize;
229         private int rcvBufSize;
230         private int backlogSize;
231 
232         Builder() {
233             this.soTimeout = Timeout.ZERO_MILLISECONDS;
234             this.soReuseAddress = false;
235             this.soLinger = TimeValue.NEG_ONE_SECONDS;
236             this.soKeepAlive = false;
237             this.tcpNoDelay = true;
238             this.sndBufSize = 0;
239             this.rcvBufSize = 0;
240             this.backlogSize = 0;
241         }
242 
243         public Builder setSoTimeout(final int soTimeout, final TimeUnit timeUnit) {
244             this.soTimeout = Timeout.of(soTimeout, timeUnit);
245             return this;
246         }
247 
248         public Builder setSoTimeout(final Timeout soTimeout) {
249             this.soTimeout = soTimeout;
250             return this;
251         }
252 
253         public Builder setSoReuseAddress(final boolean soReuseAddress) {
254             this.soReuseAddress = soReuseAddress;
255             return this;
256         }
257 
258         public Builder setSoLinger(final int soLinger, final TimeUnit timeUnit) {
259             this.soLinger = Timeout.of(soLinger, timeUnit);
260             return this;
261         }
262 
263         public Builder setSoLinger(final TimeValue soLinger) {
264             this.soLinger = soLinger;
265             return this;
266         }
267 
268         public Builder setSoKeepAlive(final boolean soKeepAlive) {
269             this.soKeepAlive = soKeepAlive;
270             return this;
271         }
272 
273         public Builder setTcpNoDelay(final boolean tcpNoDelay) {
274             this.tcpNoDelay = tcpNoDelay;
275             return this;
276         }
277 
278         /**
279          * @since 4.4
280          */
281         public Builder setSndBufSize(final int sndBufSize) {
282             this.sndBufSize = sndBufSize;
283             return this;
284         }
285 
286         /**
287          * @since 4.4
288          */
289         public Builder setRcvBufSize(final int rcvBufSize) {
290             this.rcvBufSize = rcvBufSize;
291             return this;
292         }
293 
294         /**
295          * @since 4.4
296          */
297         public Builder setBacklogSize(final int backlogSize) {
298             this.backlogSize = backlogSize;
299             return this;
300         }
301 
302         public SocketConfig build() {
303             return new SocketConfig(
304                     Timeout.defaultsToDisabled(soTimeout),
305                     soReuseAddress,
306                     soLinger != null ? soLinger : TimeValue.NEG_ONE_SECONDS,
307                     soKeepAlive, tcpNoDelay, sndBufSize, rcvBufSize, backlogSize);
308         }
309 
310     }
311 
312 }