Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
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 */
28 package ch.boye.httpclientandroidlib.conn;
30 import java.io.IOException;
31 import java.net.InetAddress;
32 import java.net.InetSocketAddress;
33 import java.net.Socket;
34 import java.net.SocketTimeoutException;
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.List;
38 import java.util.Arrays;
40 import ch.boye.httpclientandroidlib.annotation.Immutable;
42 import ch.boye.httpclientandroidlib.conn.scheme.SchemeSocketFactory;
43 import ch.boye.httpclientandroidlib.conn.scheme.SocketFactory;
44 import ch.boye.httpclientandroidlib.params.HttpConnectionParams;
45 import ch.boye.httpclientandroidlib.params.HttpParams;
47 /**
48 * Socket factory that implements a simple multi-home fail-over on connect failure,
49 * provided the same hostname resolves to multiple {@link InetAddress}es. Please note
50 * the {@link #connectSocket(Socket, String, int, InetAddress, int, HttpParams)}
51 * method cannot be reliably interrupted by closing the socket returned by the
52 * {@link #createSocket()} method.
53 *
54 * @since 4.0
55 *
56 * @deprecated Do not use. For multihome support socket factories must implement
57 * {@link SchemeSocketFactory} interface.
58 */
59 @Deprecated
60 @Immutable
61 public final class MultihomePlainSocketFactory implements SocketFactory {
63 /**
64 * The factory singleton.
65 */
66 private static final
67 MultihomePlainSocketFactory DEFAULT_FACTORY = new MultihomePlainSocketFactory();
69 /**
70 * Gets the singleton instance of this class.
71 * @return the one and only plain socket factory
72 */
73 public static MultihomePlainSocketFactory getSocketFactory() {
74 return DEFAULT_FACTORY;
75 }
77 /**
78 * Restricted default constructor.
79 */
80 private MultihomePlainSocketFactory() {
81 super();
82 }
85 // non-javadoc, see interface ch.boye.httpclientandroidlib.conn.SocketFactory
86 public Socket createSocket() {
87 return new Socket();
88 }
90 /**
91 * Attempts to connects the socket to any of the {@link InetAddress}es the
92 * given host name resolves to. If connection to all addresses fail, the
93 * last I/O exception is propagated to the caller.
94 *
95 * @param sock socket to connect to any of the given addresses
96 * @param host Host name to connect to
97 * @param port the port to connect to
98 * @param localAddress local address
99 * @param localPort local port
100 * @param params HTTP parameters
101 *
102 * @throws IOException if an error occurs during the connection
103 * @throws SocketTimeoutException if timeout expires before connecting
104 */
105 public Socket connectSocket(Socket sock, String host, int port,
106 InetAddress localAddress, int localPort,
107 HttpParams params)
108 throws IOException {
110 if (host == null) {
111 throw new IllegalArgumentException("Target host may not be null.");
112 }
113 if (params == null) {
114 throw new IllegalArgumentException("Parameters may not be null.");
115 }
117 if (sock == null)
118 sock = createSocket();
120 if ((localAddress != null) || (localPort > 0)) {
122 // we need to bind explicitly
123 if (localPort < 0)
124 localPort = 0; // indicates "any"
126 InetSocketAddress isa =
127 new InetSocketAddress(localAddress, localPort);
128 sock.bind(isa);
129 }
131 int timeout = HttpConnectionParams.getConnectionTimeout(params);
133 InetAddress[] inetadrs = InetAddress.getAllByName(host);
134 List<InetAddress> addresses = new ArrayList<InetAddress>(inetadrs.length);
135 addresses.addAll(Arrays.asList(inetadrs));
136 Collections.shuffle(addresses);
138 IOException lastEx = null;
139 for (InetAddress remoteAddress: addresses) {
140 try {
141 sock.connect(new InetSocketAddress(remoteAddress, port), timeout);
142 break;
143 } catch (SocketTimeoutException ex) {
144 throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
145 } catch (IOException ex) {
146 // create new socket
147 sock = new Socket();
148 // keep the last exception and retry
149 lastEx = ex;
150 }
151 }
152 if (lastEx != null) {
153 throw lastEx;
154 }
155 return sock;
156 } // connectSocket
159 /**
160 * Checks whether a socket connection is secure.
161 * This factory creates plain socket connections
162 * which are not considered secure.
163 *
164 * @param sock the connected socket
165 *
166 * @return <code>false</code>
167 *
168 * @throws IllegalArgumentException if the argument is invalid
169 */
170 public final boolean isSecure(Socket sock)
171 throws IllegalArgumentException {
173 if (sock == null) {
174 throw new IllegalArgumentException("Socket may not be null.");
175 }
176 // This class check assumes that createSocket() calls the constructor
177 // directly. If it was using javax.net.SocketFactory, we couldn't make
178 // an assumption about the socket class here.
179 if (sock.getClass() != Socket.class) {
180 throw new IllegalArgumentException
181 ("Socket not created by this factory.");
182 }
183 // This check is performed last since it calls a method implemented
184 // by the argument object. getClass() is final in java.lang.Object.
185 if (sock.isClosed()) {
186 throw new IllegalArgumentException("Socket is closed.");
187 }
189 return false;
191 } // isSecure
193 }