001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http.config;
029
030import org.apache.http.annotation.ThreadingBehavior;
031import org.apache.http.annotation.Contract;
032import org.apache.http.util.Args;
033
034/**
035 * Socket configuration.
036 *
037 * @since 4.3
038 */
039@Contract(threading = ThreadingBehavior.IMMUTABLE)
040public class SocketConfig implements Cloneable {
041
042    public static final SocketConfig DEFAULT = new Builder().build();
043
044    private final int soTimeout;
045    private final boolean soReuseAddress;
046    private final int soLinger;
047    private final boolean soKeepAlive;
048    private final boolean tcpNoDelay;
049    private final int sndBufSize;
050    private final int rcvBufSize;
051    private final int backlogSize;
052
053    SocketConfig(
054            final int soTimeout,
055            final boolean soReuseAddress,
056            final int soLinger,
057            final boolean soKeepAlive,
058            final boolean tcpNoDelay,
059            final int sndBufSize,
060            final int rcvBufSize,
061            final int backlogSize) {
062        super();
063        this.soTimeout = soTimeout;
064        this.soReuseAddress = soReuseAddress;
065        this.soLinger = soLinger;
066        this.soKeepAlive = soKeepAlive;
067        this.tcpNoDelay = tcpNoDelay;
068        this.sndBufSize = sndBufSize;
069        this.rcvBufSize = rcvBufSize;
070        this.backlogSize = backlogSize;
071    }
072
073    /**
074     * Determines the default socket timeout value for non-blocking I/O operations.
075     * <p>
076     * Default: {@code 0} (no timeout)
077     * </p>
078     *
079     * @return the default socket timeout value for non-blocking I/O operations.
080     * @see java.net.SocketOptions#SO_TIMEOUT
081     */
082    public int getSoTimeout() {
083        return soTimeout;
084    }
085
086    /**
087     * Determines the default value of the {@link java.net.SocketOptions#SO_REUSEADDR} parameter
088     * for newly created sockets.
089     * <p>
090     * Default: {@code false}
091     * </p>
092     *
093     * @return the default value of the {@link java.net.SocketOptions#SO_REUSEADDR} parameter.
094     * @see java.net.SocketOptions#SO_REUSEADDR
095     */
096    public boolean isSoReuseAddress() {
097        return soReuseAddress;
098    }
099
100    /**
101     * Determines the default value of the {@link java.net.SocketOptions#SO_LINGER} parameter
102     * for newly created sockets.
103     * <p>
104     * Default: {@code -1}
105     * </p>
106     *
107     * @return the default value of the {@link java.net.SocketOptions#SO_LINGER} parameter.
108     * @see java.net.SocketOptions#SO_LINGER
109     */
110    public int getSoLinger() {
111        return soLinger;
112    }
113
114    /**
115     * Determines the default value of the {@link java.net.SocketOptions#SO_KEEPALIVE} parameter
116     * for newly created sockets.
117     * <p>
118     * Default: {@code -1}
119     * </p>
120     *
121     * @return the default value of the {@link java.net.SocketOptions#SO_KEEPALIVE} parameter.
122     * @see java.net.SocketOptions#SO_KEEPALIVE
123     */
124    public boolean isSoKeepAlive() {
125        return soKeepAlive;
126    }
127
128    /**
129     * Determines the default value of the {@link java.net.SocketOptions#TCP_NODELAY} parameter
130     * for newly created sockets.
131     * <p>
132     * Default: {@code false}
133     * </p>
134     *
135     * @return the default value of the {@link java.net.SocketOptions#TCP_NODELAY} parameter.
136     * @see java.net.SocketOptions#TCP_NODELAY
137     */
138    public boolean isTcpNoDelay() {
139        return tcpNoDelay;
140    }
141
142    /**
143     * Determines the default value of the {@link java.net.SocketOptions#SO_SNDBUF} parameter
144     * for newly created sockets.
145     * <p>
146     * Default: {@code 0} (system default)
147     * </p>
148     *
149     * @return the default value of the {@link java.net.SocketOptions#SO_SNDBUF} parameter.
150     * @see java.net.SocketOptions#SO_SNDBUF
151     * @since 4.4
152     */
153    public int getSndBufSize() {
154        return sndBufSize;
155    }
156
157    /**
158     * Determines the default value of the {@link java.net.SocketOptions#SO_RCVBUF} parameter
159     * for newly created sockets.
160     * <p>
161     * Default: {@code 0} (system default)
162     * </p>
163     *
164     * @return the default value of the {@link java.net.SocketOptions#SO_RCVBUF} parameter.
165     * @see java.net.SocketOptions#SO_RCVBUF
166     * @since 4.4
167     */
168    public int getRcvBufSize() {
169        return rcvBufSize;
170    }
171
172    /**
173     * Determines the maximum queue length for incoming connection indications
174     * (a request to connect) also known as server socket backlog.
175     * <p>
176     * Default: {@code 0} (system default)
177     * </p>
178     * @return the maximum queue length for incoming connection indications
179     * @since 4.4
180     */
181    public int getBacklogSize() {
182        return backlogSize;
183    }
184
185    @Override
186    protected SocketConfig clone() throws CloneNotSupportedException {
187        return (SocketConfig) super.clone();
188    }
189
190    @Override
191    public String toString() {
192        final StringBuilder builder = new StringBuilder();
193        builder.append("[soTimeout=").append(this.soTimeout)
194                .append(", soReuseAddress=").append(this.soReuseAddress)
195                .append(", soLinger=").append(this.soLinger)
196                .append(", soKeepAlive=").append(this.soKeepAlive)
197                .append(", tcpNoDelay=").append(this.tcpNoDelay)
198                .append(", sndBufSize=").append(this.sndBufSize)
199                .append(", rcvBufSize=").append(this.rcvBufSize)
200                .append(", backlogSize=").append(this.backlogSize)
201                .append("]");
202        return builder.toString();
203    }
204
205    public static SocketConfig.Builder custom() {
206        return new Builder();
207    }
208
209    public static SocketConfig.Builder copy(final SocketConfig config) {
210        Args.notNull(config, "Socket config");
211        return new Builder()
212            .setSoTimeout(config.getSoTimeout())
213            .setSoReuseAddress(config.isSoReuseAddress())
214            .setSoLinger(config.getSoLinger())
215            .setSoKeepAlive(config.isSoKeepAlive())
216            .setTcpNoDelay(config.isTcpNoDelay())
217            .setSndBufSize(config.getSndBufSize())
218            .setRcvBufSize(config.getRcvBufSize())
219            .setBacklogSize(config.getBacklogSize());
220    }
221
222    public static class Builder {
223
224        private int soTimeout;
225        private boolean soReuseAddress;
226        private int soLinger;
227        private boolean soKeepAlive;
228        private boolean tcpNoDelay;
229        private int sndBufSize;
230        private int rcvBufSize;
231        private int backlogSize;
232
233        Builder() {
234            this.soLinger = -1;
235            this.tcpNoDelay = true;
236        }
237
238        public Builder setSoTimeout(final int soTimeout) {
239            this.soTimeout = soTimeout;
240            return this;
241        }
242
243        public Builder setSoReuseAddress(final boolean soReuseAddress) {
244            this.soReuseAddress = soReuseAddress;
245            return this;
246        }
247
248        public Builder setSoLinger(final int soLinger) {
249            this.soLinger = soLinger;
250            return this;
251        }
252
253        public Builder setSoKeepAlive(final boolean soKeepAlive) {
254            this.soKeepAlive = soKeepAlive;
255            return this;
256        }
257
258        public Builder setTcpNoDelay(final boolean tcpNoDelay) {
259            this.tcpNoDelay = tcpNoDelay;
260            return this;
261        }
262
263        /**
264         * @since 4.4
265         */
266        public Builder setSndBufSize(final int sndBufSize) {
267            this.sndBufSize = sndBufSize;
268            return this;
269        }
270
271        /**
272         * @since 4.4
273         */
274        public Builder setRcvBufSize(final int rcvBufSize) {
275            this.rcvBufSize = rcvBufSize;
276            return this;
277        }
278
279        /**
280         * @since 4.4
281         */
282        public Builder setBacklogSize(final int backlogSize) {
283            this.backlogSize = backlogSize;
284            return this;
285        }
286
287        public SocketConfig build() {
288            return new SocketConfig(soTimeout, soReuseAddress, soLinger, soKeepAlive, tcpNoDelay,
289                    sndBufSize, rcvBufSize, backlogSize);
290        }
291
292    }
293
294}